AnalogRead isn't instant, neither is writing on the tft. Oh and what have we here?
delay(50);
I suggest that if ledReady is true, you only do the stuff pertaining to the led. If it isn't, read the pots and update the display.
AnalogRead isn't instant, neither is writing on the tft. Oh and what have we here?
delay(50);
I suggest that if ledReady is true, you only do the stuff pertaining to the led. If it isn't, read the pots and update the display.
wildbill:
AnalogRead isn't instant, neither is writing on the tft.
That's a good point...
Oh and what have we here?
delay(50);
Ahh...you've got me there!!
It's starting to make sense now...it's hard to let go of old (bad?) habits!!
I suggest that if ledReady is true, you only do the stuff pertaining to the led. If it isn't, read the pots and update the display.
Many thanks for your patient guidance @wildbill...
...so I think I'm getting somewhere, I've just tried this:
else {
updateTFT();
ndx = 0;
intervals[0] = map(analogRead(pot1), 4, 1019, 20, 200); // initial pause
intervals[1] = map(analogRead(pot2), 4, 1019, 0, 200); // 1st drop size
intervals[2] = map(analogRead(pot3), 4, 1019, 20, 200); // pause between 1st and 2nd drops
intervals[3] = map(analogRead(pot4), 4, 1019, 0, 200); // 2nd drop size
intervals[4] = map(analogRead(pot5), 4, 1019, 20, 200); // pause between 2nd and 3rd drops
intervals[5] = map(analogRead(pot6), 4, 1019, 0, 200); // 3rd drop size
ledReady = false;
}
I'm seeing that the led blinks correctly now - ie. if I set a drop size value to zero, then nothing happens, which is terrific....definitely a step in the right direction, however, the screen only updates for a brief time and then disappears.
How do I get it to display the 'live' values all the time?
Is this even possible with TFT screens?
Oh yes....and I commented out the delay(50); too!
I'm sorry to have to say this: put the delay back.
The code you're using writes the data in while and then in black to erase it in preparation for next time. That delay gives you a chance to see it.
There's more complex ways to do it to avoid delay, but that should fix it as long as updateTFT isn't called while you're working with the LED.
wildbill:
I'm sorry to have to say this: put the delay back.The code you're using writes the data in while and then in black to erase it in preparation for next time. That delay gives you a chance to see it.
There's more complex ways to do it to avoid delay, but that should fix it as long as updateTFT isn't called while you're working with the LED.
Thanks @wildbill....the delay is back in.
Although I'm still trying (and failing) to get live values displayed on the screen.
I've tried placing the...
updateTFT();
...in all sorts of places - trying to avoid anywhere which might impact the main timing sequence.
(basically anywhere within the else {} statement)
It only seems to briefly flash for a moment, and then disappear.
I've tried reversing the order of TFTprints to have the data displayed after the over-writes, and that just leads to a jumbled mess...as you would expect!
The blinks do work as expected however.
When I enter a zero value for a drop size, I do indeed see nothing happen - which is encouraging.
Just need to crack this whole TFT thing next!
(I've even tried a while() loop....but that didn't work! Though I'm certain I did it wrong!)
Post your latest attempt.
Here it is, in full:
#include <digitalIOPerformance.h>
#include <Wire.h>
#include <TFT.h>
#include <SPI.h>
#define cs 10
#define dc 9
#define rst 8
//define pins
const byte startButton = 2;
const byte led = 5;
const byte pot1 = A1;
const byte pot2 = A2;
const byte pot3 = A3;
const byte pot4 = A4;
const byte pot5 = A5;
const byte pot6 = A6;
//variable to keep track of the LED
bool ledReady = false;
unsigned long previousMillis = 0;
unsigned long intervals[6];
// start instance of TFTscreen
TFT TFTscreen = TFT(cs, dc, rst);
void setup() {
Serial.begin(9600);
pinMode(startButton, INPUT_PULLUP);
pinMode(led, OUTPUT);
digitalWrite(led, LOW);
// initialize the TFTscreen and print static info
TFTscreen.begin();
TFTscreen.background(0, 0, 0);
TFTscreen.setTextSize(1);
TFTscreen.stroke(255, 255, 255);
TFTscreen.text("Del Dr1 Del Dr2 Del Dr3", 6, 6);
}
void loop() {
if (digitalRead(startButton) == LOW) {
ledReady = true;
previousMillis = millis();
}
if (ledReady) {
static byte ndx = 0;
if (ndx < 6) {
if (millis() - previousMillis >= intervals[ndx] ) {
previousMillis = millis();
digitalWrite(led, ! digitalRead(led)); // toggle the led
ndx ++;
}
}
else {
updateTFT();
ndx = 0;
ledReady = false;
intervals[0] = map(analogRead(pot1), 4, 1019, 20, 200); // initial pause
intervals[1] = map(analogRead(pot2), 4, 1019, 0, 200); // 1st drop size
intervals[2] = map(analogRead(pot3), 4, 1019, 20, 200); // pause between 1st and 2nd drops
intervals[3] = map(analogRead(pot4), 4, 1019, 0, 200); // 2nd drop size
intervals[4] = map(analogRead(pot5), 4, 1019, 20, 200); // pause between 2nd and 3rd drops
intervals[5] = map(analogRead(pot6), 4, 1019, 0, 200); // 3rd drop size
}
}
}
void updateTFT() {
TFTscreen.setTextSize(1);
TFTscreen.stroke(255, 0, 0);
TFTscreen.setCursor(5, 40);
TFTscreen.print(intervals[0]);
TFTscreen.setCursor(30, 40);
TFTscreen.print(intervals[1]);
TFTscreen.setCursor(55, 40);
TFTscreen.print(intervals[2]);
TFTscreen.setCursor(80, 40);
TFTscreen.print(intervals[3]);
TFTscreen.setCursor(105, 40);
TFTscreen.print(intervals[4]);
TFTscreen.setCursor(130, 40);
TFTscreen.print(intervals[5]);
delay(50);
TFTscreen.setTextSize(1);
TFTscreen.stroke(0, 0, 0);
TFTscreen.setCursor(5, 40);
TFTscreen.print(intervals[0]);
TFTscreen.setCursor(30, 40);
TFTscreen.print(intervals[1]);
TFTscreen.setCursor(55, 40);
TFTscreen.print(intervals[2]);
TFTscreen.setCursor(80, 40);
TFTscreen.print(intervals[3]);
TFTscreen.setCursor(105, 40);
TFTscreen.print(intervals[4]);
TFTscreen.setCursor(130, 40);
TFTscreen.print(intervals[5]);
}
How did the display behave with the code in #15?
wildbill:
How did the display behave with the code in #15?
The display updated perfectly - albeit a bit 'flickery', but that's to be expected.
The drop sequence however, was not performing satisfactorily in that a drop size of zero was still exhibiting a sizeable blink.
It makes sense that the delay created in writing to the screen is indeed affecting the drop timing - you are quite right.
Until you press the button, I would expect the latest code to do what the #15 code did. I would prefer to update the display after the pots are read but that just means it's out of date a bit. I can't explain why they differ.
You might need to do something more complicated: keep two interval arrays, one with what you display, one with what you just read from the pots. Check each pair - if they differ, overwrite the display reading in black, copy the new reading into the display array and write it on the try in white.
I would be uncomfortable with that path though until I could understand why the two programs affect the display differently.
wildbill:
Until you press the button, I would expect the latest code to do what the #15 code did. I would prefer to update the display after the pots are read but that just means it's out of date a bit. I can't explain why they differ.
That seems to be what is happening - I've been (foolishly) using the same timing data without making any changes, so have not noticed that it seems to cycle with the previous timing data.
When I make a change, it lags by one loop...if that makes sense...of course it 'catches up' with another unchanged cycle, but when the final project is put together, this will naturally be no good at all...unless I settle for performing each drop sequence twice!
Edit
I have now placed the updateTFT() after the analogRead() statements, but it still performs the same way as before.
You might need to do something more complicated: keep two interval arrays, one with what you display, one with what you just read from the pots. Check each pair - if they differ, overwrite the display reading in black, copy the new reading into the display array and write it on the try in white.
I would be uncomfortable with that path though until I could understand why the two programs affect the display differently.
Wise words @wildbill, I'm hugely grateful for your input...you have afterall pointed me in the right direction, and I'm now seeing a promising 'light at the end of the tunnel'.
With my distinct lack of knowledge, the only course of action for me now, is to learn more!
And this is what I will endeavour to do.
I shall post again when I have made a pertinent discovery....once again, many, many thanks @wildbill!
Well, I've made a minor discovery.
After much staring at the IDE, it suddenly dawned on me that the reason it lags by one cycle is due to where I placed the analogRead() statements.
So I placed them into their own function - readPots() - and called it after the button is pressed.
Now I am getting an accurate sequence of the values that are entered, and not the values that were entered in the last sequence before that.
And it's not interfering with the timing data, so I'm getting nice clean blinks.
Progress right?
I've also placed an...
else{}
...statement - nested (is that the right term?) with the...
if (ledReady) {}
...bit, like so:
if (ledReady) {
// timing sequence
}
else {
updateTFT();
}
...and this seems to have yielded a constant display of the data, however it only updates after the button is pressed - when ledReady is false....so it's not much use yet.
For those of you who are interested, the sketch is as follows:
#include <digitalIOPerformance.h>
#include <Wire.h>
#include <TFT.h>
#include <SPI.h>
// TFTscreen specific pins
#define cs 10
#define dc 9
#define rst 8
//define pins
const byte startButton = 2;
const byte led = 5;
const byte pot1 = A1;
const byte pot2 = A2;
const byte pot3 = A3;
const byte pot4 = A4;
const byte pot5 = A5;
const byte pot6 = A6;
//variable to keep track of the LED
bool ledReady = false;
// standard millis() variable
unsigned long previousMillis = 0;
// my array which contains my 6 values for drop sizes and pauses etc
unsigned long intervals[6];
//unsigned long intervalsLast[6]; // preparing to set up a 'compare' function eventually...maybe!
// create an instance of TFTscreen
TFT TFTscreen = TFT(cs, dc, rst);
void setup() {
Serial.begin(9600);
pinMode(startButton, INPUT_PULLUP);
pinMode(led, OUTPUT);
digitalWrite(led, LOW);
// initialize the TFTscreen, and print static info
TFTscreen.begin();
TFTscreen.background(0, 0, 0);
TFTscreen.setTextSize(1);
TFTscreen.stroke(255, 255, 255);
TFTscreen.text("Del Dr1 Del Dr2 Del Dr3", 6, 6);
}
void loop() {
if (digitalRead(startButton) == LOW) {
ledReady = true;
readPots(); // calling the function to read the pots here means I am now 'in sync' with the timing data
previousMillis = millis();
}
if (ledReady) {
static int ndx = 0;
if (ndx < 6) {
if (millis() - previousMillis >= intervals[ndx] ) {
previousMillis = millis();
digitalWrite(led, ! digitalRead(led)); // toggle the led
ndx ++;
}
}
else {
ndx = 0;
ledReady = false;
}
}
else {
updateTFT(); // this will update the screen, but only after the startButton is pressed (nested with if (ledReady))
}
}
void updateTFT() {
TFTscreen.setTextSize(1);
TFTscreen.stroke(255, 0, 0);
TFTscreen.setCursor(5, 40);
TFTscreen.print(intervals[0]);
TFTscreen.setCursor(30, 40);
TFTscreen.print(intervals[1]);
TFTscreen.setCursor(55, 40);
TFTscreen.print(intervals[2]);
TFTscreen.setCursor(80, 40);
TFTscreen.print(intervals[3]);
TFTscreen.setCursor(105, 40);
TFTscreen.print(intervals[4]);
TFTscreen.setCursor(130, 40);
TFTscreen.print(intervals[5]);
delay(50);
TFTscreen.setTextSize(1);
TFTscreen.stroke(0, 0, 0);
TFTscreen.setCursor(5, 40);
TFTscreen.print(intervals[0]);
TFTscreen.setCursor(30, 40);
TFTscreen.print(intervals[1]);
TFTscreen.setCursor(55, 40);
TFTscreen.print(intervals[2]);
TFTscreen.setCursor(80, 40);
TFTscreen.print(intervals[3]);
TFTscreen.setCursor(105, 40);
TFTscreen.print(intervals[4]);
TFTscreen.setCursor(130, 40);
TFTscreen.print(intervals[5]);
}
void readPots() { // placed the analogRead() statements in their own function, for clarity
intervals[0] = map(analogRead(pot1), 4, 1019, 20, 200); // initial pause
intervals[1] = map(analogRead(pot2), 4, 1019, 0, 200); // 1st drop size
intervals[2] = map(analogRead(pot3), 4, 1019, 20, 200); // pause between 1st and 2nd drops
intervals[3] = map(analogRead(pot4), 4, 1019, 0, 200); // 2nd drop size
intervals[4] = map(analogRead(pot5), 4, 1019, 20, 200); // pause between 2nd and 3rd drops
intervals[5] = map(analogRead(pot6), 4, 1019, 0, 200); // 3rd drop size
}
I shall keep playing around, and see what happens!