• Witaj na Forum Arduino Polska! Zapraszamy do rejestracji!
  • Znajdziesz tutaj wiele informacji na temat hardware / software.
Witaj! Logowanie Rejestracja


Ocena wątku:
  • 0 głosów - średnia: 0
  • 1
  • 2
  • 3
  • 4
  • 5
Odczyt zmiennej float z macierzy i problem wyświetlaniem (arduino, ds18b20)
#1
Napisałem prostą funkcję wyświetlającą temperaturę z DS18b20 przy użyciu macierzyled. Mam jednak dziwny problem wyświetleniem zmiennej typu float. Dane z czujników temperatury są przechowywane w macierzy czteroelementowej. Wartość temperatury jest rozbijana na trzy cyfry (zmienne d1, d2, d3). Jak wpiszę coś do macierzy ręcznie to wyświetla poprawnie, jak wpiszę przy użyciu biblioteki dallas do obsługi czujnika, to wyświetla bzdury. Ciekawe jest to, że zmienne d1, d2, d3 są poprawnie obliczane. W obydwu przypadkach na serialu mam to samo i nie wiem jak to ugryźć. Coś się dzieje w momencie przejścia danych przez wspomnianą macierz. Spróbowałem też bezpośrednio przy użyciu biblioteki dallas wpisać do zmiennej temp i to też działa. Ewidentnie coś się dzieje przy zapisie do macierzy. Jak odkomentuję linię (//temperatureDallas[0] = 22.3) to jest ok, a jak zakomentuję to nie jest dobrze wyświetlane. Wydruk danych na serialau jest taki sam w obydwu przypadkach. Poniżej przesyłam moją funkcję i wyjście seriala. Czy kto spotkał się z czymś takim?

Kod:
float temperatureDallas[4] = {55,55,55,55};

void ledMatrixAgent(){
  unsigned long currentMillis = millis();
  if (currentMillis - previousMillisLed >= 5000) { //odswiez ekran co 1s
  previousMillisLed = currentMillis; 

  uint16_t TMP[16] = {0}; //tymaczasowy bufor wyswietlacza
  uint8_t d1 = 0, d2 = 0, d3 = 0;
  Serial.print("ds18b20: "); Serial.println(temperatureDallas[0]);
  //temperatureDallas[0] = 22.3;
  float temp = (float)temperatureDallas[0];
  int intiger = (int)temp;
  int fraction = (int)((temp + 0.05 - intiger) * 10); 

  Serial.print("*: "); Serial.println(intiger);
  Serial.print("*: "); Serial.println(fraction);

  d1 = intiger / 10;
  d2 = intiger % 10;
  d3 = fraction;

  //koordynaty wzlędem prawego dolnego rogu
  switch (mode){
    case 0: //tryb bezczynnosci
      Serial.println(d1);
      Serial.println(d2);
      Serial.println(d3);
      for (int8_t i = 9; i >= 0; i--){
        TMP[i+3] |= (uint16_t)M[d1*10+i] << 10;
        TMP[i+3] |= (uint16_t)M[d2*10+i] << 4;
      }

      for (int8_t i = 7; i >= 0; i--){
        TMP[i+5] |= (uint16_t)S[d3*8+i];
      }

      break;
    case 1:
      break;
  }

  //podział na wyswietlacze
  for (uint8_t i = 0; i < 8; i++){
    G_L[i] = (TMP[i] & 0xFF00) >> 8;
    G_P[i] = (TMP[i] & 0x00FF);
  }
  for (uint8_t i = 8; i < 16; i++){
    D_L[i-8] = (TMP[i] & 0xFF00) >> 8;
    D_P[i-8] = (TMP[i] & 0x00FF);
  }

//zapis do wyswietlacza
  //matrix.clear();
  matrix.drawBitmap(0, 0, D_L, 8, 8, LED_ON);
  //matrix.writeDisplay();
  matrix.drawBitmap(8, 0, D_P, 8, 8, LED_ON);
  matrix.writeDisplay();

  //matrix2.clear();
  matrix2.drawBitmap(0, 0, G_L, 8, 8, LED_ON);
  //matrix2.writeDisplay();
  matrix2.drawBitmap(8, 0, G_P, 8, 8, LED_ON);
  matrix2.writeDisplay();
  }
}



Serial:

ds18b20: 22.30
*: 22
*: 3
2
2
3
 
Odpowiedź
#2
Pokazałeś fragment kodu i bez szklanej kuli ciężko pomóc.
 
Odpowiedź
#3
Nie chciałem zamieszczać całego, aby nie zaciemniać, ale ok - daję cały.

Kod:
#include <Wire.h>
#include <Adafruit_GFX.h>
#include "Adafruit_LEDBackpack.h"
#include <OneWire.h>
#include <DallasTemperature.h>

#define SENSORS_DALLAS D5


OneWire oneWire(SENSORS_DALLAS);
DallasTemperature sensorsDallas(&oneWire);
DeviceAddress DallasDeviceAddress[4];
Adafruit_8x16minimatrix matrix = Adafruit_8x16minimatrix();
Adafruit_8x16minimatrix matrix2 = Adafruit_8x16minimatrix();

uint8_t G_L[8] = {0};
uint8_t G_P[8] = {0};
uint8_t D_L[8] = {0};
uint8_t D_P[8] = {0};

uint8_t sensorsLocal = 0;
float temperatureDallas[5] = {55,55,55,55};

//static const uint8_t PROGMEM
uint8_t M[110] = {
//zero
B00011111,
B00011111,
B00011011,
B00011011,
B00011011,
B00011011,
B00011011,
B00011011,
B00011111,
B00011111,
//jeden
B00000111,
B00000111,
B00000011,
B00000011,
B00000011,
B00000011,
B00000011,
B00000011,
B00000011,
B00000011,
//dwa
B00011111,
B00011111,
B00000011,
B00000011,
B00001111,
B00011110,
B00011000,
B00011000,
B00011111,
B00011111,
//trzy
B00011111,
B00011111,
B00000011,
B00000011,
B00011110,
B00011110,
B00000011,
B00000011,
B00011111,
B00011111,
//cztery
B00011011,
B00011011,
B00011011,
B00011011,
B00011111,
B00001111,
B00000011,
B00000011,
B00000011,
B00000011,
//piec
B00011111,
B00011111,
B00011000,
B00011000,
B00011110,
B00001111,
B00000011,
B00000011,
B00011111,
B00011111,
//szesc
B00011111,
B00011111,
B00011000,
B00011000,
B00011110,
B00011111,
B00011011,
B00011011,
B00011111,
B00011111,
//siedem
B00011111,
B00011111,
B00000011,
B00000011,
B00000011,
B00000011,
B00000011,
B00000011,
B00000011,
B00000011,
//osiem
B00011111,
B00011111,
B00011011,
B00011011,
B00011111,
B00011111,
B00011011,
B00011011,
B00011111,
B00011111,
//dziewiec
B00011111,
B00011111,
B00011011,
B00011011,
B00011111,
B00001111,
B00000011,
B00000011,
B00011111,
B00011111,
//pusty
B00000000,
B00000000,
B00000000,
B00000000,
B00000000,
B00000000,
B00000000,
B00000000,
B00000000,
B00000000};

uint8_t S[] = {
//zero
B00000011,
B00000011,
B00000000,
B00000111,
B00000101,
B00000101,
B00000101,
B00000111,
//jeden
B00000011,
B00000011,
B00000000,
B00000001,
B00000001,
B00000001,
B00000001,
B00000001,
//dwa
B00000011,
B00000011,
B00000000,
B00000111,
B00000001,
B00000111,
B00000100,
B00000111,
//trzy
B00000011,
B00000011,
B00000000,
B00000111,
B00000001,
B00000111,
B00000001,
B00000111,
//cztery
B00000011,
B00000011,
B00000000,
B00000101,
B00000101,
B00000111,
B00000001,
B00000001,
//piec
B00000011,
B00000011,
B00000000,
B00000111,
B00000100,
B00000111,
B00000001,
B00000111,
//szesc
B00000011,
B00000011,
B00000000,
B00000111,
B00000100,
B00000111,
B00000101,
B00000111,
//siedem
B00000011,
B00000011,
B00000000,
B00000111,
B00000001,
B00000001,
B00000001,
B00000001,
//osiem
B00000011,
B00000011,
B00000000,
B00000111,
B00000101,
B00000111,
B00000101,
B00000111,
//dziewiec
B00000011,
B00000011,
B00000000,
B00000111,
B00000101,
B00000111,
B00000001,
B00000111,
//pusty
B00000000,
B00000000,
B00000000,
B00000000,
B00000000,
B00000000,
B00000000,
B00000000};

unsigned long previousMillisLed = 0;
unsigned long previousMillisDallas = 0;
uint8_t mode = 0; //tryb pracy wyswietlacza

void setup() {
  //while (!Serial);
  Serial.begin(9600);
  Serial.println("16x8 LED Mini Matrix Test");
 
  matrix.begin(0x70);  // pass in the address
  matrix2.begin(0x71);  // pass in the address

  matrix.setBrightness(0);
  matrix.setRotation(1);
  matrix2.setBrightness(0);
  matrix2.setRotation(1);
 
  matrix.clear();
  matrix2.clear();

  sensorsDallas.begin();
  sensorsLocal = sensorsDallas.getDeviceCount();

  for (int8_t i = 0; i < sensorsLocal; i++){
    sensorsDallas.getAddress(DallasDeviceAddress[i], i);
    sensorsDallas.setResolution(DallasDeviceAddress[i], 11);  
    printAddress(DallasDeviceAddress[i]);
  }
  sensorsDallas.setWaitForConversion(false);
  sensorsDallas.requestTemperatures();
  delay(1000);
}

void loop() {

  ledMatrixAgent();
  dallasAgent();

//  delay(5000);
}

void dallasAgent(){
  unsigned long currentMillis = millis();
  if (currentMillis - previousMillisDallas >= 10000) { //odswiez ekran co 60s
    previousMillisDallas = currentMillis; 
 
    for (uint8_t i = 0; i < sensorsLocal; i++){
      temperatureDallas[i] = sensorsDallas.getTempC(DallasDeviceAddress[i]);
    }
    sensorsDallas.requestTemperatures();
    Serial.println(temperatureDallas[0]);
//    Serial.print("Free memory: ");
//    Serial.println(ESP.getFreeHeap());
  }
}

void ledMatrixAgent(){
  unsigned long currentMillis = millis();
  if (currentMillis - previousMillisLed >= 5000) { //odswiez ekran co 1s
  previousMillisLed = currentMillis; 

  uint16_t TMP[16] = {0}; //tymaczasowy bufor wyswietlacza
  uint8_t d1 = 0, d2 = 0, d3 = 0;
  Serial.print("ds18b20: "); Serial.println(temperatureDallas[0]);
  temperatureDallas[0] = 22.3;
  float temp = (float)temperatureDallas[0];
//  int8_t intiger = (uint8_t)temperature_dallas[0];
//  int8_t fraction = (uint8_t)((temperature_dallas[0] + 0.05 - intiger) * 10);
  int intiger = (int)temp;
  int fraction = (int)((temp + 0.05 - intiger) * 10); 

  Serial.print("*: "); Serial.println(intiger);
  Serial.print("*: "); Serial.println(fraction);

//  intiger = 27.5;
//  fraction = 1;
 
  d1 = intiger / 10;
  d2 = intiger % 10;
  d3 = fraction;

  //koordynaty wzlędem prawego dolnego rogu
  switch (mode){
    case 0: //tryb bezczynnosci
      Serial.println(d1);
      Serial.println(d2);
      Serial.println(d3);
      for (int8_t i = 9; i >= 0; i--){
        TMP[i+3] |= (uint16_t)M[d1*10+i] << 10;
        TMP[i+3] |= (uint16_t)M[d2*10+i] << 4;
      }

      for (int8_t i = 7; i >= 0; i--){
        TMP[i+5] |= (uint16_t)S[d3*8+i];
      }
     
      break;
    case 1:
      break;
  }
 
  //podział na wyswietlacze
  for (uint8_t i = 0; i < 8; i++){
    G_L[i] = (TMP[i] & 0xFF00) >> 8;
    G_P[i] = (TMP[i] & 0x00FF);
  }
  for (uint8_t i = 8; i < 16; i++){
    D_L[i-8] = (TMP[i] & 0xFF00) >> 8;
    D_P[i-8] = (TMP[i] & 0x00FF);
  }

//zapis do wyswietlacza
  //matrix.clear();
  matrix.drawBitmap(0, 0, D_L, 8, 8, LED_ON);
  //matrix.writeDisplay();
  matrix.drawBitmap(8, 0, D_P, 8, 8, LED_ON);
  matrix.writeDisplay();

  //matrix2.clear();
  matrix2.drawBitmap(0, 0, G_L, 8, 8, LED_ON);
  //matrix2.writeDisplay();
  matrix2.drawBitmap(8, 0, G_P, 8, 8, LED_ON);
  matrix2.writeDisplay();
  }
}

// function to print a device address
void printAddress(DeviceAddress deviceAddress)
{
  for (uint8_t i = 0; i < 8; i++)
  {
    // zero pad the address if necessary
    if (deviceAddress[i] < 16) Serial.print("0");
    Serial.print(deviceAddress[i], HEX);
  }
  Serial.println();
}
 
Odpowiedź
#4
"Rozbijanie" temperatury zrbóz z wykorzystaniem sprintf. Prościej i skuteczniej niż jakieś dzielenia i reszty.
Używając sprintf wyświetlaj też zmienne, w ten sposób szybciej namierzysz problem..
 
Odpowiedź
  


Skocz do:


Przeglądający: 1 gości