Loop won't cycle as desired

I've dabbled but I'm not a "programmer" so be gentle.
This is debug code to see if I can get the loop working (which it apparently isn't). In the normal code, the compare values in the while statements will change but for this exercise I kept them constant to make this easier.
The loop executes fine the first time (ON time of 1500 and OFF for 500) but then nothing happens for a while then it will run again. The time between loops is not consistent. I've seen the delay as much as 2 minutes and as short as 12 seconds.
The commented code is various things I've tried.
Can anyone help?

#include <UTFT.h>
#include <URTouch.h>
#include <URTouchCD.h>
#include <EEPROM.h>

#define TOUCH_ORIENTATION PORTRAIT

// Initialize display
UTFT myGLCD(CTE32_R2, 38, 39, 40, 41);

// Initialize touchscreen
URTouch  myTouch( 6, 5, 4, 3, 2);
extern uint8_t Retro8x16[];
int M_ON, M_OFF, S_ON, S_OFF, VS_ON, VS_OFF;
int activ_Pdr;
int ep_start_M = 4000;
int ep_start_P = 0;
int ea, ev, Spd, ON, OFF;  
unsigned long Start_Time, ex, ex1;
unsigned long Cur_Time, F_ON, F_OFF;
unsigned long period, period_H, period_L;


void setup() {
  myGLCD.InitLCD(0);    // Portrait
  myGLCD.clrScr();
  pinMode(13, OUTPUT);    // onboard LED
  myTouch.InitTouch(TOUCH_ORIENTATION);
  myTouch.setPrecision(PREC_MEDIUM);
  myGLCD.setFont(Retro8x16);
  activ_Pdr = 1;
//  activ_Pdr = EEPROM.read(ep_start_P + 45);
ea = (ep_start_M - 100) + ((activ_Pdr - 1) * 24);
F_ON = EEPROM.read(ea) + (EEPROM.read(ea+1) * 256);
F_OFF = EEPROM.read(ea+2) + (EEPROM.read(ea+3) * 256);
myGLCD.setBackColor(0, 0, 0);
myGLCD.setColor(255, 255, 255);
//myGLCD.printNumI(F_ON, 25, 75, 4);
//myGLCD.printNumI(F_OFF, 25, 105, 4);
//ex= millis();
//delay (1500);
//ex1= millis();
//period=ex1-ex;
//myGLCD.printNumI(ex, 40, 140, 6);
//myGLCD.printNumI(ex1, 40, 180, 6);
//myGLCD.printNumI(period, 40, 220, 6);
}
void loop() {
  //period = 0;
 // Start_Time = millis();
  while (myTouch.dataAvailable() == 0)    // want to be able to stop by touching the screen
  {
  Start_Time = millis();
  period_H = 0;
  digitalWrite(13, HIGH);
  while (period_H < F_ON){
  Cur_Time = millis();
  period_H = Cur_Time - Start_Time;
  myGLCD.printNumI(period_H, 40, 260, 6);
}
  Start_Time = millis();
  period_L = 0;
  digitalWrite(13, LOW);
  while (period_L < F_OFF){
  Cur_Time = millis();
  period_L = Cur_Time - Start_Time;
  myGLCD.printNumI(period_L, 100, 260, 6);
}
}
//return;
}

Welcome to the forum

    F_ON = EEPROM.read(ea) + (EEPROM.read(ea + 1) * 256);
    F_OFF = EEPROM.read(ea + 2) + (EEPROM.read(ea + 3) * 256);

It would be a lot easier to use EEPROM.get()

How are the values being written to the EEPROM ?

I use EEPROM.update to load values. In the normal program the user can edit 80 values which would be used in a loop (similar to this).

edit: Some of the numbers stored can be larger than 8 bit which is why I have the ea and ea+ for addresses.

Why not use EEPROM.put() to store the values ? Internally the function only updates any bytes that have changed

As to your problem, an unsigned long such as F_ON is stored in 4 bytes but when you read it from EEPROM you are only reading 2 bytes. Do you know which order the 4 bytes are stored in ?

I don't know why I'm not using the .put. Not familiar with it I guess.

The fields that the user can edit will only accept a maximum of 4 digits (integer, not float). If the value (ev) is larger than 255 I do a EEPROM.update((ea + 1), (highByte(ev)));. If not larger I do a EEPROM.update(ea, lowByte(ev));
I don't know what happens to the higher 2 bytes. Since the examples for millis() showed using a long to store the value, I thought I'd try using longs for any variable that had anything to do with millis(). F_ON and F_OFF were previously just int but the loop didn't work then either.

I don't know what you are going for, but here's your loop() function after application of the IDE Auto Format tool, and commented-out lines removed:

void loop() {
  while (myTouch.dataAvailable() == 0)    // want to be able to stop by touching the screen
  {
    Start_Time = millis();
    period_H = 0;
    digitalWrite(13, HIGH);
    while (period_H < F_ON) {
      Cur_Time = millis();
      period_H = Cur_Time - Start_Time;
      myGLCD.printNumI(period_H, 40, 260, 6);
    }
    Start_Time = millis();
    period_L = 0;
    digitalWrite(13, LOW);
    while (period_L < F_OFF) {
      Cur_Time = millis();
      period_L = Cur_Time - Start_Time;
      myGLCD.printNumI(period_L, 100, 260, 6);
    }
  }
}

We now see at a glance that the loop consists of one while statement. I think you have some missing or extra or misplaced { braces }.

Or it is what you mean. Try a sketch without the outer while "want to be able to stop" test, get it working and worry about that deatil next.

You could use the serial monitor to print the values of some variables that inform the process you are coding, to see if they are plausible and to see if the code is flowing as you intended.

Here's your sketch, it blinks in its roundabout way. I made the while always true, jettisoned the hardware I don't have, and jammed in some values for the ones you are (not yet successfully?) grabbing out of EEPROM.


int M_ON, M_OFF, S_ON, S_OFF, VS_ON, VS_OFF;
int activ_Pdr;
int ep_start_M = 4000;
int ep_start_P = 0;
int ea, ev, Spd, ON, OFF;
unsigned long Start_Time, ex, ex1;
unsigned long Cur_Time, F_ON, F_OFF;
unsigned long period, period_H, period_L;


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

  F_ON = 700;
  F_OFF = 1300;
}

void loop() {
  //period = 0;
  // Start_Time = millis();
  while (1)    // want to be able to stop by touching the screen
  {
    Start_Time = millis();
    period_H = 0;
    digitalWrite(13, HIGH);
    while (period_H < F_ON) {
      Cur_Time = millis();
      period_H = Cur_Time - Start_Time;
      //  myGLCD.printNumI(period_H, 40, 260, 6);
    }
    Start_Time = millis();
    period_L = 0;
    digitalWrite(13, LOW);
    while (period_L < F_OFF) {
      Cur_Time = millis();
      period_L = Cur_Time - Start_Time;
      //  myGLCD.printNumI(period_L, 100, 260, 6);
    }
  }
  //return;
}

HTH

a7

Thank you 777. I tried the original code in post 1 using while (1) instead of while (myTouch.dataAvailable() == 0) and it works. I was under the impression if there was no pressure on the touchscreen that there wouldn't be any data available. Guess that's not the case.
I also tried it without the outer while loop and that also works.

Do you even know which bytes are the higher ones ? Just use EEPROM.put() to save the unsigned long values and you will have one less thing to worry about

1 Like

Pardon my ignorance but if a number is 16 bits does .put write to 2 bytes automatically? If not, I don't see the difference between .update and .put at least for my purpose here.

If a variable is 16 bits then EEPROM.put() writes 2 bytes as you say

However, an unsigned long is 4 bytes and you are only writing 2, whereas EEPROM.put() writes all 4 of them

As it is you may be writing the 2 bytes in the wrong place in the 4 byte variable

The library examples use dataAvailable() like that, so I can understand why you'd think so.

I do not know why it isn't doing what it looks like you want.

Have you a simple sketch for testing the touch screen? It may be that for some reason yours is always reporting activity or something.

a7

If a variable is 16 bits does the .put write the 2 bytes in sequential address locations? If not, how would you know where to write other data so existing data doesn't get clobbered?

Of course it does. It automatically writes the number of consecutive bytes required for the size of the data type you're put(ing). You should take a look at the source code in EEPROM.h.

The only thing you need to remember is to skip that many bytes when you specify the address to store the next object. For example, if you put a 4-byte variable in Address 0, then you should put the next variable in Address 4.

I'd like to make sure I understand the mechanics of .put & .get.
if -

int8_t  x;    // 1 byte
int y;        // 2 bytes

EEPROM.put(1, x);
EEPROM.get(1, y);
//  Will this read from address 1 and 2 and treat it as a 16 bit number?

EEPROM.put(1, y);
EEPROM.get(1, x);

//  Will this read from just address 1 (low byte)?

Hello ard_nov

Take a view here to gain the knowledge:

https://docs.arduino.cc/learn/programming/eeprom-guide/

Not sure if I should start another thread or stay with this one. I'v e read a fair amount on serial communication but haven't seen an answer to my question, which is -
If serial data is coming into the serial buffer faster than it is being read, is the new data (terminated with CR) pushing the old out or is the new data just being ignored until the CR is removed?? I'm sending measurements from a scale. The data format is a sign, 5 digits, a decimal point, 2 more digits and a terminator which can be CRLF or just CR. I chose CR. So that's 9 bytes plus terminator going to a 64 byte buffer.

Serial buffer overrun data is discarded. "pushing the old out" would be much more expensive an operation, and since the data stream would be corrupted either way, it does the cheaper operation of not writing to a full buffer.

The code in ArduinoCore-avr:

1 Like

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.