• 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
Prośba o pomoc przy kodzie
#1
Witam, korzystając z kilku projektów postanowiłem złożyć jeden. Nawet mi się wszystko udało i elementy działają.
Na płytce Arduino Uno zamontowałem czujnik czystości powietrza PMS3003 z użyciem 8bitowego konventera oraz dołożyłem czujnik temperatury i wilgotności DHT22. Wszystko podłaczyłem przez magistralę I2C do wyświetlacza LCD 20x4. Z kilku kodów złożyłem jeden który działa i wszystko co chciałem wyświetla się poprawnie.
Problem zaczął się w momencie próby przeniesienia kodu na wyświetlacz OLED  SH1106 0,96".
W żaden sposób nie mogę sobie poradzić aby zostały wyświetlone informacje z czujnika PMS3003, ( z DHT22 pobiera i wyświetla ).
Czy ktoś może mi pomóc przy tym kodzie ? 
Sam nie znam nic z tego zawsze korzystam z gotowych i częściowo przerabiam pod swoje potrzeby na zasadzie intuicji.
Tu gotowy który działa na lcd20x4
#include <stdio.h>
#include <dht.h> //DHT and LCD libraries
#define N 23
#include <LiquidCrystal_I2C.h>
#define I2C_ADDR 0x27
#define BACKLIGHT_PIN 3
#define En_pin 2
#define Rw_pin 1
#define Rs_pin 0
#define D4_pin 4
#define D5_pin 5
#define D6_pin 6
#define D7_pin 7
LiquidCrystal_I2C lcd(I2C_ADDR,En_pin,Rw_pin,Rs_pin,D4_pin,D5_pin,D6_pin,D7_pin);
dht DHT; //Declaring the DHT as a dht type to use it later
char linia1[20], linia2[20];
unsigned char bufor [N];
int PM25 = 20, PM10 = 20;
int wartoscPM25(unsigned char *thebuf);
int wartoscPM10(unsigned char *thebuf);
char sprawdzLancuch(unsigned char *thebuf, char leng);

#define DHT22_PIN 7 //Declaring where the DHT signal pin is wired


void setup(){
  Serial.begin(9600);
  lcd.begin (20,4);   
    lcd.print("Czekaj..."); // napis kontrolny
  lcd.createChar(0, termometr);
  lcd.createChar(1, kropla);
  lcd.createChar(2, stopnie);
  lcd.setBacklightPin(BACKLIGHT_PIN,POSITIVE);
  lcd.setBacklight(HIGH);   
  lcd.setCursor(0,0); 
  lcd.home ();   
}

void loop(){
  if(Serial.find(0x42))   
    Serial.readBytes(bufor,N);

    if(bufor[0] == 0x4d){
      if(sprawdzLancuch(bufor,N)){ 
        PM25=wartoscPM25(bufor);
        PM10=wartoscPM10(bufor); 
    }
    }
  lcd.clear();
  lcd.setCursor(0,0); // kursor na trzeci wiersz
  int chk = DHT.read22(DHT22_PIN); //Reading data from the module
  lcd.write((byte)0); // rzutuję ikonę termomrtr na typ byte i wyświetlam ją na lcd
  lcd.print(" TEMP= ");
  lcd.print(DHT.temperature); // wypisuję zmienną temp
  lcd.print("");
  lcd.write((byte)2); // jak ww.
  lcd.print("C");
  lcd.setCursor(0,1); // kursor na czwarty wiersz
  lcd.write((byte)1); // jak ww.
  lcd.print(" WILG= ");
  lcd.print(DHT.humidity); // wypisuję zmienną wilg
  lcd.print(" %");
  lcd.setCursor(0,2);
  sprintf(linia1,"PM2.5 = %d ug/m3",PM25);
  lcd.print(linia1);
  lcd.setCursor(0,3);
  sprintf(linia2,"PM10  = %d ug/m3",PM10);
  lcd.print(linia2);
  delay(2000); // czekam 2s
}

int wartoscPM25(unsigned char *buf) // generacja wartosci PM2,5
{
  int PM25v;
  PM25v=((buf[11]<<8) + buf[12]); 
  return PM25v;
}

int wartoscPM10(unsigned char *buf) // generacja wartosci PM10
{
  int PM10v;
  PM10v=((buf[13]<<8) + buf[14]);
  return PM10v;
}

bool sprawdzLancuch(unsigned char *buf, int dlugosc) // sprawdzenie poprawności lancucha

  bool flaga=0;
  int suma=0;

  for(int i=0; i<(dlugosc-2); i++){
  suma+=buf[i];
  }
suma=suma + 0x42;

  if(suma == ((buf[dlugosc-2]<<8)+buf[dlugosc-1])) 
  {
    suma = 0;
    flaga = 1;
  }
  return flaga;
}


A tu kod który zacząłem dostosowywać do wyświetlacza OLED  SH1106 0,96 też po SCL i SDA.

#include "U8glib.h"
#include "dht.h"

#include <stdio.h>

#define dht_apin 7

#define N 23

dht DHT;

char linia1[20], linia2[20];

unsigned char bufor [N];

int PM25 = 20, PM10 = 20;

int wartoscPM25(unsigned char *thebuf);

int wartoscPM10(unsigned char *thebuf);

char sprawdzLancuch(unsigned char *thebuf, char leng);



U8GLIB_SH1106_128X64 u8g(U8G_I2C_OPT_NONE);                    // I2C / TWI 1.3

//U8GLIB_SSD1306_128X64 u8g(U8G_I2C_OPT_NONE|U8G_I2C_OPT_DEV_0);    // I2C / TWI 0.96



void draw(void) {

u8g.setFont(u8g_font_helvR10); u8g.drawStr(20, 12, "Temp: "); u8g.drawStr(20, 27, "Wilg: ");

u8g.setFont(u8g_font_helvR10); u8g.drawStr(20, 43, "PM2.5: "); u8g.drawStr(20, 59, "PM10: ");

u8g.setFont(u8g_font_helvR10);

u8g.setPrintPos(70, 12); u8g.print(DHT.temperature, 0); u8g.drawStr(100, 12, "C");

u8g.setPrintPos(70, 27); u8g.print(DHT.humidity, 0); u8g.drawStr(100, 27, "%"); 

}



void setup(void) {

  if(Serial.find(0x42))   

    Serial.readBytes(bufor,N);



    if(bufor[0] == 0x4d){

      if(sprawdzLancuch(bufor,N)){ 

        PM25=wartoscPM25(bufor);

        PM10=wartoscPM10(bufor); 

    }

}

}

void loop(void) {

 

DHT.read22(dht_apin); // Read apin on DHT11 or DHT22

u8g.firstPage(); do { draw();

}

while( u8g.nextPage() );

delay(5000);

}

int wartoscPM25(unsigned char *buf) // generacja wartosci PM2,5

{

  int PM25v;

  PM25v=((buf[11]<<8) + buf[12]); 

  return PM25v;

}



int wartoscPM10(unsigned char *buf) // generacja wartosci PM10

{

  int PM10v;

  PM10v=((buf[13]<<8) + buf[14]);

  return PM10v;

}



bool sprawdzLancuch(unsigned char *buf, int dlugosc) // sprawdzenie poprawności lancucha



  bool flaga=0;

  int suma=0;



  for(int i=0; i<(dlugosc-2); i++){

  suma+=buf[i];

  }

suma=suma + 0x42;



  if(suma == ((buf[dlugosc-2]<<8)+buf[dlugosc-1])) 

  {

    suma = 0;

    flaga = 1;

  }

  return flaga;
}



Do tego etapu doszedłem i stanąłem, Temperaturę i wilgotność wyświetla lecz pozostałych dwóch PM2.5 i PM10 nie  potrafię tak przekopiować aby nie było błędu.

Dziękuję za ewentualną pomoc.
 
Odpowiedź
#2
Tu pokażę jak to wygląda na YT.
https://youtu.be/ln4rgg5ljuM
 
Odpowiedź
#3
No bo w tym kodzie (dla OLED) nie napisałeś instrukcji dla wyświetlania danych z PMS, więc ich nie wyświetla.

(10-07-2019, 14:27)whitedog169 napisał(a): nie  potrafię tak przekopiować aby nie było błędu.

Jakie błędy pokazuje kompilator?
Jeśli masz problem z kodem lub sprzętem, zadaj pytanie na forum. Nie odpowiadam na PW, jeśli nie dotyczą one spraw forum lub innych tematów prywatnych.

[Obrazek: SsIndaG.jpg]
 
Odpowiedź
#4
(10-07-2019, 15:27)Robson Kerman napisał(a): No bo w tym kodzie (dla OLED) nie napisałeś instrukcji dla wyświetlania danych z PMS, więc ich nie wyświetla.

(10-07-2019, 14:27)whitedog169 napisał(a): nie  potrafię tak przekopiować aby nie było błędu.

Jakie błędy pokazuje kompilator?
Na chwilę obecną nie pokazuje błędów, do tego etapu na którym się zatrzymałem.
Program się wgrywa i wyświetla na OLED.
Teraz chcę aby dane z PMS były wyświetlane i analogicznie jak pozostałe linijki próbuję z jednego kodu wkleić do kodu drugiego w takiej postaci:
u8g.setPrintPos(70, 43); u8g.print(linia1,"PM2.5 = %d ug/m3",PM25); u8g.drawStr(100, 43, "ug/m3");
i tu już kompilator krzyczy
 
Odpowiedź
#5
ok, program wgrywa się poprawnie.
Troszkę zmieniłem.
Wyświetlają się wszystkie 4 wartości tylko jest jedno ale,.
Temperatura i wilgotność faktycznie widać że się zmieniają natomiast pyłki PM 10 i PM2.5 wyświetlaja tylko stałą wartość 20. Jeszcze gdzieś czegoś brakuje.
Kod wygląda teraz tak:
#include "U8glib.h"
#include "dht.h"

#include <stdio.h>

#define dht_apin 7

#define N 23

dht DHT;

char linia1[20], linia2[20];

unsigned char bufor [N];

int PM25 = 20, PM10 = 20;

int wartoscPM25(unsigned char *thebuf);

int wartoscPM10(unsigned char *thebuf);

char sprawdzLancuch(unsigned char *thebuf, char leng);



U8GLIB_SH1106_128X64 u8g(U8G_I2C_OPT_NONE); // I2C / TWI 1.3

//U8GLIB_SSD1306_128X64 u8g(U8G_I2C_OPT_NONE|U8G_I2C_OPT_DEV_0); // I2C / TWI 0.96



void draw(void) {

u8g.setFont(u8g_font_helvR10); u8g.drawStr(10, 12, "Temp: "); u8g.drawStr(10, 27, "Wilg: ");
u8g.setFont(u8g_font_helvR10); u8g.drawStr(10, 43, "PM2.5: "); u8g.drawStr(10, 59, "PM10: ");
u8g.setFont(u8g_font_helvR10);
u8g.setPrintPos(60, 12); u8g.print(DHT.temperature, 0); u8g.drawStr(90, 12, "C");
u8g.setPrintPos(60, 27); u8g.print(DHT.humidity, 0); u8g.drawStr(90, 27, "%");
u8g.setPrintPos(60, 43); u8g.print((linia1,"PM2.5 = %d ug/m3",PM25)); u8g.drawStr(90, 43, "ug");
u8g.setPrintPos(60, 59); u8g.print((linia2,"PM10 = %d ug/m3",PM10)); u8g.drawStr(90, 59, "ug");
}
void setup(void) {

}
void loop(void)

{
if(Serial.find(0x42))
Serial.readBytes(bufor,N);
if(bufor[0] == 0x4d){
if(sprawdzLancuch(bufor,N)){
PM25=wartoscPM25(bufor);
PM10=wartoscPM10(bufor); }}
DHT.read22(dht_apin); // Read apin on DHT11 or DHT22}

u8g.firstPage(); do { draw();
}
while( u8g.nextPage() );
delay(500);
}
int wartoscPM25(unsigned char *buf) // generacja wartosci PM2,5
{
int PM25v;
PM25v=((buf[11]<<8) + buf[12]);
return PM25v;
}
int wartoscPM10(unsigned char *buf) // generacja wartosci PM10
{
int PM10v;
PM10v=((buf[13]<<8) + buf[14]);
return PM10v;

}



bool sprawdzLancuch(unsigned char *buf, int dlugosc) // sprawdzenie poprawności lancucha

{

bool flaga=0;

int suma=0;



for(int i=0; i<(dlugosc-2); i++){

suma+=buf[i];

}

suma=suma + 0x42;



if(suma == ((buf[dlugosc-2]<<8)+buf[dlugosc-1]))

{

suma = 0;

flaga = 1;

}

return flaga;
}
 
Odpowiedź
#6
No bo w pierwszym kodzie formatujesz dane i wpisujesz je do zmiennej linia1
Kod:
sprintf(linia1,"PM2.5 = %d ug/m3",PM25);

A następnie wyświetlasz tę zmienną
Kod:
lcd.print(linia1);

W ostatnim kodzie wysyłasz do wyświetlacza takie coś:
Kod:
u8g.print((linia1,"PM2.5 = %d ug/m3",PM25));

Nie wiem czy ta procedura potrafi obsłużyć ten format.
Spróbuj:
Kod:
sprintf(linia1,"PM2.5 = %d ug/m3",PM25);
u8g.print(linia1);
Jeśli masz problem z kodem lub sprzętem, zadaj pytanie na forum. Nie odpowiadam na PW, jeśli nie dotyczą one spraw forum lub innych tematów prywatnych.

[Obrazek: SsIndaG.jpg]
 
Odpowiedź
#7
Rozdziel problem przygotowania zmiennych do wyświetlania i samo wyświetlanie. Na czas testowania nowego ekranu możesz zastąpić wnętrza funkcji do czujników po prostu licznikami, przy każdym wywołaniu funkcji do pyłu zrób tylko return licznik++ i koniec. Będziesz wiedział czy problem jest po stronie kodu do ekranu czy po stronie czujników, bo np. się kabelek źle podłączyło przy okazji zmiany ekranu a Ty szukasz problemu tam gdzie go nie ma.
 
Odpowiedź
#8
Mógłbyś też wrzucić kod na pastebina, żeby było łatwiej czytać. No i stosuj zasadę MWE w takich przypadkach Tongue
 
Odpowiedź
#9
Na początek dziękuję za zainteresowanie, kod nadal nie działa.
Przypomnę kod dostosowywałem z istniejącego działającego na LCD20x4.
Na obecnym OLED na który to chcę przenieść projekt zamiast zmieniać (wyświetlać) wartość pozyskaną z czujnika pyłu wyświetla stałą wartość 20.
jeżeli zmienię w tej linijce wartość na jakąkolwiek inną:
int PM25 =20, PM10 =20;
to na taką też zmieni mi na OLED.

Na LCD20x4 mam podobnie ale tylko wówczas gdy wypnę piny z płytki Uno RX i TX na czas wgrania programu, wtedy wyświetla się wartość 20 lecz zaraz po podłączeniu ponownie następuje prawidłowy odczyt.

Dziś jeszcze raz cały układ podpiąłem pod LCD20x4 I2C i działa świetnie, zmieniam ekran na OLED wgrywam program pod nowy ekran i wartości stoją.

Nie wiem czy można zamieszczać linki ale wrzuciłem ten kod do pastebina jak życzył sobie jeden z kolegów.
https://pastebin.pl/view/ce573021
 
Odpowiedź
#10
Kod nadal nie działa, bo nic z nim nie zrobiłeś.
Przecież napisałem co masz zmienić.
Dla czego upierasz się przy tej konstrukcji?:
u8g.print((linia1,"PM2.5 = %d ug/m3",PM25))
Możesz mi wyjaśnić jak działa funkcja u8g.print?
Poczytaj: https://github.com/olikraus/u8glib/wiki/...ence#print
Jeśli masz problem z kodem lub sprzętem, zadaj pytanie na forum. Nie odpowiadam na PW, jeśli nie dotyczą one spraw forum lub innych tematów prywatnych.

[Obrazek: SsIndaG.jpg]
 
Odpowiedź
  


Skocz do:


Przeglądający: 1 gości