Stránka 1 z 6

konverze datových typů / komunikace s displayem pomocí SPI

Napsal: 18 led 2020, 12:37
od Maxim
Dobrý den,
poradil by mi někdo jak zobrazovat záznamy teplot na display?
Pro komunikaci s displayem používám knihovny TFT.h a SPI.h.
Pro měření teploty používám čidla DHT22 a DS18s20.
Hodnoty z těchto čidel převádím na INT kvůli úspoře paměti. Z teploty 24.5 tedy mám číslo 245 a dále pak bojuji s konverzí tohoto čísla na CHAR, protože neumím na display poslat jinou proměnnou než CHAR. Možná někdo poradí jak na to? Konverze čísla mi také dělá problémy, protože někdy má číslo 245 tři znaky a někdy čtyři, takže nevím jak jednoduše tam zpátky vložit tečku.
Děkuji za rady.

Re: konverze datových typů / komunikace s displayem pomocí SPI

Napsal: 18 led 2020, 13:18
od gilhad
Proste to ukladej na dve desetina mista, takze 25.4=25.40=2540 25.43=25.43=2543 a 123.45=12345 to se do int vsechno vejde a asi vetsi rozsah nepotrebujes, furt to budou dva byte (pokud muze byt teplota 26 C)

Obracene pouzij modulo 10, modulo 100 a zbytek po deleni stem a mezi to dej pismenko tecka (a ohlidej si, aby i pri 0.01 C se ti to vypsalo aspon do radu jednotek)

Re: konverze datových typů / komunikace s displayem pomocí SPI

Napsal: 18 led 2020, 13:46
od jankop
Troufám si tvrdit, že tvoje snaha na úsporu paměti není efektivní. Už představa že nahrazuješ float - int, abys ušetřil dva bajty paměti je divná.
Na druhé straně ti cokoliv radit je zbytečné, neboť z tvého dotazu se nedá ani náznakem vytušit, jak vypadá program, jaké konkrétní knihovny používáš, nedej bože jaký typ displeje máš k dispozici. Možná bychom přišli na to, že vlastně šetřit paměť ani nepotřebuješ.

Re: konverze datových typů / komunikace s displayem pomocí SPI

Napsal: 18 led 2020, 15:16
od Maxim
Display používám tento
https://www.banggood.com/cs/1_441_82_02 ... rehouse=CN

1,8"

knihovny mimo ty co jsem posílal
#include <OneWire.h> // knihovny pro externí čidlo
#include <DallasTemperature.h> //knihovny pro externí čidlo
#include <LowPower.h>

ukládám si záznamy teploty do pole o 256 prvcích, což zabere přes 70% paměti čipu

pomocí snprintf překonvertuju číslo na text, ale je to trochu boj
existují nějaké lepší funkce?

Re: konverze datových typů / komunikace s displayem pomocí SPI

Napsal: 18 led 2020, 15:23
od kiRRow
Myslím, že bez kódu se nehneme ...

Re: konverze datových typů / komunikace s displayem pomocí SPI

Napsal: 18 led 2020, 15:29
od Maxim

Kód: Vybrat vše

char pridaniDesetinneTecky(char *vstupniPole , int vstupniPoleLen) {

    vstupniPole[vstupniPoleLen] = vstupniPole[vstupniPoleLen - 1];
    vstupniPole[vstupniPoleLen - 1] = '.';
    vstupniPole[vstupniPoleLen + 1] = 0;
    
 }

Zde je pokus o funkci, která mi vloží desetinou tečku zpět do řetězce, ale nefunguje správně, protože vstupniPoleLen je pokaždé jiné číslo.

Re: konverze datových typů / komunikace s displayem pomocí SPI

Napsal: 18 led 2020, 15:36
od kiRRow
celý kód ...

nebudem tu přece dny řešit nějakou funkci, která tam v důsledku ani nemusí být, protože se to celý dá udělat jinak ...

Re: konverze datových typů / komunikace s displayem pomocí SPI

Napsal: 18 led 2020, 15:47
od pavel1tu
Normálně přes sprintf,

https://arduinobasics.blogspot.com/2019 ... ction.html

a ta konverze tě trvale žádnou paměť nestojí,
udělej sina to jednu proměnnou
char retezec_tmp[20] - počet znaků podle max. delky zobrazovaného textu.
Je to nejjednodušší a nejčistší, než to nějak lámat jak se tu výše naznačuje ...

Re: konverze datových typů / komunikace s displayem pomocí SPI

Napsal: 18 led 2020, 15:47
od Maxim

Kód: Vybrat vše

// include TFT and SPI libraries
#include <TFT.h>
#include <SPI.h>
#include "DHT.h" //knihovna pro modul DHT22
#include <OneWire.h> // knihovny pro externí čidlo
#include <DallasTemperature.h> //knihovny pro externí čidlo
#include <LowPower.h>


// pin definition for Arduino UNO
#define cs   10
#define dc   9
#define rst  8
#define DHTPIN 6 //nastavení PINu pro modul DHT22
#define DHTTYPE DHT22   // DHT 22  (AM2302)

// nastavení čísla vstupního pinu pro externí čidlo
const int pinCidlaDS = 5;
// vytvoření instance oneWireDS z knihovny OneWire (ext. čidlo)
OneWire oneWireDS(pinCidlaDS);
// vytvoření instance senzoryDS z knihovny DallasTemperature (ext. čidlo)
DallasTemperature senzoryDS(&oneWireDS);


// create an instance of the library
TFT TFTscreen = TFT(cs, dc, rst);

DHT dht(DHTPIN, DHTTYPE);

int16_t nejvyssiTeplota = -100;
int16_t nejnizsiTeplota = 200;

int casNejvyssiTeplota;
int casNejnizsiTeplota;
int casNamereniNejvyssiTeploty;
int casNamereniNejnizsiTeploty;
long casOdStartuArduina;
int pocetUspani;

int vstavej = 0;
int pocetStlaceni = 0;
int posledniStavTlacitka = 0;
int uspat = 0;
int hlidac = 0;

int16_t zaznamyTeplot[256]; //tady bude asi nutné uložit nějaké speciální hodnoty a né nuly
int16_t zaznamyTeplotExt[256]; //

uint8_t indexTeplot = 0; //index který zapisuji jako index pole záznamů teplot, sám přeteče při 255+1

int16_t indexNejnizsiTeploty = 0;
int16_t indexNejvyssiTeploty = 0;
int16_t nejnizsiUlozenaTeplota = 901;
int16_t nejvyssiUlozenaTeplota = -900;

int16_t indexNejnizsiTeplotyExt = 0;
int16_t indexNejvyssiTeplotyExt = 0;
int16_t nejnizsiUlozenaTeplotaExt = 9010;
int16_t nejvyssiUlozenaTeplotaExt = -2000;

String tlacitkoText;
char tlacitkoTextZobraz[10];

int prevodCislaNaText(char *pomocnePole , size_t velikostPole , int16_t VstupINT) { // funkce která vykouzlí pole charů pomocí nějakých odkazů na pole... musí se správně předat parametry

  int VystupCHARlen;
  if (VstupINT < 0) {
    VystupCHARlen = snprintf(pomocnePole, velikostPole , "%i" , (int)VstupINT); //převede záporný int "VstupINT" na řetězec "pomocnePole" a uloží do VystupCHARlen délku proměnné velikostPole, kterou vrací funkce snprinf
  } else {
    VystupCHARlen = snprintf(pomocnePole, velikostPole - 1 , "%i" , (int)VstupINT); //převede kladný int "VstupINT" na řetězec "pomocnePole" a uloží do VystupCHARlen délku proměnné velikostPole, kterou vrací funkce snprinf
  }
  return VystupCHARlen;

}

char pridaniDesetinneTecky(char *vstupniPole , int vstupniPoleLen) {

  if (vstupniPoleLen < 4) {
    vstupniPole[vstupniPoleLen] = vstupniPole[vstupniPoleLen - 1];
    vstupniPole[vstupniPoleLen - 1] = '.';
    vstupniPole[vstupniPoleLen + 1] = 0;
  } else {
    vstupniPole[vstupniPoleLen] = vstupniPole[vstupniPoleLen - 1];
    vstupniPole[vstupniPoleLen - 1] = vstupniPole[vstupniPoleLen];
    vstupniPole[vstupniPoleLen - 2] = vstupniPole[vstupniPoleLen - 1];
    vstupniPole[vstupniPoleLen - 2] = '.';
    vstupniPole[vstupniPoleLen] = 0;
  }
  return vstupniPole;

}    

long zobrazeniCasuAZnakuCasu(char *pomocnePole , size_t velikostPole , long hodnotaCasu) {

  long hodnotaCasuUpravena = hodnotaCasu;

  if (hodnotaCasu < 99) {

    hodnotaCasuUpravena = snprintf(pomocnePole, velikostPole - 1, "%i" , (long)hodnotaCasu); //převede int "hodnotaCasu" na řetězec "velikostPole" a uloží do velikostPole délku proměnné velikostPole, kterou vrací funkce snprinf
    pomocnePole[hodnotaCasuUpravena] = 's'; //na konec řetězce připíše s

  }

  if ((hodnotaCasu > 99) and (hodnotaCasu < 5939)) {
    hodnotaCasuUpravena = hodnotaCasu / 60;
    hodnotaCasuUpravena = snprintf(pomocnePole, velikostPole - 1, "%i" , (long)hodnotaCasuUpravena); //převede int "hodnotaCasu" na řetězec "velikostPole" a uloží do velikostPole délku proměnné velikostPole, kterou vrací funkce snprinf
    pomocnePole[hodnotaCasuUpravena] = 'm'; //na konec řetězce připíše m

  }

  if (hodnotaCasu > 5939) {
    hodnotaCasuUpravena = hodnotaCasu / 3600;
    hodnotaCasuUpravena = snprintf(pomocnePole, velikostPole - 1, "%i" , (long)hodnotaCasuUpravena); //převede int "hodnotaCasu" na řetězec "velikostPole" a uloží do velikostPole délku proměnné velikostPole, kterou vrací funkce snprinf
    pomocnePole[hodnotaCasuUpravena] = 'h'; //na konec řetězce připíše h

  }

  pomocnePole[hodnotaCasuUpravena + 1] = 0; //vytvoří novou zarážku na konci řetězce

  return hodnotaCasu + 1;

}


void setup() {

  Serial.begin(9600);

  pinMode(3, INPUT_PULLUP); //pin pro vstup tlačítka
  pinMode(A0, INPUT);

  Serial.println("DHT22 funguje!"); //ověření spojení s modulem DHT22

  senzoryDS.begin();

  //initialize the library
  TFTscreen.begin();

  // clear the screen with a black background
  TFTscreen.background(0, 0, 0);

}

void loop() {

  float h = dht.readHumidity();
  float t = dht.readTemperature();
  senzoryDS.requestTemperatures();
  float te = senzoryDS.getTempCByIndex(0);

  int16_t teplotaZaznamINT = t * 10; // teplota vynásobená 10 (pro úsporu paměti)
  int16_t teplotaExtZaznamINT = te * 100; // teplota vynásobená 100 (pro úsporu paměti)

  int sensorValue = analogRead(A0);
  // Převede analogový vstup (od 0 do 1023) na napětí (0 - 5V):
  float voltage = sensorValue * (5.0 / 1023.0);
  float voltageUpravene = voltage * 100;
  int voltageINT = int(voltageUpravene);

  zaznamyTeplot[indexTeplot] = teplotaZaznamINT; //zapíše hodnotu teploty s indexem indexTeplot
  zaznamyTeplotExt[indexTeplot] = teplotaExtZaznamINT; //zapíše hodnotu teploty externího čidla s indexem indexTeplot
  indexTeplot++;
  int tlacitko = digitalRead(3);  

  nejnizsiUlozenaTeplota = 901;
  nejvyssiUlozenaTeplota = -200;
  indexNejnizsiTeploty = 0;
  indexNejvyssiTeploty = 0;

  for (int16_t i = 0; i < 256; i++) {

    int16_t porovnavanaTeplota = zaznamyTeplot[i];
    int16_t porovnavanaTeplotaExt = zaznamyTeplotExt[i];

    if (porovnavanaTeplota != 0) {

      if (porovnavanaTeplota < nejnizsiUlozenaTeplota) {
        nejnizsiUlozenaTeplota = porovnavanaTeplota;
        indexNejnizsiTeploty = i;
      }
      if (porovnavanaTeplota > nejvyssiUlozenaTeplota) {
        nejvyssiUlozenaTeplota = porovnavanaTeplota;
        indexNejvyssiTeploty = i;
      }

    }

    if (porovnavanaTeplotaExt != 0) {

      if (porovnavanaTeplotaExt < nejnizsiUlozenaTeplotaExt) {
        nejnizsiUlozenaTeplotaExt = porovnavanaTeplotaExt;
        indexNejnizsiTeplotyExt = i;
      }
      if (porovnavanaTeplotaExt > nejvyssiUlozenaTeplotaExt) {
        nejvyssiUlozenaTeplotaExt = porovnavanaTeplotaExt;
        indexNejvyssiTeplotyExt = i;
      }

    }

  }

  //test a nastavení nejvyšší a nejnižší teploty
  if (nejvyssiTeplota < t) {
    nejvyssiTeplota = t * 10;
    casNejvyssiTeplota = millis() / 1000;
  }

  if (nejnizsiTeplota > t) {
    nejnizsiTeplota = t * 10;
    casNejnizsiTeplota = millis() / 1000;
  }

  casOdStartuArduina = millis() / 1000;

  char teplotaHodnota[5];
  char teplotaExtHodnota[7];
  char vlhkostHodnota[5];
  char nejvyssiTeplotaZobraz[5];
  char casNamereniNejvyssiTeplotyHodnota[8];
  char nejnizsiTeplotaZobraz[5];
  char casNamereniNejnizsiTeplotyHodnota[8];
  char casNejvyssiTeplotaZobrazit[8];
  char pocetSekundOdStartu[8];
  char indexNejnizsiTeplotyZobraz[4];
  char indexNejvyssiTeplotyZobraz[4];
  char indexNejnizsiTeplotyZobrazExt[4];
  char indexNejvyssiTeplotyZobrazExt[4];
  char napetiZobraz[4];
  char napetiZobrazDouble[4];
  char pocetUspaniZobraz[5];

  int16_t nejnizsiUlozenaTeplotaINT = nejnizsiUlozenaTeplota * 10;
  int16_t nejvyssiUlozenaTeplotaINT = nejvyssiUlozenaTeplota * 10;
  int16_t aktualniTeplotaINT = t * 10;

  char nejnizsiUlozenaTeplotaZobrazit[5];
  char nejvyssiUlozenaTeplotaZobrazit[5];
  char aktualniTeplotaZobrazit[5];
  char napetiZobrazit[5];

  char buffer[5];

  //nejnizsiTeplotaZobrazit = snprintf(buffer, 6 , "%i" , nejnizsiUlozenaTeplotaINT);

  //char nejnizsiTeplotaZobrazit[6];
  prevodCislaNaText(indexNejnizsiTeplotyZobraz, sizeof(buffer4) , indexNejnizsiTeploty);
  prevodCislaNaText(indexNejvyssiTeplotyZobraz, sizeof(buffer4) , indexNejvyssiTeploty);

  int nejnizsiTeplotaZobrazLen = prevodCislaNaText(nejnizsiTeplotaZobraz , sizeof(buffer) , nejnizsiTeplota);

  pridaniDesetinneTecky(nejnizsiTeplotaZobraz , nejnizsiTeplotaZobrazLen);

  int nejvyssiTeplotaZobrazLen = prevodCislaNaText(nejvyssiTeplotaZobraz , sizeof(buffer) , nejvyssiTeplota);
  pridaniDesetinneTecky(nejvyssiTeplotaZobraz , nejvyssiTeplotaZobrazLen);

  int aktualniTeplotaZobrazitLen = prevodCislaNaText(aktualniTeplotaZobrazit, sizeof(buffer) , aktualniTeplotaINT);
  pridaniDesetinneTecky(aktualniTeplotaZobrazit , aktualniTeplotaZobrazitLen);

  prevodTeplotyNaText(nejnizsiUlozenaTeplotaZobrazit, sizeof(buffer) , nejnizsiUlozenaTeplotaINT);
  Serial.print(nejnizsiUlozenaTeplotaZobrazit);
  Serial.print("-");
  Serial.print(nejnizsiUlozenaTeplotaZobrazit[2]);
  Serial.print("-");
  int zkkk = sizeof(nejnizsiUlozenaTeplotaZobrazit);
  Serial.print(zkkk);
  Serial.println("-");
  pridaniDesetinneTecky(nejnizsiUlozenaTeplotaZobrazit , zkkk);
  Serial.print(nejnizsiUlozenaTeplotaZobrazit);
  int nejvyssiUlozenaTeplotaZobrazitLen = prevodCislaNaText(nejvyssiUlozenaTeplotaZobrazit, sizeof(buffer) , nejvyssiUlozenaTeplotaINT);
  Serial.println(nejvyssiUlozenaTeplotaZobrazitLen);
  pridaniDesetinneTecky(nejvyssiUlozenaTeplotaZobrazit , nejvyssiUlozenaTeplotaZobrazitLen);

  prevodCislaNaText(napetiZobrazit, sizeof(buffer) , voltageINT);
  pridaniDesetinneTecky2(napetiZobrazit);
  napetiZobrazit[4] = 0;

  //char nejnizsiUlozenaTeplotaZobrazit[6];
  //prevodTeplotyNaText(nejnizsiUlozenaTeplotaZobrazit, sizeof(nejnizsiUlozenaTeplotaZobrazit) , nejnizsiUlozenaTeplota);

  //char nejvyssiUlozenaTeplotaZobrazit[6];
  //prevodTeplotyNaText(nejvyssiUlozenaTeplotaZobrazit, sizeof(nejvyssiUlozenaTeplotaZobrazit) , nejvyssiUlozenaTeplota);

  //char nejnizsiUlozenaTeplotaExtZobrazit[6];
  //prevodTeplotyExtNaText(nejnizsiUlozenaTeplotaExtZobrazit, sizeof(nejnizsiUlozenaTeplotaExtZobrazit) , nejnizsiUlozenaTeplotaExt);


  TFTscreen.background(0, 0, 0);
  TFTscreen.stroke(100, 255, 100); //zelená
  TFTscreen.setTextSize(1);

  TFTscreen.text("T: ", 3 , 2);
  TFTscreen.text(aktualniTeplotaZobrazit, 23, 2);

  TFTscreen.stroke(255, 150, 150); // modrá
  TFTscreen.text(nejnizsiTeplotaZobraz, 54, 2);

  TFTscreen.stroke(50, 50, 255); // červená
  TFTscreen.text(nejvyssiTeplotaZobraz, 86, 2);

  TFTscreen.stroke(255, 255, 255); //bílá
  //TFTscreen.text("'C", 130, 2);
  /*
    TFTscreen.text("Vlhkost akt.: ", 3 , 16);
    TFTscreen.text(vlhkostHodnota, 83, 16);
    TFTscreen.text("%", 110, 16);

    TFTscreen.text("Ext. tepl.: ", 3 , 29);
    TFTscreen.text(teplotaExtHodnota, 83, 29);
    TFTscreen.text("'C", 120, 29);
  */
  TFTscreen.text("Nap.: ", 3 , 45);
  TFTscreen.text(napetiZobrazit, 83, 45);
  TFTscreen.text("V", 120, 45);

  /*
    //TFTscreen.stroke(255, 255, 255); //bílá
    //TFTscreen.text(casNejvyssiTeplotaZobrazit, 3, 60);

    //TFTscreen.text(textZobrazit, 25, 60);

    //TFTscreen.text(teplotaZobrazit, 100, 70);

    TFTscreen.stroke(100, 255, 100); //zelená
    TFTscreen.text(tlacitkoTextZobraz, 3, 55);
  */
  TFTscreen.stroke(255, 100, 100); // modrá
  TFTscreen.text(nejnizsiUlozenaTeplotaZobrazit, 3, 70);
  TFTscreen.text(indexNejnizsiTeplotyZobraz, 35, 70);

  TFTscreen.stroke(50, 50, 255); //červená
  TFTscreen.text(nejvyssiUlozenaTeplotaZobrazit, 60, 70);
  TFTscreen.text(indexNejvyssiTeplotyZobraz, 90, 70);

  //minimální a maximální externí teploty
  //TFTscreen.stroke(255, 255, 255); //bílá
  //TFTscreen.text("Ext:", 3, 85);

  //TFTscreen.stroke(255, 100, 100); // modrá
  //TFTscreen.text(nejnizsiUlozenaTeplotaExtZobrazit, 30, 85);
  //TFTscreen.text(indexNejnizsiTeplotyZobrazExt, 35, 85);

  //TFTscreen.stroke(50, 50, 255); //červená
  //TFTscreen.text(nejvyssiUlozenaTeplotaExtZobrazit, 90, 85);
  //TFTscreen.text(indexNejvyssiTeplotyZobrazExt, 90, 85);


  /*
    TFTscreen.stroke(255, 255, 255); //bílá
    TFTscreen.text(pocetSekundOdStartu, 3, 115);

    TFTscreen.stroke(255, 255, 255); //bílá
    TFTscreen.text(casZobrazit, 73, 115);
    TFTscreen.text(pocetUspaniZobraz, 100, 115);


    //TFTscreen.text(zaznamyTeplot);
  */

  // wait 500 miliseconds until change to next color
  delay(30);
  LowPower.powerDown(SLEEP_120MS, ADC_OFF, BOD_OFF);
  pocetUspani++;

}

Re: konverze datových typů / komunikace s displayem pomocí SPI

Napsal: 18 led 2020, 17:23
od Maxim
pavel1tu píše:
18 led 2020, 15:47
Normálně přes sprintf,

https://arduinobasics.blogspot.com/2019 ... ction.html

a ta konverze tě trvale žádnou paměť nestojí,
udělej sina to jednu proměnnou
char retezec_tmp[20] - počet znaků podle max. delky zobrazovaného textu.
Je to nejjednodušší a nejčistší, než to nějak lámat jak se tu výše naznačuje ...
sprintf mi nefunguje s floatem

Kód: Vybrat vše

sprintf(data, "Floats f: %f , .1f: %.1f , .3f: %.3f", myFloat, myFloat, myFloat);
Serial.println(data);
toto mi vypíše

Floats f: ? , .1f: ? , .3f: ?