[Arduino/c++] Dane z wyświetlacza do pamięci podręcznej?


(Hotfils3) #1

Witam!

Posiadam: Arduino Uno Rev3

Swoją przygodę z arduino zacząłem 2 dni temu. Ale c++ znam już od jakiegoś czasu i pewne komendy w miarę ogarniam. Swoją drogą nie wiem czy arduino to c++ czy c? Mam wyświetlacz 7-segmentowy, 4-cyfrowy ze wspólną anodą. Ogarnąłem jak wyświetlać na nim tekst i dzisiaj po południu zakończyłem swój pierwszy program - termometr. Program zczytuje temperaturę z czujnika, konwertuje ją na pierwszą i drugą cyfrę liczby, po czym “dekoder” ustala które segmenty mają się świecić i “przełącznik” układa znaki na wyświetlaczu. Niestety proces odczytu stanu czujnika trwa gdzieś 400ms co powoduje że muszę mrugnąć ekranem żeby zaktualizować temperaturę… Tata powiedział, że mogę tak coś zrobić że przerzucę stan wyświetlacza do -gdzieś tam- i wtedy mogę procesorem odczytać stan, a jednocześnie ekran będzie podtrzymywany przez to co przerzucę -gdzieś tam-. Moje pytanie brzmi czy -gdzieś tam- o którym mówie istnieje, i czy da się tam zapisać wystarczającą ilość danych do podtrzymania wyświetlacza. Załączam kod który pisałem dobre 2 dni :slight_smile:

Domyślam się że jest toporny, ale cóż… Mój pierwszy kod :slight_smile: Komentarze pisałem sam do siebie żeby się nie pogubić.

#include <Multiplex7Seg.h>
int aPin = 3; //Pin
int bPin = 4; //Pin
int cPin = 5; //Pin
int dPin = 6; //Pin
int ePin = 7; //Pin
int fPin = 8; //Pin
int gPin = 9; //Pin
int cyfra1 = 10; //Pin
int cyfra2 = 11; //Pin
int cyfra3 = 12; //Pin
int cyfra4 = 13; //Pin
bool cyfra1on = false; //zmienna
bool cyfra2on = false;
bool cyfra3on = false;
bool cyfra4on = false;
bool error = false;
int odswt = 200; //ile razy ekran bedzie odswiezony temperatura
int odsww = 200; //odswiezen na wilgotnosci
int temp1;
int temp2;
int temphumidity = 1;

#include <DHT.h>
#define DHTPIN 2
#define DHTTYPE DHT11
DHT dht(DHTPIN, DHTTYPE);

void setup() {
  Serial.begin(9600);
  Serial.println("Miernik temperatury");
  dht.begin();
  pinMode(aPin, OUTPUT); //Segmenty jak sa low to swieca
  pinMode(bPin, OUTPUT); //jak sa high to nie swieca
  pinMode(cPin, OUTPUT);
  pinMode(dPin, OUTPUT);
  pinMode(ePin, OUTPUT);
  pinMode(fPin, OUTPUT);
  pinMode(gPin, OUTPUT);
  pinMode(cyfra1, OUTPUT); //Cyfry daje na zawsze HIGH
  pinMode(cyfra2, OUTPUT);
  pinMode(cyfra3, OUTPUT);
  pinMode(cyfra4, OUTPUT);
}
void loop() {
  wyswietlanie();
  switch(odswt) {
    case 0:
    nic();
    updt();
    delay(0);
    odswt=200;
    break;
    deafult:
    loop();
    break;
  }
}
void updt() { //aktualizacja temp i obliczenia
  int temperatura = dht.readTemperature();
  temp1 = temperatura / 10;
  temp2 = temperatura - (temp1 * 10);
}
void dekoder() { //dekoduje cyfry na patterny
  }

void wyswietlanie() { //gotowa funckja wyswietlajaca
  petla();
  przelacznik1();
  petla();
  przelacznik2();
  petla();
  przelacznik3();
  petla();
  przelacznik4();
  --odswt;
}
  void przelacznik1() { //przelacza wejscie na cyfry
  digitalWrite(cyfra1, HIGH);
  digitalWrite(cyfra2, LOW);
  digitalWrite(cyfra3, LOW);
  digitalWrite(cyfra4, LOW);
  cyfra1on = false;
  cyfra2on = true;
  cyfra3on = false;
  cyfra4on = false;
  delay(5);
  }
  void przelacznik2() {
  digitalWrite(cyfra1, LOW);
  digitalWrite(cyfra2, HIGH);
  digitalWrite(cyfra3, LOW);
  digitalWrite(cyfra4, LOW);
  cyfra1on = false;
  cyfra2on = false;
  cyfra3on = true;
  cyfra4on = false;
  delay(5);
  }
  void przelacznik3() {
  digitalWrite(cyfra1, LOW);
  digitalWrite(cyfra2, LOW);
  digitalWrite(cyfra3, HIGH);
  digitalWrite(cyfra4, LOW);
  cyfra1on = false;
  cyfra2on = false;
  cyfra3on = false;
  cyfra4on = true;
  delay(5);
  }
  void przelacznik4() {
  digitalWrite(cyfra1, LOW);
  digitalWrite(cyfra2, LOW);
  digitalWrite(cyfra3, LOW);
  digitalWrite(cyfra4, HIGH);
  cyfra1on = true;
  cyfra2on = false;
  cyfra3on = false;
  cyfra4on = false;
  delay(5);
}
  void odczyt() { //odczyt z czujnika
  delay(0);
  float wilgotnosc = dht.readHumidity();
  float temperatura = dht.readTemperature();
  if (isnan(wilgotnosc) || isnan(temperatura)) {
    Serial.println("Wystapil blad odczytu!");
    return;
  }
  float heatindex = dht.computeHeatIndex(temperatura, wilgotnosc, false);
  Serial.print("Wilgotnosc: ");
  Serial.print(wilgotnosc);
  Serial.print(" %\t");
  Serial.print("Temperatura: ");
  Serial.print(temperatura);
  Serial.print(" *C\t");
  Serial.println("Koniec odczytu");
}
  void petla() { //ta petla rozmieszcza cyfry na wyswietlaczu
  if(cyfra1on != 0) {
    switch(temp1) {
    case 1:
    jeden();
    break;
    case 2:
    dwa();
    break;
    case 3:
    trzy();
    break;
    case 4:
    cztery();
    break;
    case 5:
    piec();
    break;
    case 6:
    szesc();
    break;
    case 7:
    siedem();
    break;
    case 8:
    osiem();
    break;
    case 9:
    dziewiec();
    break;
    case 0:
    nic();
    break;
  } }
  else;
  if(cyfra2on != 0) {
    switch(temp2) {
      case 1:
      jeden();
      break;
      case 2:
      dwa();
      break;
      case 3:
      trzy();
      break;
      case 4:
      cztery();
      break;
      case 5:
      piec();
      break;
      case 6:
      szesc();
      break;
      case 7:
      siedem();
      break;
      case 8:
      osiem();
      break;
      case 9:
      dziewiec();
      break;
      case 0:
      zero();
      break;
      ;
    }
  } else;
  if(cyfra3on != 0) stopien(); else
  if(cyfra4on != 0) c(); else
  error=true;
}
void nic() { //gotowe patterny - nic
  digitalWrite(aPin, HIGH);
  digitalWrite(bPin, HIGH);
  digitalWrite(cPin, HIGH);
  digitalWrite(dPin, HIGH);
  digitalWrite(ePin, HIGH);
  digitalWrite(fPin, HIGH);
  digitalWrite(gPin, HIGH);  
}
void zero() { //zero
  digitalWrite(aPin, LOW);
  digitalWrite(bPin, LOW);
  digitalWrite(cPin, LOW);
  digitalWrite(dPin, LOW);
  digitalWrite(ePin, LOW);
  digitalWrite(fPin, LOW);
  digitalWrite(gPin, HIGH);
}
void jeden() { //jeden
  digitalWrite(aPin, HIGH);
  digitalWrite(bPin, LOW);
  digitalWrite(cPin, LOW);
  digitalWrite(dPin, HIGH);
  digitalWrite(ePin, HIGH);
  digitalWrite(fPin, HIGH);
  digitalWrite(gPin, HIGH);
}
void dwa() { //dwa
  digitalWrite(aPin, LOW);
  digitalWrite(bPin, LOW);
  digitalWrite(cPin, HIGH);
  digitalWrite(dPin, LOW);
  digitalWrite(ePin, LOW);
  digitalWrite(fPin, HIGH);
  digitalWrite(gPin, LOW);
}
void trzy() { //trzy
  digitalWrite(aPin, LOW);
  digitalWrite(bPin, LOW);
  digitalWrite(cPin, LOW);
  digitalWrite(dPin, LOW);
  digitalWrite(ePin, HIGH);
  digitalWrite(fPin, HIGH);
  digitalWrite(gPin, LOW);
}
void cztery() { //cztery
  digitalWrite(aPin, HIGH);
  digitalWrite(bPin, LOW);
  digitalWrite(cPin, LOW);
  digitalWrite(dPin, HIGH);
  digitalWrite(ePin, HIGH);
  digitalWrite(fPin, LOW);
  digitalWrite(gPin, LOW);
}
void piec() { //piec
  digitalWrite(aPin, LOW);
  digitalWrite(bPin, HIGH);
  digitalWrite(cPin, LOW);
  digitalWrite(dPin, LOW);
  digitalWrite(ePin, HIGH);
  digitalWrite(fPin, LOW);
  digitalWrite(gPin, LOW);
}
void szesc() { //szesc
  digitalWrite(aPin, LOW);
  digitalWrite(bPin, HIGH);
  digitalWrite(cPin, LOW);
  digitalWrite(dPin, LOW);
  digitalWrite(ePin, LOW);
  digitalWrite(fPin, LOW);
  digitalWrite(gPin, LOW);
}
void siedem() { //siedem
  digitalWrite(aPin, LOW);
  digitalWrite(bPin, LOW);
  digitalWrite(cPin, LOW);
  digitalWrite(dPin, HIGH);
  digitalWrite(ePin, HIGH);
  digitalWrite(fPin, HIGH);
  digitalWrite(gPin, HIGH);
}
void osiem() { //osiem
  digitalWrite(aPin, LOW);
  digitalWrite(bPin, LOW);
  digitalWrite(cPin, LOW);
  digitalWrite(dPin, LOW);
  digitalWrite(ePin, LOW);
  digitalWrite(fPin, LOW);
  digitalWrite(gPin, LOW);
}
void dziewiec() { //dziewiec
  digitalWrite(aPin, LOW);
  digitalWrite(bPin, LOW);
  digitalWrite(cPin, LOW);
  digitalWrite(dPin, LOW);
  digitalWrite(ePin, HIGH);
  digitalWrite(fPin, LOW);
  digitalWrite(gPin, LOW);
}
void stopien() { //stopien
  digitalWrite(aPin, LOW);
  digitalWrite(bPin, LOW);
  digitalWrite(cPin, HIGH);
  digitalWrite(dPin, HIGH);
  digitalWrite(ePin, HIGH);
  digitalWrite(fPin, LOW);
  digitalWrite(gPin, LOW);
}
void c() { //C
  digitalWrite(aPin, LOW);
  digitalWrite(bPin, HIGH);
  digitalWrite(cPin, HIGH);
  digitalWrite(dPin, LOW);
  digitalWrite(ePin, LOW);
  digitalWrite(fPin, LOW);
  digitalWrite(gPin, HIGH);
}
void h() { //H
  digitalWrite(aPin, HIGH);
  digitalWrite(bPin, LOW);
  digitalWrite(cPin, LOW);
  digitalWrite(dPin, HIGH);
  digitalWrite(ePin, LOW);
  digitalWrite(fPin, LOW);
  digitalWrite(gPin, LOW);  
}

 


(przemor25) #2

Za dużo tych break-ów :stuck_out_tongue:


(Drobok) #3

Nie piszę dla arduino. Ale dla atmegi wyświetlanie sprowadza się do przesłania rejestru do danego portu. Stan którym sterujesz zależy od podłączenia diody pod port. Więc arduino sam z siebie tego nie obejdzie.

Nie ustawiaj każdego pinu po kolei tylko ustaw cały port. Skróci ci to kod o 90%. Trzymanie w incie małych liczb mija się z celem. Tracisz tylko cenną pamięć.

Powinieneś korzystać z przerwań, odświeżanie dynamiczne powinieneś realizować dla danej częstotliwości (np 100Hz na segment), więc pętla dla 4segmentów powinna mieć 400 iteracji na sekundę.

Wyświetlanie pojedynczego segmentu powinnieneś mieć tak:

Ty zmieniasz stan na podstawie zapalonego segmentu, więc nawet jak poprawie zrealizujesz wyświetlanie dynamiczne to będzie ci to migać (stan n będzie widziany jako (n-1)n). 

Gdy przestaniesz obciążać odświeżaniem cały procesor, to wtedy termometr nie będzie ci nic psuł.

Zamiast robić wielki switch (a w praktyce masę warunków) zrób tablicę, oszczędzisz dość sporo czasu na pozostałe obliczenia.


(Hotfils3) #4

Czyli - jeśli dobrze rozumiem - puenta jest taka, że jeśli uproszczę kod o: port, tablicę i bardziej poprawną funkcję wyświetlania to będę obciążał procesor w 50%? I pozostały procent użyję na sczytanie temperatury? Chyba źle zrozumiałem - wydaje mi się że 100% procesora idzie na aktualnie wykonywaną czynność. Nie ma multitaskingu :P Ajajaj… Generalnie widzę że bez szerszej wiedzy daleko nie zajdę, więc pouczę się tych tablic, portów i wtedy przepiszę kod na nowo.

Wielkie dzięki za wszystkie cenne uwagi!


(Drobok) #5

Coś w ten deseń, tyle że nie 50%, a kilka %.

Ty robisz coś w kółko, mnóstwo razy pomijając mnóstwo zbędnych instrukcji (np dla 1 wykonasz 1 porównanie a dla 9 porównań 9). Np delay zajmuje procesor na Xms (o ile taktowanie w środowisku jest równe taktowaniu procesora). Więc przez Xms nie możesz zrobić kompletnie nic.

Procesor będzie robił coś w stylu:

:nic


(Hotfils3) #6

Delay’e używam tylko i wyłącznie dlatego, że nie znam żadnej innej funkcji powodującej zamrożenie / opóźnienie / wydłużenie / przerwę. W delphi pisałem freeze czy jakoś tak i to kompletnie zamrażało program. Tyle wiem. Ale postaram się doedukować i zobaczę jak to wyjdzie.

 

EDIT: Ale nawet jeśli ogarnę kod to będę mógł odczytać temperaturę w tle? Podczas nieustannego wyświetlania?


(Drobok) #7

Ty nie wyświetlasz nieustannie, tylko mrugasz tymi diodami ponad 100x/s - dzięki temu ludzkie oko nie widzi że dioda mruga, jasność zwiększasz prądem diody. Tak działa np wyświetlanie obrazu na ekranie.

Zacznij od przerwań. Później zainteresuj się wyświetlaniem dynamicznym, a później połącz to i dołóż termometr. W necie jest sporo kodu więc tego co masz aktualnie się nie kalkuluje przerabiać (a raczej wycinać z niego większości