Variables, startup() and loop()

Hi folks.

It has been a while.

Up front I shall say I apologise for the stupid questions I am about to ask. Something is really wrong with me and it seems what I once knew and thought worked, doesn't any more. Which is obvious in saying, but back then, it wasn't and now I am stuck with these problems which are because I misunderstood something at the start.

Background:
I was thrown in to Arduino head first a few years back and really had a hard time learning.
Along the way I did learn things and have written a couple of good sketches which do for me what I wanted/needed.

Sure along the way other people DID help me and wrote sketches. I won't deny that. I tried to use their sketches as foundations for new sketches and for most of the times: They worked.

But then it all fell apart and I am in a mess.

I would include the sketches here/now but really think it would do more harm than good.

One sketch which works and is good for the purpose written is a "strobe" sketch to pulse an output pin at a given frequency.
The frequency is set via the serial input. Not exactly rocket science. But my original attempt was ..... not really working.
The new sketch was good and as I said: It worked.

I used that to help me write a new sketch which was a bit different, in that instead of frequency, it was more Pulse Width Modulation.

Now, yeah, I know there are pins on the Arduino to do PWM. Why not use them?
Well, I wanted to practice programming and try to do it myself.

As it was supposed to be a SIMPLE program, I didn't really bother with making function blocks. There was no need. It simply went "top to bottom" and looped.

But then the Gremlins appeared and everything went pear shaped.

Adding debug code was messy and I thought I would put them in blocks and access them with simple calls. NOT as simple as I thought.

Because most things were defined in the LOOP() part of the code, their names were lost when I called the debug parts. Yeah, ok, I could have parsed them but that was only adding to overhead for me and further complicating things.

I persisted and got the code "working". But there were still bugs. What was my next step to be?

What I thought I would/cold do: Is take the variable names and put them before the SETUP() and LOOP() parts of the code. That way they would be GLOBAL names. Can't be that difficult can it?

Well it seems it can be.
I had a "working" version of the code.
I took ONE line:
unsigned long BLAH = ;
and put that OUTSIDE the LOOP() part of the code.

It compiled ok and I sent it to the Arduino.
The sketch didn't work.

I moved the line back WITHIN the LOOP() code, compiled it and uploaded it.
It worked.

I gave up. Yeah, not the best solution, but I had had it. I honestly couldn't work out what was going on.

Also, reading other people's sketches there are weird things like:
constant int X = 1;

I understood it was:
static int X = 1;

(outside LOOP() or any other blocks of code.)

And so I learned that I was dumber than I thought. I'm getting used to that these days.

Now I am trying to learn about loops.

The strobe sketch was easy enough to read and it was basically:

calculate X;
turn on output;
get micros();
store it;
if stored value + X > micros()
{
turn off output
}

BASICALLY!!!!

So I set up the variables, got the current micros(), sotred it, did the maths, and all that.

It seemed to work. But then the subtleties started to show up.
I was adjusting the step value by 100. I then put in code to allow adjustment of the step value to 10 or 50 or 100.
Things didn't add up.
Not having a CRO didn't help.

Finally I used a CRO and it was confirmed! It wasn't doing what it was supposed to do.

I reluctantly did a basic sketch:

every 2 seconds:
turn light on for 1 second.
repeat.

So it would:
read mircos()
trun on the light
add 1000000 and see if 1 second had passed.
If it had, turn the light off.
repeat.

It doesn't work!

I can't seem to get the code right.

Attached is the pitiful effort.

The other sketches won't be attached as I don't need that much salt to be rubbed in just now.

I HOPE to hear from people and HOPE to respond quickly.
Alas there is this ongoing problem where I am not getting notifications of replies.
That is why I have been so quite of late.
No good posting if you don't get told there are replies.

P,.S.
I will also include the strobe sketch. Not saying anything is wrong with it, but just so you can see how messed up I am at reading/understanding what is going on.

Strobe_2.ino (1.31 KB)

Another_LED_Test.ino (938 Bytes)

Code from original post (another_LED_test.ino)

//  Another_output_test

byte OUTPUT_PIN = 6;

int SecNow;
int SecGone;
unsigned long LoopTime     = 1000000;
unsigned long InternalLoop =  500000;

unsigned long LastMicros;



void setup()
{
  // put your setup code here, to run once:
  Serial.begin(115200);
  delay(200);
  Serial.println("Setting up");
  pinMode(OUTPUT_PIN,OUTPUT);
  
  
}

void loop()
{
  // put your main code here, to run repeatedly:
  SecNow = (micros()/LoopTime);
  Serial.println(SecNow);
  int SF = 0;
  int RF = 0;
  if(SecGone != SecNow)
  {
    if (SF == 0)
    {
      Serial.println("New cycle");
      SF = 1;
      RF = 0;
    }
    //  Other code here
    SecGone = SecNow;
  }
  else
  //  Given SecGone does equal SecNow
  {
    //
    RF = 0;
    if((micros() - LastMicros) >= InternalLoop)
    {
      //
      if (RF == 0)
      {
        Serial.println("Reset");
        RF = 1;
        SF = 0;
      }
    //  Rest of code here
    }
  }
  
}
  int SF = 0;
  int RF = 0;

This sets these two variables to zero at the top of every loop. They will never be anything different. I think you might have meant to declare them as static so that their value is remembered between iterations of loop().

  static int SF = 0;
  static int RF = 0;

They will be initialised to zero before the first time they are used but never again, even though this code appears inside the loop.

(I haven't received any notifications.... I am luckily still connected.)

You are very correct. That is because I know the sketch doesn't work and it is probably due to stupid things like that.

So indulge me:

void loop()
{
  // put your main code here, to run repeatedly:
  SecNow = (micros()/LoopTime);
  Serial.println(SecNow);
  int SF = 0;
  int RF = 0;
  if(SecGone != SecNow)
  {

should be:

void loop()
{
  // put your main code here, to run repeatedly:
  SecNow = (micros()/LoopTime);
  Serial.println(SecNow);
  static int SF = 0;
  static int RF = 0;
  if(SecGone != SecNow)
  {

What is the difference between the latter there and:

unsigned long LastMicros;
int SF = 0;
int RF = 0;



void setup()
{
  // put your setup code here, to run once:
  Serial.begin(115200);
  delay(200);
  Serial.println("Setting up");
  pinMode(OUTPUT_PIN,OUTPUT);
  
  
}

void loop()
{
  // put your main code here, to run repeatedly:
  SecNow = (micros()/LoopTime);
  Serial.println(SecNow);
  if(SecGone != SecNow)
  {

I feel this is one of many things which is confusing me no end.

I'll be online for a while yet and shall try to remember to come back to this page and refresh before ending the session.

The difference is that the static variables can only be accessed from within the loop() function. This prevents other functions from changing them or even seeing them, unless loop() specifically allows it.

This is important if you use any library code. What if a library uses the variable name "SF"? Which version of SF would it be accessing?

Hint: The 'updated topics' link at the top of the page, just under your user icon, will take you back to every topic that you have posted in, which has updates you haven't seen.

Thanks.

I just think it is bad form that as hard as I try to not post "dumb" questions, and what ever, that I don't get notifications.

It can't be my end, as I have tried a couple of machines. Same result.

I shall really have to sit down and try to get a handle on all this.

Just that if I declare "FOO" at the start - in the pre-amble, to call it - it is a GLOBAL variable.

I get that.

So what is the deal with not just saying:
int FOO;
Where as some people put:
static int FOO;

I know in "blocks of code" the variables are only seen in there - if defined in that block.
And there is also a "constant" type declaration too I think.
So you could have:
int FOO;
static FOO;
constant FOO;

I don't understand the difference when they are declared in the pre-amble.

Sure STATIC when in a function block means it is remembered next time it is called.
So it isn't like you are calling a "virgin" block of code the second time. It remembers stuff from last time.
But CONSTANT?

I shall start a new post with the MESS code I have written. It has more holes than Swiss cheese. But it is a bit of a learning curve for me.

In LOOP() I have a declaration - something like:
unsigned long BLAH;

The sketch "works" (as good as it does) but if I move that line from with in LOOP() and put it in the pre-amble, the sketch doesn't work.

Go figure.

Pointless talking here about it. I shall have to power up the other machine and post it at some stage.

Thanks again though.
:slight_smile:

lost_and_confused:
and what ever, that I don't get notifications.

It does not require very much effort to check the Forum every hour, or every 6 hours or once a day (whichever you prefer). I can't see the need for notifications.

Checking the Forum has the other advantage that you may come across other Threads that have information you could use. Or perhaps some Threads where you could help someone else.

And please don't start new Threads about the same project.

...R

Robin2:
It does not require very much effort to check the Forum every hour, or every 6 hours or once a day (whichever you prefer). I can't see the need for notifications.

Checking the Forum has the other advantage that you may come across other Threads that have information you could use. Or perhaps some Threads where you could help someone else.

Once they started with email notifications, I switched them of as soon as possible. I don't want a mailbox full with messages from this forum.

And I agree that visiting here is also a way to improve your knowledge (just by reading topics and possible solutions) and by helping people in threads that you have knowledge of (e.g. issues that you experienced yourself and found a solution for). Sharing is caring :wink:

@lost_and_confused

You currently have 842 posts to your name.

Surely by now you have read the forum "stickies" about using code tags.

Please use code tags.

Read this before posting a programming question

How to use this forum

Please use them. I don't care if you are confused or not. If you wilfully ignore the forum rules your posts will be deleted and your account suspended.

In global scope (the preamble, as you call it) 'static' variables are visible only to functions IN THAT ONE SOURCE FILE. This is handy for libraries that share data between functions but don't want that data to be visible to anyone else.

The 'const' keyword tells the compiler that you never intend to change that variable. The compiler can then generate an error if you try to store a value in that variable. It lets the compiler protect you from your own mistakes.

johnwasser:
In global scope (the preamble, as you call it) 'static' variables are visible only to functions IN THAT ONE SOURCE FILE. This is handy for libraries that share data between functions but don't want that data to be visible to anyone else.

The 'const' keyword tells the compiler that you never intend to change that variable. The compiler can then generate an error if you try to store a value in that variable. It lets the compiler protect you from your own mistakes.

Ok with the first part, but only sort of.

As I understand it, the "preamble" sets up GLOBAL variables. Ok.
So I could have a variable declared here and it is seen all over.
But what is so "different" about the STATIC qualifier to not having it?

Moving on (sorry) to the CONST part.
I thought #DEFIN LED 13
was doing that.
From what I read:

DEFINE LED 13

is the same as
const LED = 13;

I am sorry if this is seeming to go nowhere but it is how I am seeing things.

Hope to hear back.

I thought #DEFIN LED 13
was doing that.

You mean:

#define LED 13

From what I read:

DEFINE LED 13

is the same as
const LED = 13;

You mean:

#define LED 13

is the same as:

const int LED = 13;

Try to get the syntax right. You can't just throw in upper-case or discard letters or words and hope it works.

This has been asked many times. Try using Google for:

define vs const site:arduino.cc

It's not fair to not bother searching, and then expect people to repeat what has been said, like, 40000 times.

lost_and_confused:
From what I read:

DEFINE LED 13

is the same as
const LED = 13;

From what you read where?

The fact I missed the D in define is possibly a keyboard error. Keys stick or don't get recognised when pressed.
I also failed English/Spelling/Basic syntactical structure.

Also:

and using HelloMessage in 25 places, you'll get 25 copies of the string in SRAM. A const char array would result in only one copy.

On the other hand, there are conventions (not always followed) that call for variable names to be camelCase, and #define names to be ALLCAPITALLETTERS, so that constants can be recognized as such.

I got confused that the NAME of the variable should be in caps and not the command.

I am NOT PERFECT.

Also, these are conventions. As I am not 24/7 programming all the different rules for all the different languages get beyond me, and I get them mixed up.

I have enough trouble trying to stay on the straight and narrow, I don't want/need any extra complications to make my life any more difficult than it already is.

Sorry, but how are we supposed to know that even though you know it should be

#define MYVAR

instead of

#DEFINE myvar

, you accidentally typed it the incorrect way and would never actually do that in your real code?

If you get confused here, what makes it obvious you won't when you write your code?

You came here asking for help and clarification, and then you expect us to guess at what you do know, but accidentally wrote incorrectly, and what you don't know?

And even after being admonished to used code tags, you still refuse to.

lost_and_confused:
I am NOT PERFECT.

If you think that Forum members are being hard on you by expecting careful spelling just wait till you have to deal with the compiler :slight_smile:

Writing computer programs requires a very high level of precision. If you can't achieve that your programs will not work.

...R