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

Wiring, C++, C, Java, ...
Pravidla fóra
Toto subfórum slouží k řešení obecných otázek kolem programování (konstrukce, knihovny, alokace paměti, ...)
Maxim
Příspěvky: 128
Registrován: 22 led 2019, 20:32
Reputation: 0

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

Příspěvek od Maxim » 18 led 2020, 12:37

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.

Uživatelský avatar
gilhad
Příspěvky: 779
Registrován: 07 bře 2018, 11:22
Reputation: 0

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

Příspěvek od gilhad » 18 led 2020, 13:18

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)

jankop
Příspěvky: 1029
Registrován: 06 zář 2017, 20:04
Reputation: 0
Bydliště: Brno
Kontaktovat uživatele:

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

Příspěvek od jankop » 18 led 2020, 13:46

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š.

Maxim
Příspěvky: 128
Registrován: 22 led 2019, 20:32
Reputation: 0

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

Příspěvek od Maxim » 18 led 2020, 15:16

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?

Uživatelský avatar
kiRRow
Příspěvky: 1152
Registrován: 07 kvě 2019, 07:03
Reputation: 0
Bydliště: Opava

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

Příspěvek od kiRRow » 18 led 2020, 15:23

Myslím, že bez kódu se nehneme ...

Maxim
Příspěvky: 128
Registrován: 22 led 2019, 20:32
Reputation: 0

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

Příspěvek od Maxim » 18 led 2020, 15:29

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.

Uživatelský avatar
kiRRow
Příspěvky: 1152
Registrován: 07 kvě 2019, 07:03
Reputation: 0
Bydliště: Opava

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

Příspěvek od kiRRow » 18 led 2020, 15:36

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 ...

Uživatelský avatar
pavel1tu
Příspěvky: 2054
Registrován: 26 říj 2017, 08:28
Reputation: 0
Bydliště: Trutnov
Kontaktovat uživatele:

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

Příspěvek od pavel1tu » 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 ...
UNO, NANO, Mikro, PRO mini, DUE, ESP32S2, RPi PICO
Pavel1TU
"Správně napsaný kod lze číst jako knihu"

Maxim
Příspěvky: 128
Registrován: 22 led 2019, 20:32
Reputation: 0

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

Příspěvek od Maxim » 18 led 2020, 15:47

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++;

}

Maxim
Příspěvky: 128
Registrován: 22 led 2019, 20:32
Reputation: 0

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

Příspěvek od Maxim » 18 led 2020, 17:23

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: ?

Odpovědět

Kdo je online

Uživatelé prohlížející si toto fórum: Žádní registrovaní uživatelé a 26 hostů