De uitdaging is een led-simulatie:
Mijn configuratie is als volgt:
Arduino Nano met 128*64 OLED, controller SSD1306, SPI interface.
extern [rood] ledje aan pin 3
Ik heb twee monochrome bitmapjes gemaakt (16x21 pixels): led_OFF en led_ON, en die staan als char array in progmem.
Bijgaande sketch doet het volgende:
bitmapje 'led_OFF' naar OLED
print tekst 'OFF' naar OLED
pin 3 LOW
wacht 1 seconde
bitmapje 'led_ON' naar OLED
print tekst 'ON ' naar OLED
pin 3 HIGH
So far so good! Het enige is dat ik gebruik maak van de delay () functie. Dat wil ik graag omzetten naar 'blink without delay' code;
// OLED_SSD_1306_nano_nano_led_simulation_nn
// four pin white OLED I2c
//
// physical led pin 3
// Sept 11, 2020
// Floris Wouterlood
// public domain
//
#include <avr/pgmspace.h>
#include <U8glib.h>
#define OLED_SCK 13 // pins on the Arduino
#define OLED_MOSI 11
#define OLED_CS 10
#define OLED_DC 9
#define OLED_RES 8
int j = 0;
U8GLIB_SSD1306_128X64 u8g(OLED_SCK, OLED_MOSI, OLED_CS, OLED_DC, OLED_RES); // U8glib constructor OLED display
const int ledPin = 3;
int flag=0;
long longInterval = 1000; // interval at which to blink (milliseconds)
static const unsigned char led_icon_ON [] PROGMEM = { // NOTE - these icons are 16 x 21 pixel monochrome
0x03, 0xc0, // ∙∙∙∙∙∙████∙∙∙∙∙∙
0x07, 0xe0, // ∙∙∙∙∙██████∙∙∙∙∙
0x0f, 0xf0, // ∙∙∙∙∙██████∙∙∙∙∙
0x1f, 0xf8, // ∙∙∙∙████████∙∙∙∙
0x1f, 0xf8, // ∙∙∙██████████∙∙∙
0x1f, 0xf8, // ∙∙∙██████████∙∙∙
0x1f, 0xf8, // ∙∙∙██████████∙∙∙
0x1f, 0xf8, // ∙∙∙██████████∙∙∙
0x1f, 0xf8, // ∙∙∙██████████∙∙∙
0x1f, 0xf8, // ∙∙∙██████████∙∙∙
0x3f, 0xfc, // ∙∙████████████∙∙
0x40, 0x02, // ∙█∙∙∙∙∙∙∙∙∙∙∙∙█∙
0x40, 0x02, // ∙█∙∙∙∙∙∙∙∙∙∙∙∙█∙
0x3f, 0xfc, // ∙∙████████████∙∙
0x04, 0x10, // ∙∙∙∙∙█∙∙∙∙∙█∙∙∙∙
0x04, 0x10, // ∙∙∙∙∙█∙∙∙∙∙█∙∙∙∙
0x04, 0x10, // ∙∙∙∙∙█∙∙∙∙∙█∙∙∙∙
0x04, 0x10, // ∙∙∙∙∙█∙∙∙∙∙█∙∙∙∙
0x04, 0x10, // ∙∙∙∙∙█∙∙∙∙∙█∙∙∙∙
0x04, 0x10, // ∙∙∙∙∙█∙∙∙∙∙█∙∙∙∙
0x04, 0x10 // ∙∙∙∙∙█∙∙∙∙∙█∙∙∙∙
};
static const unsigned char led_icon_OFF [] PROGMEM = {
0x03, 0xc0, // ∙∙∙∙∙∙████∙∙∙∙∙∙
0x06, 0x60, // ∙∙∙∙∙██∙∙██∙∙∙∙∙
0x0c, 0x30, // ∙∙∙∙██∙∙∙∙██∙∙∙∙
0x18, 0x18, // ∙∙∙∙██∙∙∙∙██∙∙∙∙
0x10, 0x08, // ∙∙∙██∙∙∙∙∙∙██∙∙∙
0x10, 0x08, // ∙∙∙█∙∙∙∙∙∙∙∙█∙∙∙
0x10, 0x08, // ∙∙∙█∙∙∙∙∙∙∙∙█∙∙∙
0x10, 0x08, // ∙∙∙█∙∙∙∙∙∙∙∙█∙∙∙
0x10, 0x08, // ∙∙∙█∙∙∙∙∙∙∙∙█∙∙∙
0x10, 0x08, // ∙∙∙█∙∙∙∙∙∙∙∙█∙∙∙
0x3f, 0xfc, // ∙∙████████████∙∙
0x40, 0x02, // ∙█∙∙∙∙∙∙∙∙∙∙∙∙█∙
0x40, 0x02, // ∙█∙∙∙∙∙∙∙∙∙∙∙∙█∙
0x3f, 0xfc, // ∙∙████████████∙∙
0x04, 0x10, // ∙∙∙∙∙█∙∙∙∙∙█∙∙∙∙
0x04, 0x10, // ∙∙∙∙∙█∙∙∙∙∙█∙∙∙∙
0x04, 0x10, // ∙∙∙∙∙█∙∙∙∙∙█∙∙∙∙
0x04, 0x10, // ∙∙∙∙∙█∙∙∙∙∙█∙∙∙∙
0x04, 0x10, // ∙∙∙∙∙█∙∙∙∙∙█∙∙∙∙
0x04, 0x10, // ∙∙∙∙∙█∙∙∙∙∙█∙∙∙∙
0x04, 0x10 // ∙∙∙∙∙█∙∙∙∙∙█∙∙∙∙
};
void setup() {
pinMode (ledPin,OUTPUT);
Serial.begin (9600);
Serial.println ();
Serial.println ("SSD 1306 OLED 128*64 led simulation - uses delay()");
Serial.println ();
Serial.print ("let's start");
Serial.println ();
u8g.setColorIndex(1); // display draws with pixel on
u8g.setFont (u8g_font_unifont); // select font
}
void loop() {
{
u8g.firstPage();
do {
draw();
} while (u8g.nextPage());
flag++;
if (flag>1) flag =0;
Serial.println (flag);
if (flag ==0)
Serial.println ("led OFF");
else if (flag=1)
Serial.println ("led ON");
delay (longInterval);
Serial.println ("delay intervalactive ");
if (flag ==0)
digitalWrite (ledPin,LOW);
else if (flag=1)
digitalWrite (ledPin,HIGH);
}
}
void draw(void){
u8g.drawCircle(40,35, 18);
if (flag ==0)
u8g.drawBitmapP (33, 25, 2, 21, led_icon_OFF);
else if (flag==1)
u8g.drawBitmapP (33, 25, 2, 21, led_icon_ON);
if (flag ==0)
u8g.drawStr ( 73, 52, "OFF");
else if (flag==1)
u8g.drawStr ( 73, 52, "ON ");
}
de vraag is: blink without delay maakt gebruik van subroutines. U8glib gaat daat niet goed mee om, en het ledje blijft voortdurend op ON staan.
Is het mogelijk om bijgaand, op delay () draaiend sketchje op mijn configuratie draaiend te krijgen met behulp van millis(). Ik ben er nog niet uit, en daarom is elke suggestie welkom! u8glib staat namelijk allerlei creatieve dingen toe, maar geen subroutines. Oplossing?