2024. április 15., hétfő

Fénypisztoly - Jurassic Park

 Amikor még gimnáziumba jártam Budapesten olyan 1999 körül, a Corvin moziban volt kirakva egy játéktermi játékgép: The Lost World: Jurassic Park

1997-ben hozta ki a Sega, gondolom az azonos című azonos évben bemutatott Jurassic Park marketingjére ülve.

Suli után sokat játszottunk rajta, nem volt olcsó, ha jól emlékszem 200 forint volt egy zseton hozzá.

A képen a bal oldali masina. Ez a kép amúgy a Savoya parkban készült az azóta már bezárt Arcadia Savoya játékteremben 2023 decemberében. Elvileg ez csak egy kiállítás volt, fix árért az összes géppel lehetett játszani korlátlan ideig.


Szóval nagyon hangulatos volt ez a Jurassic Park Arcade gép. Gondoltam megnézem van-e PC-s változata, és igen volt. Mégpedig az arcade gép eredeti ROM-ját lehet PC-n emulálni. Nagyon megörültem, de egérrel túl könnyű vele játszani. Az eredeti gépen úgynevezett fény pisztolyok voltak. Ahová irányította az ember a pisztolyt, oda tudott lőni. De ez csak a katódsugárcsöves monitorokon működött. Manapság már LCD kijelzők vannak. Erre van egy új megoldás ami gyakorlatilag a Nintendo Wii controllerét használja fegyverként. A tv fölé kell rakni egy infra led fényforrást és a controller infra kamerája ezt lekövetve, egérként is tudjuk használni. Aztán voltak házi megoldások is, csináld magad fénypisztoly, infra kamerával Arduino-val. Na én ezt raktam össze végül, hogy tudjak a plazma tévén játszani vele. A leggazdaságosabban egy Wii controllerrel lehet megoldani, ha van de ekkor is kell az infra led fényforrás. Wii sensor bar-nak hívják. Létezik egy kiegészítő is a Wii kontrollerhez amibe berakva egy pisztoly formát kapunk.

Tehát hozzávalók, ahogyan én csináltam:

- a Farnell-től SEN0158 IR POSITIONING CAMERA, ARDUINO BOARD 85258300

10.000 forint volt

-Arduino Leonardo, ide az Uno nem jó, mert a Leonardo tud csak egeret emulálni

-kartondoboz a pisztoly formához

-nyomógombok a tüzeléshez

-kábelek

-egy 5méteres usb kábel

A megvalósításhoz az ötletet innen vettem és másoltam: (ez két link)

SAMCO DIY Light Gun - Trouble Shooting Sketch (youtube.com)

GitHub - samuelballantyne/IR-Light-Gun: Arduino Library for the SAMCO Arduino Powered IR Light Gun

Íme a végeredmény. A használat, ha rádugtuk a számítógépre, el kell indítani az Arduino IDE-t és a serial monitort. Persze be kell kapcsolni az infra ledeket is. A kamerát az infra ledekre mutatva meg kell nyomni a kalibráló gombot, ami nekem a piros gomb bal oldalon. Utána a tűz gomb 1x, nálam ez az alsó mikrokapcsoló belül. Utána a tv bal felső sarkára célozva újabb tűz gomb, majd a tv bal alsó sarkára célozva újabb tűz gomb. Innentől elvileg egérként tudjuk használni.

Meg kell jegyezzem az én nagy plazma tévémmel nem működik jól mert túl nagy a tv átmérője. Az infra kamera érzékelési szöge pedig elég kicsi. Maga az arduino kód sem hiszem hogy tökéletes nagyon remeg az egérmutató. Egy Wii kontroller valószínű sokkal jobb lenne. A kalibráció során is vannak gondok mert néha csak sokadjára sikerül működésre bírni ha véletlenül túlságosan kifelé célozva nyomjuk meg a tűzgombot, ekkor a kamea nem látja az infra led forrást és rosszul kalobrál.






Saját készítésű infra led fal. Próbapadokra bedugtam két infra ledet, két ellenállással, egy usb végű kábelről megtáplálva ami egy power bank-ból kapja az áramot. Egy teli knozerv pedig tartja az egészet.





Arduino kód:

/*
  Samco - Arduino Powered IR Light Gun
  Go to https://github.com/samuelballantyne for code & instructions.
  created June 2019
  by Sam Ballantyne
  This sample code is part of the public domain.
*/
int positionX[4];               // RAW Sensor Values
int positionY[4];               
int oneY = 0;                   // Re-mapped so left sensor is always read first
int oneX = 0;
int twoY = 0;
int twoX = 0;
int finalX = 0;                 // Values after tilt correction
int finalY = 0;
int xLeft = 0;                  // Stored calibration points
int yTop = 0;
int xRight = 0;
int yBottom = 0;
int MoveXAxis = 0;              // Unconstrained mouse postion
int MoveYAxis = 0;               
int conMoveXAxis = 0;           // Constrained mouse postion
int conMoveYAxis = 0;           
int count = 4;                  // Set intial count
int caliPin = A1;               // Set Calibration Pin (change to A4 to use ALT Pin)
int leftPin = A2;               // Set Left Mouse Pin
int rightPin = A3;
int buttonState1 = 0;           // Set Button states
int lastButtonState1 = 0;
int buttonState2 = 0;
int lastButtonState2 = 0;
int buttonState3 = 0;
int lastButtonState3 = 0;
int buttonState4 = 0;         
int lastButtonState4 = 0;
int buttonState5 = 0;         
int lastButtonState5 = 0;      
#include <HID.h>                // Load libraries
#include <Wire.h>
#include <AbsMouse.h>
#include <DFRobotIRPosition.h>
DFRobotIRPosition myDFRobotIRPosition;
int res_x = 1920;               // Put your screen resolution width here
int res_y = 1080;               // Put your screen resolution height here

void setup() {
  
  
  Serial.begin(9600);                     // For debugging (make sure your serial monitor has the same baud rate)
  AbsMouse.init(res_x, res_y);            
  pinMode(caliPin, INPUT_PULLUP);         // Set pin modes
  pinMode(leftPin, INPUT_PULLUP);
  pinMode(rightPin, INPUT_PULLUP);
  
  myDFRobotIRPosition.begin();            // Start IR Camera
  AbsMouse.move((res_x / 2), (res_y / 2));          // Set mouse position to centre of the screen
  
  delay(500);
  
}



void loop() {
  if (count > 3) {
    getPosition();
    mouseButtons();
    PrintResults();
    go();
  }
  /* ------------------ START/PAUSE MOUSE ---------------------- */

  else if (count > 2 ) {

    skip();
    mouseCount();

  }

  /* ---------------------- TOP LEFT --------------------------- */

  else if (count > 1 ) {
    AbsMouse.move(300, 200);
    mouseCount();
    getPosition();
    reset();
    xLeft = finalX;
    yTop = finalY;
    PrintResults();
  }

  /* -------------------- BOTTOM RIGHT ------------------------- */

  else if (count > 0 ) {
    AbsMouse.move((res_x - 300), (res_y - 200));
    mouseCount();
    getPosition();
    reset();
    xRight = finalX;
    yBottom = finalY;
    PrintResults();
  }

  /* ---------------------- LET'S GO --------------------------- */

  else {
    AbsMouse.move(conMoveXAxis, conMoveYAxis);
    mouseButtons();
    getPosition();
    MoveXAxis = map (finalX, xLeft, xRight, 300, (res_x - 300));
    MoveYAxis = map (finalY, yTop, yBottom, 200, (res_y - 200));
    conMoveXAxis = constrain (MoveXAxis, 0, res_x);
    conMoveYAxis = constrain (MoveYAxis, 0, res_y);
    
    PrintResults();
    reset();


  }
}

/*        -----------------------------------------------        */
/* --------------------------- METHODS ------------------------- */
/*        -----------------------------------------------        */

void getPosition() {    // Get tilt adjusted position from IR postioning camera
  myDFRobotIRPosition.requestPosition();
  if (myDFRobotIRPosition.available()) {
    for (int i = 0; i < 4; i++) {
      positionX[i] = myDFRobotIRPosition.readX(i);
      positionY[i] = myDFRobotIRPosition.readY(i);
    }
        if (positionX[0] > positionX[1]) {
      oneY = positionY[0];
      oneX = positionX[0];
      twoY = positionY[1];
      twoX = positionX[1];
    }
    else if (positionX[0] < positionX[1]) {
      oneY = positionY[1];
      oneX = positionX[1];
      twoY = positionY[0];
      twoX = positionX[0];
    }
    else {
      oneY = 1023;
      oneX = 0;
      twoY = 1023;
      twoX = 0;
    }
    
    finalX = 512 + cos(atan2(twoY - oneY, twoX - oneX) * -1) * (((oneX - twoX) / 2 + twoX) - 512) - sin(atan2(twoY - oneY, twoX - oneX) * -1) * (((oneY - twoY) / 2 + twoY) - 384);
    finalY = 384 + sin(atan2(twoY - oneY, twoX - oneX) * -1) * (((oneX - twoX) / 2 + twoX) - 512) + cos(atan2(twoY - oneY, twoX - oneX) * -1) * (((oneY - twoY) / 2 + twoY) - 384);
  }
  else {
    Serial.println("Device not available!");
  }
}


void go() {    // Setup Start Calibration Button
  buttonState1 = digitalRead(caliPin);
  if (buttonState1 != lastButtonState1) {
    if (buttonState1 == LOW) {
      count--;
    }
    else { // do nothing
    }
    delay(50);
  }
  lastButtonState1 = buttonState1;
}


void mouseButtons() {    // Setup Left, Right & Middle Mouse buttons
  buttonState2 = digitalRead(leftPin);
  buttonState3 = digitalRead(rightPin);
  if (buttonState2 != lastButtonState2) {
    if (buttonState2 == LOW) {
      AbsMouse.press(MOUSE_LEFT);
    }
    else {
      AbsMouse.release(MOUSE_LEFT);
    }
    delay(10);
  }
  if (buttonState3 != lastButtonState3) {
    if (buttonState3 == LOW) {
      AbsMouse.press(MOUSE_RIGHT);
    }
    else {
      AbsMouse.release(MOUSE_RIGHT);
    }
    delay(10);
  }

  lastButtonState2 = buttonState2;
  lastButtonState3 = buttonState3;
}

void mouseCount() {    // Set count down on trigger
  buttonState2 = digitalRead(leftPin);
  if (buttonState2 != lastButtonState2) {
    if (buttonState2 == LOW) {
      count--;
    }
    else { // do nothing
    }
    delay(10);
  }
  lastButtonState2 = buttonState2;
}


void reset() {    // Pause/Re-calibrate button
  buttonState1 = digitalRead(caliPin);
  if (buttonState1 != lastButtonState1) {
    if (buttonState1 == LOW) {
      count = 3;
      delay(50);
    }
    else { // do nothing
    }
    delay(50);
  }
  lastButtonState1 = buttonState1;
}

void skip() {    // Unpause button
  buttonState1 = digitalRead(caliPin);
  if (buttonState1 != lastButtonState1) {
    if (buttonState1 == LOW) {
      count = 0;
      delay(50);
    }
    else { // do nothing
    }
    delay(50);
  }
  lastButtonState1 = buttonState1;
}


void PrintResults() {    // Print results for debugging
  Serial.print("RAW: ");
  Serial.print(finalX);
  Serial.print(", ");
  Serial.print(finalY);
  Serial.print("     Count: ");
  Serial.print(count);
  Serial.print("     Calibration: ");
  Serial.print(xLeft);
  Serial.print(", ");
  Serial.print(yTop);
  Serial.print(", ");
  Serial.print(xRight);
  Serial.print(", ");
  Serial.print(yBottom);
  Serial.print("     Position: ");
  Serial.print(conMoveXAxis);
  Serial.print(", ");
  Serial.println(conMoveYAxis);
}




2024. április 14., vasárnap

Az otthoni levegő minősége

Elkezdett foglalkoztatni az otthoni levegő minőségének a témája. Édesanyám mindig mondta, hogy szellőztessek, persze én inkább csukva szerettem tartani az ablakot mert nem akartam a hideget és meleget beengedni. A szobaajtót is becsuktam, hogy a főzés és a tv hangja se érjen el. Nem ideális körülmények a létezésre. Gondoltam vásárolok egy szén-dioxid mérőt és megnézem tényleg van-e értelme szellőztetni. Miért szén-dioxid mérőt? Azért mert az ember lélekzéskor szén-dioxidot lélekzik ki, ami így egyre jobban feldúsul a zárt térben. Utána lehet nézni milyen tüneteket okoz a túl sok szén-dioxid a levegőben. Fáradtság, fejfájás, szem irritáció, száraz torok, szédülés, koncentrációzavar, köhögés. 



Tehát vettem egy CO2 szenzort (Sensirion SCD41 kb 3x3cm a mérete) és elkezdtem mérni a hálószobában lefekvés után a széndioxid koncentrációt a levegőben. Mennyi a normális co2 mennyiség? Szabad levegőn kb 400ppm jelenleg a co2 koncentráció. Ez lenne az ideális szint. 1000ppm felett már magasnak mondják. A szenzor amit vettem ppm értéket ad, tehát ideális a méréshez. 

Megjegyzem a lakásban egyedül tartózkodtam.

A hálószobám 8m2 nagyságú a légköbméter 21 m3. Elég kicsi! Szóval éjszakára becsuktam ajtót ablakot és mértem. A kiinduló érték 550ppm volt. Ez egy óra múlva 900ppm, 2 óra múlva 1200ppm, 3 óra múlva 1500ppm, 4 óra múlva 1860ppm, 4 és fél óra múlva 2000ppm-re nőtt! Ekkor felkeltem és kinyitottam az ablakot. Eléggé rémisztőnek tűnik a dolog.

Következő mérés nyitott szobaajtó, csukott ablak. A lakás 63m2-es. 530ppm-ről indultam 7 és fél óra alatt még nem érte el az 1000ppm-et, de fokozatosan emelkedett a szint.

Következő mérés. A másik szobában az ablakot bukóra hagytam nyitva egész éjjel. Így egész végig 500-550ppm körül maradt a szén-dioxid szint. Azóta így alszom. 

Kíváncsi voltam észreveszek-e változást az alvás minőségében. De még mennyire, sokkal nyugodtabban alszom és kipihentebben ébredek. Ajánlom mindenkinek. 

Vajon ha mondjuk ketten aludtunk volna a szobában csukott ajtóval, ablakkal milyen értékek lettek volna? Talán ezért olyan fáradtak az emberek? Vagy egy irodában ahol egy szobában 8-an ülnek és nem megy a szellőzés ott mi lehet?

Itt felmerülhet az a kérdés, hogy oké, nyitva hagyom az ablakot, de akkor bejön a hideg vagy a meleg, bejön a zaj, a szmog. Ez mind igaz. Ezért rosszabb a városban lakók életminősége. Én jelenleg Budapesten a XI. kerületben lakom. Éjszakára bukón nyitva hagyom az ablakot a lakás nem hül ki. A zaj elviselhető. A szmog, légszennyezés nyomon követhető a meteorológia szolgálat mérőállomásaival, vagy az idokep.hu oldalon. De leginkább a következő weboldalt ajánlom:

https://sensor.community/hu/

Itt közösségi közreműködők, bárki által üzembe helyezett érzékelők adatait valós időben feltöltve látható a levegő minősége. Ha a légszennyezettség közepesnél rosszabb, akkor nem hagyom nyitva az ablakot. Ideális az lenne ha egy légszűrős szellőztető rendszert építenék a lakásba ami akkor is szellőztetne ha kint szennyezett a levegő. Szerencsére a szennyezett napok elég ritkák ott ahol lakom így ebbe nem fogtam bele. 

Hogy valós képet kaphassak a lakásomnál a levegő minőségéről, vásároltam egy szálló por/Nitrogén oxid mérő szenzort is. (Sensirion Sen55 - kb 5x5 cm nagy) 

Ez valós időben méri a PM1.0, PM2.5, PM4.0 és PM10 méretű részecskéket a levegőben. Valamint a Nitrogén oxidokat is. Ha valaki nem akar erre szánni, az a sensor.community oldalon nyomon tudja követni a szennyezéseket. Én idén Budapesten Január 31-én és február 1-én éreztem, hogy nagyon szennyezett a levegő, de azt is elfújta a szél talán már másnap vagy harmadnap. Legutóbb húsvétkor érkezett szaharai homok a levegőben, ez rontott a levegő minőségen.

Ezen kívül rendben volt a levegő minősége. Ezt a cikket 2024. április 4-én írom.

A meteorológiai szolgálat méréseivel kapcsolatban látok furcsaságokat. A levegő munkacsoport azt állítja a mérőállomásai nem a legdurvább helyeken hanem parkokban vannak. Az is torzítja a mérést, hogy óránkénti értéket adnak csak meg és ott is a legrosszabb mérési értékeket. Szerintem a közösségi valós idejű mérések sokkal pontosabban mutatják a helyzetet.

Más kérdés nagyvároson kívül, sok helyen fával tüzelnek, nagyon sok helyen szemetet égetnek. Ilyenkor ha van az embernek saját mérőeszköze jobb helyzetben van, mert ha más nem teszi közzé a mérési adatait a faluban mondjuk akkor nem tudja az ember mi van, csak az orrára és szemére hagyatkozhat. 

A legjobbnak a levegő szűrős, levegőt felmelegítő/hűtő folyamatos szellőztető rendszer tűnik.

CO2 mérő összeállítása:

Eszközök amit használtam:

-Arduino Uno

-Sensirion SCD41 ez nagyon drága volt, 25.000 forint, de rendeltem egyet kínából is az aliexpressről, ott 8700-ért lehet kapni és mint kiderült ugyan olyan jó



-kábel: JST1.0 SH1.0 4-pin cable with socket male DuPont wire For STEMMA QT/QWIIC

stemma qt 4-es csatlakozós a másik oldala sima tűs



-Adafruit Monochrome 0.96" 128x64 OLED Graphic Display - STEMMA QT

erről a kijelzőről lehet leolvasni az értékeket, aki számítógépről használja, annak nem kell kijelző.

Ez 10.000 forint volt, de aliexpressről 600 forintért rendeltem egy másikat.



-kábel: JST1.0 SH1.0 4-pin cable with socket male DuPont wire For STEMMA QT/QWIIC

ebből a stemm qt-ból olyat kell venni aminek mindkét vége a 4-es csatlakozójú


Én az I2C protokolt használtam. Itt két kábel kell az adatforgalomnak, a másik kettő a pozitív és negatív kábel az áramellátáshoz. A co2 szenzorba bedugtam a 4-es csatlakozó egyik végét, a másik végét a kijelzőbe. A kijelző másik csatlakozójába a 4-es csatlakozó és a másik végén tűs kábelt. 

A 4 kábel közül kettő a pozitív és negatív a másik kettő az Arduino SCL és SDA csatlakozójára kötendő. Az én képeimen a kábelek színezése eltérő lehet mint amit kap az ember a boltban, mindig ellenőrizzük melyik hova csatlakozik, a szín nem mindig egyezik!+

Az I2C eszközöknek van egyedi azonosítójuk a 0x3D és 0x3C a kijelzőké, az scd41-nek 0x62.






A használt kód az eredeti adafruit kijelzővel:

#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <Arduino.h>
#include <SensirionI2CScd4x.h>
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
// The pins for I2C are defined by the Wire-library. 
// On an arduino UNO:       A4(SDA), A5(SCL)
// On an arduino MEGA 2560: 20(SDA), 21(SCL)
// On an arduino LEONARDO:   2(SDA),  3(SCL), ...
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);
SensirionI2CScd4x scd4x;


void setup() {
  Serial.begin(9600);
  //display.dim(true);
  // SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally
  if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3D)) {
    Serial.println(F("SSD1306 allocation failed"));
    for(;;); // Don't proceed, loop forever
  }
  // Show initial display buffer contents on the screen --
  // the library initializes this with an Adafruit splash screen.
  display.display();
  delay(500); // Pause for 2 seconds
  // Clear the buffer
  display.clearDisplay();
 Wire.begin(0x62);
 //uint16_t error;
 //   char errorMessage[256];
  scd4x.begin(Wire);
  scd4x.startPeriodicMeasurement();
display.dim(true);
}
  
  void loop() {
delay(5000);
    uint16_t co2;
    float temperature;
    float humidity;
    scd4x.readMeasurement(co2, temperature, humidity);
    display.clearDisplay();
    display.setTextSize(3);             // Normal 1:1 pixel scale
    display.setTextColor(SSD1306_WHITE);        // Draw white text
    display.setCursor(0, 0);            // Start at top-left corner
//    display.print(F("Co2: "));
    display.println(co2);
//    display.print(F("Temperature: "));
    display.println(temperature);
//    display.print(F("Humidity: "));
    display.println(humidity);
    display.display();
     
    }

A használt kód a kínai másolat kijelzővel:

#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <Arduino.h>
#include <SensirionI2CScd4x.h>

#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
#define OLED_RESET -1

// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
// The pins for I2C are defined by the Wire-library. 
// On an arduino UNO:       A4(SDA), A5(SCL)
// On an arduino MEGA 2560: 20(SDA), 21(SCL)
// On an arduino LEONARDO:   2(SDA),  3(SCL), ...
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);
SensirionI2CScd4x scd4x;



void setup() {
  Serial.begin(9600);

  //display.dim(true);

  // SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally
  if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3D)) {
    Serial.println(F("SSD1306 allocation failed"));
    for(;;); // Don't proceed, loop forever
  }

  // Show initial display buffer contents on the screen --
  // the library initializes this with an Adafruit splash screen.
  display.display();
  delay(500); // Pause for 2 seconds

  // Clear the buffer
  //display.clearDisplay();
 Wire.begin(0x62);
// uint16_t error;
//    char errorMessage[256];
  scd4x.begin(Wire);
  scd4x.startPeriodicMeasurement();
//display.dim(true);
}

  

  void loop() {

delay(5000);
    uint16_t co2;
    float temperature;
    float humidity;
    scd4x.readMeasurement(co2, temperature, humidity);
    display.clearDisplay();

    display.setTextSize(3);             // Normal 1:1 pixel scale
    display.setTextColor(SSD1306_WHITE);        // Draw white text
    display.setCursor(0, 0);            // Start at top-left corner
//    display.print(F("Co2: "));
    display.println(co2);
//    display.print(F("Temperature: "));
    display.println(temperature);
//    display.print(F("Humidity: "));
    display.println(humidity);

    display.display();

     
    }

Levegő minőség mérő összeállítása:

Eszközök amit használtam:

-Arduino Uno

-SEN55 érzékelő. Ez sem olcsó, 8.000 volt, az aliexpressen nem is találtam meg. Elvileg vannak alternatív mérők is, én ezt vettem meg végül.

-kábel - ennek spécibb, 6 tűs a csatlakozója, de ugyan úgy I2C interfészen is tud kommunikálni
tehát az egyik oldal a 6-os csatlakozó a másik vége 6 db fiú vagy anya vég.

-Adafruit Monochrome 0.96" 128x64 OLED Graphic Display - STEMMA QT

erről a kijelzőről lehet leolvasni az értékeket, aki számítógépről használja, annak nem kell kijelző.

Ez 10.000 forint volt, de aliexpressről 600 forintért rendeltem egy másikat.


-kábel: JST1.0 SH1.0 4-pin cable with socket male DuPont wire For STEMMA QT/QWIIC

stemma qt 4-es csatlakozós a másik oldala sima tűs

Én az I2C protokolt használtam. Itt két kábel kell az adatforgalomnak, a másik négy a következő:


egyik plusz a másik minusz, az 5-ös is mehet a földre mert ezzel választjuk ki, hogy az I2C protokollt használja. 6-ost nem kell bedugni sehová. 3-as 4-es a két adatkábel.

Az I2C eszközöknek van egyedi azonosítójuk a SEN55-nek 0x69.





A használt kód:

#include <Arduino.h>
//#include <SensirionI2CSen5x.h>
#include <Wire.h>
//#include <SPI.h>
//#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
#define OLED_RESET     -1 // Reset pin # (or -1 if sharing Arduino reset pin)
// SEN55
const int16_t SEN55_ADDRESS = 0x69;
int a = 1;

Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

void setup() {
 //Serial.begin(9600);
Wire.begin();
if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3D)) {
    Serial.println(F("Nem találom a kijelzőt."));
    for(;;); // Don't proceed, loop forever
  }
display.display();
  delay(500); // Pause for 2 seconds
    
// Send command to start measurement (0x0021)
  Wire.beginTransmission(SEN55_ADDRESS);
  Wire.write(0x00);
  Wire.write(0x21);
  Wire.endTransmission();
  //Serial.println("PM1.0\tPM2.5\tPM4.0\tPM10.0\tVOC_Index\tNOx_Index\tRH\tT");
  
  // Wait until sensor is ready, fan is initialized
  delay(1000);
 
}
void loop() {
   // Initializing variables
  uint16_t pm1p0, pm2p5, pm4p0, pm10p0;
  int16_t voc, nox, humidity, temperature;
  uint8_t data[24], counter;
  
  // Send command to read measurement data (0x03C4)
  Wire.beginTransmission(SEN55_ADDRESS);
  Wire.write(0x03);
  Wire.write(0xC4);
  Wire.endTransmission();
  // Wait 20 ms to allow the sensor to fill the internal buffer
  delay(20);
  // Read measurement data of SEN55, after two bytes a CRC follows
  Wire.requestFrom(SEN55_ADDRESS, 24);
  counter = 0;
  
  while (Wire.available()) {
    data[counter++] = Wire.read();
  }
  // PM1.0 to PM10 are unscaled unsigned integer values in ug / um3
  // VOC level is a signed int and scaled by a factor of 10 and needs to be divided by 10
  // humidity is a signed int and scaled by 100 and need to be divided by 100
  // temperature is a signed int and scaled by 200 and need to be divided by 200
  pm1p0 = (uint16_t)data[0] << 8 | data[1];
  pm2p5 = (uint16_t)data[3] << 8 | data[4];
  pm4p0 = (uint16_t)data[6] << 8 | data[7];
  pm10p0 = (uint16_t)data[9] << 8 | data[10];
  humidity = (uint16_t)data[12] << 8 | data[13];
  temperature = (uint16_t)data[15] << 8 | data[16];
  voc = (uint16_t)data[18] << 8 | data[19];
  nox = (uint16_t)data[21] << 8 | data[22];
  
  // Print output
  display.clearDisplay();
  display.setTextSize(1);      // Normal 1:1 pixel scale
  display.setTextColor(SSD1306_WHITE); // Draw white text
  display.setCursor(0, 0);  
 
  //display.print(F("PM 1.0: "));
  //display.println(String(float(pm1p0) / 10));
  
  display.print(F("PM 2.5: "));
  display.println(String(float(pm2p5) / 10));
  //display.print(F("PM 4.0: "));
  //display.println(String(float(pm4p0) / 10));
  display.print(F("PM 10 : "));
  display.println(String(float(pm10p0) / 10));
  
  
  display.print(F("Humidi: "));
  display.println(String(float(humidity) / 100));
  
  
  display.print(F("Temper: "));
  display.println(String(float(temperature) / 200));
  
  display.print(F("VOC   : "));
  display.println(String(float(voc) / 10));
  display.print(F("NOx   : "));
  display.println(String(float(nox) / 10));
 
    if (a == 1){
  display.print(F("----"));  
  a= a-1;
  } else if (a == 0) {
   display.print(F("++++"));
   a = a+1;
  }
  
  
  display.display();
  // Wait 2 s for next measurement
  delay(2000);
}