/*---------------------------------------------------------------------- Project: InsoL@b Author : user@B0 Tetalab.org File : displays.h 2026-04-21 This work is copyrighted under CERN Open Hardware Licence Version 2 ------------------------------------------------------------------------ Management of the I2C oled SH1306 for RP2040 Zero clone ----------------------------------------------------------------------* ------------------ Functions for Oled display ---------------------*/ #ifndef _INSOLAB_DISPLAYS_H_ #define _INSOLAB_DISPLAYS_H_ #include "bitmaps.h" #include "ledRGB.h" #include #include #include // Declaration for SSD1306 display on I2C (SDA, SCL pins) // The pins for I2C are defined by the Wire-library. // Default on RP2040 Zero: SDA GPIO 4 SCL GPIO 5 #include #define OLED_WIDTH 128 // OLED display width, in pixels #define OLED_RST -1 // Reset pin #ifdef ESSAIS #define OLED_HEIGHT 64 // OLED display height, in pixels #define OLED_ADR 0x3C //0x3D //Address 0x3D/0x3C to 128x64, 0x3C to 128x32 #else #define OLED_HEIGHT 32 // OLED display height, in pixels #define OLED_ADR 0x3C // 0x3C #endif Adafruit_SSD1306 oled(OLED_WIDTH, OLED_HEIGHT, &Wire, OLED_RST); char _oledmsg[32]; // general purpose character buffer void showInfo(char* l1, char* l2, char* l3) { oled.clearDisplay(); oled.setTextSize(1); oled.setTextColor(SSD1306_WHITE); oled.setCursor(0,0); sprintf(_oledmsg,"%s",l1); oled.println(_oledmsg); sprintf(_oledmsg,"%s",l2); oled.println(_oledmsg); sprintf(_oledmsg,"%s",l3); oled.println(_oledmsg); oled.display(); } void showTxt1(uint8_t x, uint8_t y, char* txt) { oled.setTextSize(1); oled.setTextColor(SSD1306_WHITE); oled.setCursor(x,y); // O,0 at top-left corner sprintf(_oledmsg,"CR:%s",txt); oled.println(txt); oled.display(); } void showText(String l1, String l2) { oled.clearDisplay(); oled.setTextColor(SSD1306_WHITE); oled.setTextSize(2); oled.setCursor(0,0); oled.println(l1); oled.setTextSize(1); oled.setCursor(0,18); oled.println(l2); oled.display(); } void showInit() { ledInit(); ledRGB(BLANK);// ledRGB(BLANK); //ledRGB(RED);// if(!oled.begin(SSD1306_SWITCHCAPVCC, OLED_ADR)) { Serial.begin(115200); delay(100); Serial.println(F("SSD1306 allocation failed")); ledRGB(RED); for(;;); // Don't proceed, loop forever } // setRotation(0)->point(0,0) is close to pin SDA oled.clearDisplay(); oled.setRotation(2); // 2->point(0,0) is opposite of pins, 1&3 are vertical //sprintf(_oledmsg, "SSD1306 @ %2d OK", OLED_ADR); oledTxt1(0,0,_oledmsg); delay(100); // Serial.println(_oledmsg); } void showLOGO(int16_t gt) { /*--------- logo on SSD1306 -------------*/ oled.clearDisplay(); oled.invertDisplay(true); oled.drawBitmap( LOGO_X0, LOGO_Y0,logo_bmp, LOGO_WIDTH, LOGO_HEIGHT, LOGO_COLOR); oled.display(); playRTTTL(sLOGO); delay(gt); oled.invertDisplay(false); } void showTITRE() { // TextSize(2)=>10char, TextSize(1)=>22char, oled.clearDisplay(); oled.setCursor(0,0); oled.setTextSize(2); // doble scale oled.setTextColor(SSD1306_WHITE); oled.println(F("InsoLab UV")); // 10 chars max oled.setTextSize(1); oled.setCursor(0,18); // Normal 1:1 pixel scale oled.println(F(" Any button to start")); // 21 chars max oled.display(); } void showCHOIX(uint16_t t) { oled.clearDisplay(); oled.setTextColor(SSD1306_WHITE); oled.setCursor(0,0); oled.setTextSize(2); sprintf(_oledmsg,"Expo: %3ds",t); // 10 chars max oled.println(_oledmsg); oled.setCursor(0,18); oled.setTextSize(1); // 21 chars max oled.println(F("- goto UV, + settings")); oled.display(); } void showEXPOS(uint16_t t, int16_t m) { oled.clearDisplay(); oled.setTextColor(SSD1306_WHITE); oled.setCursor(0,0); oled.setTextSize(2); sprintf(_oledmsg,"Count:%3ds",t); oled.println(_oledmsg); oled.setCursor(0,18); oled.setTextSize(1); sprintf(_oledmsg,"- stop, + add up %3ds",m); oled.println(_oledmsg); oled.display(); delay(200); } void showREGLE() { oled.clearDisplay(); oled.setTextColor(SSD1306_WHITE); oled.setCursor(0,0); oled.setTextSize(2); oled.println(F("Set times")); oled.setCursor(0,18); oled.setTextSize(1); sprintf(_oledmsg," - step, + expo UV"); oled.println(_oledmsg); oled.display(); } void showDUREE(uint16_t t) { oled.clearDisplay(); oled.setTextColor(SSD1306_WHITE); oled.setCursor(0,0); oled.setTextSize(2); sprintf(_oledmsg,"Time: %3ds",t); oled.println(_oledmsg); oled.setCursor(0,18); oled.setTextSize(1); sprintf(_oledmsg,"- less, + more"); oled.println(_oledmsg); oled.display(); } void showINCRE(uint16_t t) { oled.clearDisplay(); oled.setTextColor(SSD1306_WHITE); oled.setCursor(0,0); oled.setTextSize(2); sprintf(_oledmsg,"Step: %3d",t); oled.println(_oledmsg); oled.setCursor(0,18); oled.setTextSize(1); sprintf(_oledmsg,"- less, + more"); oled.println(_oledmsg); oled.display(); } void showSAUVE(uint16_t t, char* txt) { oled.clearDisplay(); oled.setTextColor(SSD1306_WHITE); oled.setCursor(0,0); oled.setTextSize(2); sprintf(_oledmsg,"%s %3ds",txt,t); oled.println(_oledmsg); oled.setCursor(0,18); oled.setTextSize(1); sprintf(_oledmsg,"- quit, + save"); oled.println(_oledmsg); oled.display(); } typedef struct s_iconMvt { int xp,yp,dy; } t_iconMvt; typedef struct s_sprite { int count, h, w, x, y, dy; const unsigned char *bmp; t_iconMvt *iconsMvt; } t_sprite ; void initSprite(t_sprite *s, int c, int h, int w, int x, int y, int dy, const unsigned char *bmp,t_iconMvt *iconsMvt) { //t_iconMvt iconsMvt[c]; //WIP malloc ?? || Arg s->count=c; s->h=h; s->w=w; s->x=x; s->y=y; s->dy=dy; for(int i=0; i< s->count; i++) { iconsMvt[i].xp = random(1 - s->w, OLED_WIDTH); iconsMvt[i].yp = -s->h; iconsMvt[i].dy = random(1, 6); } s->bmp=bmp; s->iconsMvt= iconsMvt; } void drawSprite(t_sprite *s, Adafruit_SSD1306 d) { //int8_t iconsMvt[FLOCONS][3]; d.clearDisplay(); for(int i=0; i < s->count; i++) { d.drawBitmap( s->iconsMvt[i].xp, s->iconsMvt[i].yp, s->bmp, s->w, s->h, SSD1306_WHITE); } //d.display(); // Show the display buffer on the screen } void updateSprite(t_sprite *s) { for(int i=0; i < s->count; i++) { s->iconsMvt[i].yp += s->iconsMvt[i].dy; // If sprite is off the bottom of the screen... if (s->iconsMvt[i].yp >= OLED_HEIGHT) { // Reinitialize to a random position, just off the top s->iconsMvt[i].xp = random(1 - s->w, OLED_WIDTH); s->iconsMvt[i].yp = -s->h; // HEIGHT s->iconsMvt[i].dy = random(1, 6); } } // f=0; f< sprites.count; f++) } #endif // _INSOLAB_DISPLAYS_H_