Newcomers PRG-course 1 finish your project faster

Hello newcomer,

that's a headline I decided to use very conscious to get the attraction of the coders that are "In a hurry"

So here is the example code. More of my opinion below the code-section

/* Blink without Delay
delay() is the most crappy command that makes every newcomer scratch
their head why does my program not work as expected?

This demo-code is structured into functions
to all newcomers: programming with functions needs 1 minute more time
to write the code but saves 2 to 10 HOURS to find bugs
= you will finish your project much faster because you write a small function
test function and then write the next function. 
This means if a bug occurs it is located in a much smaller area 
= much faster to find. ==> faster finished project

This version of Blink without delay is based on a function 
called "TimePeriodIsOver" 

This function gives back a result "true"  or "false" depending on what the name
of the function says "timePeriodIsOver"

You need ONE additional line of code to make it work.
You have to define a variable that acts as a timing-variable

example: unsigned long myTimer; 

  This example code is in the public domain.
*/

// constants won't change. Used here to set a pin number:
const int ledPin =  LED_BUILTIN;// the number of the LED pin

// Variables will change:
int ledState = LOW;             // ledState used to set the LED

// Generally, you should use "unsigned long" for variables that hold time
// The value will quickly become too large for an int to store
unsigned long myTimer;            // timing-variable
const unsigned long    myInterval = 1000;  // interval at which to blink (milliseconds)


// TimePeriodIsOver ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++   
// function for timing just copy & paste without modifying it
boolean timePeriodIsOver (unsigned long &periodStartTime, unsigned long timePeriod) {
  unsigned long currentMillis  = millis();  
  if ( currentMillis - periodStartTime >= timePeriod )
  {
    periodStartTime = currentMillis; // set new expireTime
    return true;                     // more time than TimePeriod) has elapsed since last time if-condition was true
  } 
  else return false;                 // not expired
} //TimePeriodIsOver ----------------------------------------------------------------------------


// LED-switching  +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// function for switching the LED
void switchLEDState() {
  // if the LED is off turn it on and vice-versa:
  if (ledState == LOW) {
    ledState = HIGH;
  } 
  else {
    ledState = LOW;
  }
  digitalWrite(ledPin, ledState); // set the LED with the ledState of the variable:
} //LED-switching --------------------------------------------------------------


void setup() {
  pinMode(ledPin, OUTPUT);   // set the digital pin as output:
}


void loop() {
  // here is where you'd put code that needs to be running all the time.

  // check if TimePeriodIsOver if true then change the state of the LED
  if (  timePeriodIsOver(myTimer,myInterval) ) {    
    switchLEDState(); // a single line of code with a SELF-explaining name what the function does 
  }
  
}

I have been online in this forum for 1,5 years now. Almost every week 1 to 8 times the same newcomer-questions are posted. Posting the questions is completely OK for me. It is the question of the newcomer. A reasonable part of these questions is just caused by the poor quality of the basic examples delivered with the Arduino-IDE.

If these examples would be of better quality the questions simply wouldn't arise!

So this thread is a start of a series of - what I think - are good quality examples of coding which can be used as templates for often needed functionality.

The start is a blink-without-delay-example that is faster to understand and surely faster to adapt than the "standard" blink without delay.

My definition of "good" is:

Can a newcomer quickly reach a level of understanding that enables him to adapt the given example to his own code and it will work?

It is for sure: with this quickly adapting- new questions will arise if the adaption deviates too much from the given example.
But then it is a real question with a highly motivated user to dive deeper into understanding what is "underneath the hood".

The purists here will surely complain about this approach. I will read their comments but I don't care until they convince me with very good arguments included with the example-codes. (That's why I don't expect anybody convincing me)

best regards Stefan

1 Like

Good idea.
There are a couple of remarks.

  1. You have all time-related variables of type unsigned long, and only one myInterval is just long. Most likely it should also be unsigned long.
  2. The switchLEDState() function would have parameters. If you add a second LED, it will not be able to change its state. This could be, for example, switchLEDState(int pin, int state).

good catch. I corrected this in the original code. As it is documented here and is only a minor change I think it is acceptable in this case.
best regards Stefan

the preface to The Elements of Programming Style by Kernighan and Plauger starts by saying

Good programming cannot be taught by preaching generalities.

the book discusses the flaws it what look like well written programs and showing how to correct and improve them

that does not convince me. Can you post at least an example of a "good programmed program" and how the authors improved it?
Or even better demonstrating the "badness" of my example-code and how to improve it?

remember my defintion of "good" is:

Can a newcomer quickly reach a level of understanding that enables him to adapt the given example to his own code and it will work?

for real big professional programs I probably agree

best regards Stefan

click the link, read the book

this almost sounds like it's ok to learn bad habits while learning and learn the "better" way later

I don’t know the example you are attempting to improve upon.

I do not think basic example programs should have magic “just copy & paste” functions or sections or libraries or whatever.

It takes more than most noobs bring to this kind of discussion to see why it applies at all to anything they might ever want to do. The reason you see something N times a week is that N different ppl have run into something to which your method might apply, only they don’t know it… only in the context of needing to are most going to bother taking the time to learn something general - and even then it’s more likely they solve an immediate problem and do not see it when it arises, in different clothings, again.

a7

if you're trying to describe how to write good programs to newbies, it would make sense to see how others, more professional have tried.

and by good, do you mean fast with flaws or complete, correct and without flaws?

A slightly unfortunate example of a book.
It can be read by those who taught Fortran in the 70s.
All the code is crammed with GOTO operators that are not used today.
Better to read Code Complete by Steve McConnell.

The basic blink without delay installed by the Arduino-IDE-installer

that's what happends with using the basic examples delivered by the arduino-IDE: examples

  • If you need timing - code a delay()

  • don't show functions (and this creates the bad habit of not using functions consequently)

The all do it. Just at a different place.
Any libraries does it
the only difference is using a command
#include instead of copy& paste

and any "basic" command even like
pinMode()
digitalWrite()
pulsein() etc. etc.

does it. The only difference is it is already build in
it does not explain it down to and into the earth of how inputregisters have to be setup to make it work.

so where is the principle difference of using a function like timePeriordIsOver?

Most of my critique is against the basic examples delivered by the Arduino-IDE
best regards Stefan

The Elements of Programming Style by Kernighan and Plauger

Code Complete by Steve McConnell

are neither good for beginners, and I suspect do not fit well with modern learning styles.

Think of where you were, in terms of getting a grip on this stuff, when you used either.

It’s like assigning Steppenwolf to teenagers. Sure they can read it, but do they get it?

a7

Well, TBH you did say you don’t care what anyone thinks, and you did claim that you have created an inarguably superior example program, so I guess I will waste no further time on this.

a7

i'm realizing these discussions pertain to newbie arduino programmers, not freshman CS majors.

as the authors state in the preface, i think one of the best ways to learn to program is from understanding the flaws of what look like otherwise well written programs.

which is why i think it makes sense to rewrite a newbies code showing a "better" approach so they can see a contrast and perhaps the weaknesses in their code

as for being dated (much less written in unfamiliar languages), Cargill wrote C++ Programming Style in 1992. but it's more about classes than basic (C) programming

what are modern learning styles?

Here it is:
https://github.com/arduino/arduino-examples/blob/main/examples/02.Digital/BlinkWithoutDelay/BlinkWithoutDelay.ino
and the associated tutorial:

Maybe I have to explain more who I would like to adress with these examples:

There is a subset of users that could be described as:

I have no or almost no knowledge about programming.

I want to do some rather small project with a quite limited functionality

I'm looking for code-examples or code-snippets that seem to have a similar functionality like the one I need in my project. which I hope to adapt pretty quick to my needs to finish this project.

So this subset of users is not interested in becoming a professional software-developer or a more and more advanced hobby-programmer.

My examples shall guide this subset of users to learn a little better programming as the basic examples delivered with the arduino-IDE does show to them.

best regards Stefan

for those who aren't coders and just trying to use the arduino as a component in their project, they are looking for something like a library/function that does almost exactly what they want.

consider


// toggle an output pin using timestamp and interval
void
blynk (
    byte            pin,
    unsigned long  &msecLst,
    unsigned long   Interval )
{
    unsigned long msec = millis();

    if ( (msec - msecLst) > Interval)  {
        msecLst = msec;
        digitalWrite (pin, ! digitalRead (pin));
    }
}

// -----------------------------------------------------------------------------
byte ledPins [] = { 10, 11 };
#define N_LEDS  sizeof(ledPins)

const unsigned long Interval0 = 1000;
const unsigned long Interval1 = 1250;

unsigned long  msecPin0;
unsigned long  msecPin1;

// -------------------------------------
// configure output pins
void setup ()
{
    Serial.begin (9600);

    for (unsigned n = 0; n < N_LEDS; n++)
        pinMode (ledPins [n], OUTPUT);
}

// -------------------------------------
// invoke 2 timed events
void loop ()
{
    blynk (ledPins [0], msecPin0, Interval0);
    blynk (ledPins [1], msecPin1, Interval1);
}


THX. Good old blink without delay.

I don't see the advantages of @StefanL38 's version.

At least the original only uses minimal "mysterious" things, and they are such first and important parts of Arduino programming that we forgive the use of pinMode and digitalRead and digitalWrite.

Of course all useful programs do some I/O, and for that we are usually introducing things that are not part of the language. I would sanction the use of Serial.print also: useful, arguably necessary and standard. Not some bright flash of light from one guy who thinks it's the bomb.

But both this program and the original demo code tots gloss over or fail to hammer away at sufficiently, noted in a comment

void loop() {
     // here is where you'd put code that needs to be running all the time.

Why doesn't either go ahead and make that a bit more obvious? Maybe even dream up something trivial that could be checked to see that, indeed, we can walk and chew gum (or wait for pizza whilst eating the mail) at the same time?

Placed where it is, the comment is easily overlooked, and if not, its true implications go undemonstrated.

a7

I disagree on that

  unsigned long currentMillis = millis();

  if (currentMillis - previousMillis >= interval) {
    // save the last time you blinked the LED
    previousMillis = currentMillis;

is harder to understand than

  if (  timePeriodIsOver(myTimer,myInterval) ) {    
    switchLEDState(); // a single line of code with a SELF-explaining name what the function does 
  }

The original example does not show the use of functions

and therefore the original example is unstructered. You have to have trained eyes to see the structure in it.

The function-names in my example say what happends
In the original example you have to have trained eyes to re-recognise "ah its timing based on millis()"

You seem to forget how much you take for granted because you have written so often.

best regards Stefan

I would guess that was done intentionally.

But if your goal is to provide blocks of code for copy/paste assembly of sketches, then functions are certainly better.

I'm not convinced the user you are targeting benefits from that approach over using a library, of which there are already multiple for this sort of application, but it may be that there are some users who don't want to write the code, but want it all in their sketch. I do see that here on the forum from time to time, but it's when a student has been prohibited from using libraries for an assignment.