Text formateren voor LCD display

blackdog

Golden Member

Hi!

Voor een project van mij wil ik een digitale temperatuur, de bekende DS18B20 sensor uitlezen zowel wat temperatuur als het unieke sensor addres.

Met het display dat ik ga gebruiken wat een SPI TFT 240x320 pixels is heb ik al gekozen voor ene bepaalde letter grote zodat ik ook de rest van de data in 1x op het display kwijt kan.
De processor wordt een Arduino/Teensy versie of zoiets.

Met een klein stukje software kan je het unieke sensor adres uit de sensor halen wat er ongeveer zo uit ziet:

0x10, 0x99, 0x3E, 0xB5, 0x02, 0x08, 0x00, 0xD3

Voor het makkelijk uitlezen wil ik dit in een bepaalde fontgrote hebben zodat mijn oude oogjes dit goed kunnen lezen.
Bij de door mij gekozen fontgrote kan ik de sting in twee delen op het scherm brengen en ik wil het dan zo hebben:

Type Sensor DS18B20, adres is:
0x10 0x99 0x3E 0xB5
0x02 0x08 0x00 0xD3

Temp: 40.72C Corectie -0,72C

Het weergegeven sensor adres wordt op twee regels geplaatst en bevat dan geen comma's meer.
Ik heb geen idee hoe de comma's er uit te filteren en dan de data in twee stukken de delen om ze afzonderlijk op het display te plaatsen.
De vier regels hierboven worden in een kader geplaatst en er komt ook een kader voor een analoge sensor de TMP36/37

Wie wil mij helpen dit probleem op te lossen.

Deze vraag heeft te maken met dit topic van mij over een Temperatuur Sensor Kalibrator:
https://www.circuitsonline.net/forum/view/136090

Alvast mijn dank en groet,
Blackdog

You have your way. I have my way. As for the right way, the correct way, and the only way, it does not exist.
buckfast_beekeeper

Golden Member

De hex string is altijd identiek. Het is dus niet moeilijk om met diverse string functies daar de nodige gegevens uit te halen. Daarna plak je ze gewoon in een nieuwe string of je plakt de gegevens karakter per karakter gewoon direct op het display.

in gewoon basic kan je de string manipuleren met left$(string, aantal karakters), mid$(string, beginpositie, aantal karakters) en right$(string, aantal karakters). In C bestaan gelijkaardige zaken.

Van Lambiek wordt goede geuze gemaakt.

Hoi blackdog,

In de Arduino IDE bestaat het object String

Kijk eens naar:
StringReplace() (comma's verwijderen)
StringSubstring() opknippen in 2 delen

Met deze functies zou je het al voor elkaar kunnen krijgen.

Action expresses priorities LH
blackdog

Golden Member

Hi LetterHenk,

Dank voor de info :-)

Ben ondertussen aan het afkicken van Arduino pro mini en aanverwante microcontrolers...
Gillend gek werd ik vanavond door al die rammelende poortinstellingen van converterchips 5V 3V3 enz enz, bah!
Ik heb een redelijke voorraad van mini en micro Arduino's, ik denk dat ik dat alles terzijde ga schuiven, het is de tijd niet waard...

Als ik aan Nano pak werkt het altijd net al de Teensy LC, inprikken type Teensy kiezen, sketch uploaden en gaan met die banaan.
Die 4x hogere prijs van een Teensy LC heb je er zo uit!

Waarom dit allemaal, ik heb geen zin om een levelconverter achter de Nano te gebruiken omdat het TFT display 3V3 is wat level betreft.
De Keuze is nu gemaakt, het wordt een Teensy en ga die op voorraad leggen :-)

Mooi, als ik morgen tijd heb, ga ik het "string" commande uitzoeken.

Nu verder afkoelen *grin*

Groet,
Bram

You have your way. I have my way. As for the right way, the correct way, and the only way, it does not exist.

Zelf heb ik al snel de neiging om een nieuwe routine te schrijven in plaas van te gaan zoeken in allerlei libraries.

Dan kom je aan een routine als de volgende:

code:



// Stel je hebt een buffer met de volgende text:
// = dus 45 bytes tekst en 1 byte 0x00 terminator
char SensorAddress[45] = "0x10, 0x99, 0x3E, 0xB5, 0x02, 0x08, 0x00, 0xD3";

// En je wilt dat omrekenen naar 2 strings met 
// "0x10 0x99 0x3E 0xB5"
// "0x02 0x08 0x00 0xD3"
// Dan heb je 2 buffers nodig, elk met 21 posities.
char Line1[21];
char Line2[21];

// En een funktie die de data filtert:
void AddressFilter(const char *Input, char *Output)
{  
   uint8_t i = 0;
   uint8_t j = 0;

   for ( ;; )
   {  char c = Input[i++];
      if(c == 0)
      {  // Einde van de input string
         Output[j++] = 0;
         break; 
      }
      else if(c == ',')
      {  // Deze overslaan
      } 
      else
      {  // Anderen wel copieren
         Output[j++] = c;
      }

      // Test op eind van de input string:
      if(i > 21)  
      {  Output[j++] = 0; 
         break;
      } 
   }
}

   // En vervolgens deze funktie 2 keer aanroepen.

   // Eerste helft naar Line1
   AddressFilter(&Address[ 0], Line1);
   // Tweede helft naar Line2
   AddressFilter(&Address[24], Line2);


blackdog

Golden Member

Hi deKees, :-)

Ik ben een paar uur bezig geweest om de comma's uit de string te pulken en het is mij gelukt.
De rede dat dit zo lang duurde is omdat ik door de dyslectie sommige stukjes tekst gewoon niet goed "zie" in mijn brein.
Dit stukje was het grootste probleem => exString.replace(", ", ' ');
Vooral de vele "vreemde" karakters achter elkaar.
Zo'n verschil met een schema van zeg een meetinstrument of een versterker waarvan ik vrijwel direct de opset begrijp, maar je kan niet alles hebben in het leven ;-)

Er staat ook wat code om te meten hoelang het filteren van de comma's duurt.

c code:

String exString = 0;    // example string

unsigned long time;

void setup() {
  Serial.begin(115200);
}
void loop() {
//  Serial.print("Time: ");
  unsigned long start = micros();
  exString = "0x10, 0x99, 0x3E, 0xB5, 0x02, 0x08, 0x00, 0xD3";
  exString.replace(", ", ' ');
  
  Serial.println(exString);
  Serial.println();
  Serial.println();

  unsigned long end = micros();
  unsigned long delta = end - start;
  Serial.print("Loop-Time-uSec: ");
  Serial.println(delta);
  delay(1000);
}

Dank je voor de code, ik plak deze morgen in de code er bij om te kijken of het de gewenste resultaat geeft.
Ik heb deze keer niet gezocht naar een Library voor deze functies maar in de standaard Arduino code onder de string functies.

Groet,
Bram

You have your way. I have my way. As for the right way, the correct way, and the only way, it does not exist.
EricP

mét CE

Een schitterend voorbeeld van waarom ik zo'n hekel aan dat Arduino-taaltje heb: je haalt die data gewoon als bytes uit die sensor. Iemand heeft in zijn of haar wijsheid besloten dat de output in een sting geformatteerd moet worden. Uiteraard past die formattering niet iedereen, dus je moet weer moeite gaan doen om die string uit elkaar te gaan slopen om de juiste data eruit te halen.

Wat is er mis met een array met 8 bytes?

Op 8 maart 2017 23:14:43 schreef blackdog:

Waarom dit allemaal, ik heb geen zin om een levelconverter achter de Nano te gebruiken omdat het TFT display 3V3 is wat level betreft.

bwa, zo lastig is het toch allemaal niet. ik knoop gewoon 10k weerstanden tussen de nano outputs en de scherm inputs.

enkel bij VCC voor het scherm moet je dan aftakken op de 3.3V of 5V pin van je arduino. de meeste van mijn schermpjes die ik gebruik, hebben achteraan zo een jumper zitten. 5V is de jumper open, 3.3V is de jumper gesloten.

vind het ook een ellende dat ze daar de ene keer 3.3V gebruiken in de datalijnen en de andere keer 5V. ook bij i2c heb je die ellende

ik hou van werken ..., ik kan er uren naar kijken

@EricP;

Ik weet niet wat blackdog gebruikt, maar de nu gebruikelijke OneWire lib gebruikt een array byte addr[8] voor OneWire adressen.
Zie: http://playground.arduino.cc/Learning/OneWire

Er is allicht vanalles aan te merken op zaken die onder "Arduino" vallen, maar er is geen "Arduino taal", enkel wat libraries die je ook links kunt laten liggen, en die open source zijn dus waar je desnoods even in kunt duiken om te kijken hoe het werkt. Het is allemaal gewoon C / C++.
U maakt zich hier een beetje belachelijk.

blackdog

Golden Member

Morge Heren,

Het stukje code dat ik ga gebruiken is waar Aart de link van geeft.
Dan kan ik in het display aangeven of het een DS18S20 or DS18B20 betreft die ik in de tester heb gestoken.

Voor de analoge sensor ga ik een vergelijking doen zodat ik dan ook kan aangeven of er een TMP35, TMP36 of een TMP37 in de tester gestoken is.
De uitgangsspanningen voor de TMP36 en TMP37 zitten dicht bij elkaar maar dat moet goed lukken ze uit elkaar te kunen houden.

De waarden van de lineaire sensoren die ik wil gaan meten bij 40C oven temperatuur.
TMP35 = 400mV
TMP36 = 900mV
TMP37 = 800mV
Maar meer hierover in het andere topic, dit even hier toegevoegd om een beeld te geven waar ik mee bezig ben wat de code betreft.

fcapri
Ik ken de truc met de weerstanden, deze heb ik ondermeer gebruikt bij het Nokia display.
Een paar type van mijn TFT schermpjes hebben de 3V3 of 5V jumper.
Het is denk ik betrouwbaarder als de onderdelen die je aan elkaar knoopt van het zelfde spannings niveau zijn.
Verder had ik al aangegeven dat ik een liefhebber ben geworden van de Teensy en deze is 3,3V en dan heb ik ook het probleem niet met de displays en als toegift een betere AD converter :-)

Als er tijd over is vandaag, zie ik uit naar de werking van het stukje code van deKees.

Dank allen voor de input en gegroet,
Bram

You have your way. I have my way. As for the right way, the correct way, and the only way, it does not exist.
EricP

mét CE

Ik weet niet wat blackdog gebruikt, maar de nu gebruikelijke OneWire lib gebruikt een array byte addr[8] voor OneWire adressen.
Zie: http://playground.arduino.cc/Learning/OneWire

Wow. Ze leren bij! :)

Er is allicht vanalles aan te merken op zaken die onder "Arduino" vallen, maar er is geen "Arduino taal", enkel wat libraries die je ook links kunt laten liggen

En dat maakt een Arduino... een Arduino. De hardware is niks anders dan een AVR op een stukkie PCB. Als je die libs niet gebruikt (en dus hun taaltje niet volgt), dan... is het gewoon een AVR.

, en die open source zijn dus waar je desnoods even in kunt duiken om te kijken hoe het werkt.

Dat is mooi. Mooi om te weten hoe het werkt. En dan komt er nog steeds niet uit wat handig is.

Het is allemaal gewoon C / C++.

En op die ++ gaat het fout :)

U maakt zich hier een beetje belachelijk.

Mwah... alleen om dat ik niks van dat Arduino-gedoe moet hebben? Ik denk dat ik lang genoeg met controllers en meer specifiek met AVRs heb gewerkt om het idiote van al die libs in te zien...
Toegegeven, je kunt in weinig tijd iets leuks in elkaar klussen. Als alles doet wat het doen moet. En het spul 'past' zoals het je goed uit komt. Als...

Gillend gek werd ik vanavond door al die rammelende poortinstellingen van converterchips 5V 3V3 enz enz, bah!

Is het spul niet 5V tolerant (blijkbaar niet...).

Het is denk ik betrouwbaarder als de onderdelen die je aan elkaar knoopt van het zelfde spannings niveau zijn.

Het houd het leven in elk geval simpeler. En dat is altijd goed...

Ik ben wel benieuwd wat de resultaten zijn van een stelletjes 1820's. Die nauwkeurigheid die Maxim spect zullen ze wel halen. Wellicht zijn er veel die beter zijn dan dat...

Hallo Bram,

je kan een hex string ook printen als volgt:

c code:

Serial.print(78, HEX) gives "4E"

https://www.arduino.cc/en/serial/print

je kan ook de library functie sprintf gebruiken http://en.cppreference.com/w/cpp/io/c/fprintf

of nog iets meer zelf doen zoals in deze post https://forum.arduino.cc/index.php?topic=38107.msg282343#msg282343
let wel, in de code PrintHex83 moet je de Serial.println(tmp) terug uit commentaar halen

veel plezier ;-)

@EricP; Bedankt voor de uitwijding :)
Ik wil er niet te veel offtopic op door gaan, maar ik versta onder 'Arduino' het geheel van hard- en software. Voor mij persoonlijk zijn de complete, out-of-the-box werkende toolchains voor vele processoren en configuraties de belangrijkste reden om het te gebruiken.
Er zijn ook zeker dingen waar ik wandstuiterig van wordt, zoals de steeds meer creatieve pin nummering :+ En de enorme Arduino Teensy-addon (met zijn gezeur bij opstarten en tientallen eigen libs) vind ik weer onprettig.

Wat betreft 5V / 3V3, als 3V3 gewenst is zou ik ook al snel naar een CPU op 3V3 gaan.
Veel AVR's kunnen daar op draaien, maar (formeel) niet op 16 MHz, dus of het xtal vervangen of als nauwkeurigheid niet zo belangrijk is een interne clock op 8 MHz instellen.