I got this screen and I takes 37 milliseconds to write to with the Adafruit library using I2C Bus. I would like my code to loop at least 10 times every milliseconds because I'm trying to catch quick pulses. I'm wondering if anyone knows of nonblocking libraries for the screen because otherwise I'm going to have to figure out how to do it myself and I've never done anything with communication before.
Hopefully this question wasn't too silly.
How frequently are you writing to the screen ?
How often does the data being displayed on the screen change ?
Every 500ms or whenever a pulse is sent by user input which could be anywhere between 300ms and 100ms but isn't consistent
The Wire library is blocking so every i2c transmission blocks until complete. Your best bet would be to see if you can speed up the clock (400kHz vs. 100kHz) and minimize what you are changing on the screen and only update the bare minimum. You could also only do a single transmission each time through loop() [set screen position, set color, set text, etc.] but that might become a lot of work.
It may be easier to catch your pulses using interrupts and then just deal with them when they happen.
I have to read time between pulses or I would definitely use interrupts.
Wire is set to 400khz by default when used with the Adafruit library
The problem with the Adafruit library is that it sends the entire buffer to the display every time you try to write to it. So you its faster to send everything in one bunch. Unfortunately I cant find a faster library.
The problem with updating a UI slowly is that it's very sloppy and it makes it much more difficult to use . I might just have to figure out out how to code it all on my own, but I would really prefer not doing that.
Easily done. The one trick it to make a copy of your volatile variable so it can't get updated/corrupted in you loop()
volatile unsigned long pulseWidth;
void setup() {
...
}
void loop() {
unsigned long pulseWidthCopy;
cli(); // no interrupts
pulseWidthCopy = pulseWidth;
sei();
... // use pulseWidthCopy
}
void ISR() {
static unsigned long lastTime;
unsigned long currentTime = millis();
pulseWidth = currentTime - lastTime;
lastTime = currentTime;
}
That seems like a lot of code to put in an isr?
3 memory copies and 1 substation is a lot? Nope.
Calling millis() seems kinda heavy, no?
no. It is just a copy of the timer0_millis variable.
I am a bit confused with your concerns about how much time you are spending in the ISR. Why? If this routine gets called once every 300-500 msec.
I've just always been told do as little in interrupts as possible. Also for precision reasons I need to use micros()
A new requirement! Yay!
void ISR() {
static unsigned long lastTime;
\\ unsigned long currentTime = millis();
unsigned long currentTime = micros();
pulseWidth = currentTime - lastTime;
lastTime = currentTime;
}
Just as a general observation, I assume you mean OLED when you say "SSD1306" ?
If so - as a general point, those SSD1306 OLEDs (like the 0.96" displays etc) are terrific displays but they are not very fast anyway. You might like to tinker with the code, but the display itself might be a limiting factor in terms of performance.
I was hoping there was some way to have the screen updated in the background while the rest of my code continues to loop, but since I couldn't seem to find a way to do that. I have put all my code in timer interrupts instead. So all I have in the main loop is the screen updating function.
This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.