Using millis() with a switch case condition

Hey there!

I wan't to blink LEDs without a delay function.

From Python I send a hex number to the Arduino, which selects one LED of 27.
This I realize with a switch case condition.

The next step is to get the LEDs blinked without a delay function.

I was trying it with an external function like this, but it doesn't work:

void blinkWithoutDelay(int pin, int off, int on)
{
        int blinkPhase=millis()%(off+on);
        
        if (blinkPhase<off) {
          digitalWrite(pin, LOW);
        }
        else {
          digitalWrite(pin, HIGH);
        }
}

The case condition of one value:

void loop() 
{
 
    if(Serial.available())
    {
       
        switch(Serial.read())
      {
        case 0x01: blinkWithoutDelay(4, 50, 2000);
                   break;

The Python Code:

import serial
import time

ser = serial.Serial('COM3', 9600)
time.sleep(2)
ser.write(b'\x01')
ser.close()

Thanks alot!

Greetings!

eule

I was trying it with an external function like this, but it doesn't work:

External? External to what?

That function does something. You need to be way more informative than "it doesn't work".

How and where are you calling that function?

@eule, post your complete Arduino program.

...R
Serial Input Basics - simple reliable ways to receive data.

Sorry guys!

I just wanted to say that I coded a function for the different cases, where it is opened with different parameters, e.g. the the LEDpin.

Here the whole arduino code:

void setup() {
 
   Serial.begin(9600); 
  // pins 3 - 29 set as output, default will be low
  pinMode(3, OUTPUT);   //Fach1 - rot
  pinMode(4, OUTPUT);   //Fach1 - blau
  pinMode(5, OUTPUT);   //Fach1 - grün
  
  pinMode(6, OUTPUT);   //Fach2 - rot
  pinMode(7, OUTPUT);   //Fach2 - blau
  pinMode(8, OUTPUT);   //Fach2 - grün
  
  pinMode(9, OUTPUT);   //Fach3 - rot
  pinMode(10, OUTPUT);  //Fach3 - blau
  pinMode(11, OUTPUT);  //Fach3 - grün
  
  pinMode(12, OUTPUT);  //Fach4 - rot
  pinMode(13, OUTPUT);  //Fach4 - blau
  pinMode(14, OUTPUT);  //Fach4 - grün
  
  pinMode(15, OUTPUT);  //Fach5 - rot
  pinMode(16, OUTPUT);  //Fach5 - blau
  pinMode(17, OUTPUT);  //Fach5 - grün
  
  pinMode(18, OUTPUT);  //Fach6 - rot
  pinMode(19, OUTPUT);  //Fach6 - blau
  pinMode(20, OUTPUT);  //Fach6 - grün
  
  pinMode(21, OUTPUT);  //Fach7 - rot
  pinMode(22, OUTPUT);  //Fach7 - blau
  pinMode(23, OUTPUT);  //Fach7 - grün
  
  pinMode(24, OUTPUT);  //Fach8 - rot
  pinMode(25, OUTPUT);  //Fach8 - blau
  pinMode(26, OUTPUT);  //Fach8 - grün
  
  pinMode(27, OUTPUT);  //Fach9 - rot
  pinMode(28, OUTPUT);  //Fach9 - blau
  pinMode(29, OUTPUT);  //Fach9 - grün
  
}

void loop() {
  
    switch (Serial.read()) {
    case 0x01:
      blinkWithoutDelay(3, 100, 200)
      break;
    case 0x02:
      digitalWrite(4,  HIGH);
      break;
    case 0x03:
      digitalWrite(5,  HIGH);
      break;
    case 0x04:
      digitalWrite(3,  HIGH);
      digitalWrite(5,  HIGH);
      break;
    case 0x05:
      digitalWrite(3,  HIGH);
      digitalWrite(4,  HIGH);
      break;
    case 0x06:
      digitalWrite(3,  HIGH);
      digitalWrite(4,  HIGH);
      digitalWrite(5,  HIGH);
      break;
    case 0x07:
      digitalWrite(6,  HIGH);
      break;
    case 0x08:
      digitalWrite(7,  HIGH);
      break;
    case 0x09:
      digitalWrite(8,  HIGH);
      break;
    case 0x0A:
      digitalWrite(6,  HIGH);
      digitalWrite(8,  HIGH);
      break;
    case 0x0B:
      digitalWrite(6,  HIGH);
      digitalWrite(7,  HIGH);
      break;
    case 0x0C:
      digitalWrite(6,  HIGH);
      digitalWrite(7,  HIGH);
      digitalWrite(8,  HIGH);
      break;
    case 0x0D:
      digitalWrite(9,  HIGH);
      break;
    case 0x0E:
      digitalWrite(10, HIGH);
      break;
    case 0x0F:
      digitalWrite(11, HIGH);
      break;
    case 0x10:
      digitalWrite(9,  HIGH);
      digitalWrite(11, HIGH);
      break;
    case 0x11:
      digitalWrite(9,  HIGH);
      digitalWrite(10, HIGH);
      break;
    case 0x12:
      digitalWrite(9,  HIGH);
      digitalWrite(10, HIGH);
      digitalWrite(11, HIGH);
      break;
    case 0x13:
      digitalWrite(12, HIGH);
      break;
    case 0x14:
      digitalWrite(13, HIGH);
      break;
    case 0x15:
      digitalWrite(14, HIGH);
      break;
    case 0x16:
      digitalWrite(12, HIGH);
      digitalWrite(14, HIGH);
      break;
    case 0x17:
      digitalWrite(12, HIGH);
      digitalWrite(13, HIGH);
      break;
    case 0x18:
      digitalWrite(12, HIGH);
      digitalWrite(13, HIGH);
      digitalWrite(14, HIGH);
      break;
    case 0x19:
      digitalWrite(15, HIGH);
      break;
    case 0x1A:
      digitalWrite(16, HIGH);
      break;   
    case 0x1B:
      digitalWrite(17, HIGH);
      break;
    case 0x1C:
      digitalWrite(15, HIGH);
      digitalWrite(17, HIGH);
      break;    
    case 0x1D:
      digitalWrite(15, HIGH);
      digitalWrite(16, HIGH);
      break;      
    case 0x1E:
      digitalWrite(15, HIGH);
      digitalWrite(16, HIGH);
      digitalWrite(17, HIGH);
      break;
    case 0x1F:
      digitalWrite(18, HIGH);
      break;
    case 0x20:
      digitalWrite(19, HIGH);
      break;
    case 0x21:
      digitalWrite(20, HIGH);
      break;
    case 0x22:
      digitalWrite(18, HIGH);
      digitalWrite(20, HIGH);
      break;
    case 0x23:
      digitalWrite(18, HIGH);
      digitalWrite(19, HIGH);
      break;  
    case 0x24:
      digitalWrite(18, HIGH);
      digitalWrite(19, HIGH);
      digitalWrite(20, HIGH);
      break;   
         
       
       
       
       
       
       
  }

  void blinkWithoutDelay(int pin, int off, int on)
{
        int blinkPhase=millis()%(off+on);
        
        if (blinkPhase<off) {
          digitalWrite(pin, LOW);
        }
        else {
          digitalWrite(pin, HIGH);
        }
}


}

Copied from OP

void loop()
{

if(Serial.available())
{

switch(Serial.read())
{
case 0x01: blinkWithoutDelay(4, 50, 2000);
break;

void blinkWithoutDelay(int pin, int off, int on)
{
int blinkPhase=millis()%(off+on);

if (blinkPhase<off) {
digitalWrite(pin, LOW);
}
else {
digitalWrite(pin, HIGH);
}
}

The blinkWithoutDelay(int pin, int off, int on)
gets executed , single pass, only ONCE AFTER after Serial.read case is 0x01, therefore you need to find another way to execute it multiple time- blink. .
Hint - the linkWithoutDelay(int pin, int off, int on) was intended to be part of continuous loop, mainly real Arduino loop(). You could put it into case 0x01 in similar loop , perhaps time limited ( blink 10 times) BUT than you will loose the nonblocking feature of blinkWithoutDelay(int pin, int off, int on). Your call.

Yes that‘s true! For me it would even be fine, if the LED would be lightning for example 2 seconds after Turning it on with the hex number! How could I do this on easy way without blocking of a Delay function? =)

How could I do this on easy way without blocking of a Delay function? =)

You have some code that decides what to do. You have some code that does what needs doing. Do NOT place the do-what-needs-doing code in the decide-wjat-needs-to-be-done block.

So I am changing my code into this:

But I even have the problem that the LED is not blinking?!

Code of the Arduino:

char serialData;
unsigned long startMillis = 0;
unsigned long currentMillis = 0;
const unsigned long interval = 1000;

void setup() 
{
  
  Serial.begin(9600);
  pinMode(3, OUTPUT);   //Fach1 - rot
  pinMode(4, OUTPUT);   //Fach1 - blau
  pinMode(5, OUTPUT);   //Fach1 - grün
  pinMode(6, OUTPUT);   //Fach2 - rot
  startMillis = millis();
  
}

void loop() 
{
  currentMillis = millis();

  if (currentMillis - startMillis >= interval && Serial.available())
  {
     
      
      if(Serial.read() == 0x01){
        digitalWrite(4, !digitalRead(4));
         startMillis = currentMillis;
      }      
    
      if(Serial.read() == 0x02)
      {
        digitalWrite(6,!digitalRead(6));
         startMillis = currentMillis;
      }
     }
  }

Code of Python:

import serial
import time

ser = serial.Serial('COM3', 9600)
time.sleep(2)
ser.write(b'\x01')
#ser.write(b'\x02')
ser.close()

I would be very happy if anybody could help me!

Greetings!

eule

ser.write(b'\x01')

I don't speak Python. Can you please tell me exactly what this writes ?

UKHeliBob:

ser.write(b'\x01')

I don't speak Python. Can you please tell me exactly what this writes ?

It writes 1 byte with the hex-value 0x01. If the "b" was omitted, the value would have been encoded using the system codepage (eg. UTF-8).

What I just want to do is to send a hex number from python to the Arduino, read it and make with this hex number a decision what number of LED will be switched on.

With the millis() function I want to hold the LED switched on for about 3 seconds.

I was now trying about 50 different solutions and no one is working :confused:

I'm really new to arduino..

Thanks!

eule

If you have multiple LED's and you want each of them to be able to blink without blocking then you need to store blink start time, duration and frequency for each of the LED's. For each "loop()", you would then use a for loop to go through all the LED's and adjust their state accordingly. You should detach the process of reading command from serial completely from the blinking process.

Start with something really simple. No timing, just on/off control of a LED

const byte ledPin = 10;

void setup()
{
  Serial.begin(115200);
  pinMode(ledPin, OUTPUT);
}

void loop()
{
  if (Serial.available())
  {
    char inChar = Serial.read();
    if (inChar == '1')
    {
      digitalWrite(ledPin, LOW);
    }
    else 
    if (inChar == '2')
    {
      digitalWrite(ledPin, HIGH);
    }
  }
}

Note that this uses characters and can be tested using input from the Serial monitor. Get this working before moving on to add timing

I solved this already UKHeliBob
I have to get this working on my work.

No chancetime to begin with more easy things.

I think I have enough experience to get this working... I hope so =)

If I send the hex number from Python to the Arduino, is it normal that the setup is reloading

What priority has the millis() function and what priority has the pyserial functions

Thanks!

If I send the hex number from Python to the Arduino, is it normal that the setup is reloading

It is if you open and close the serial link from Python. Opening the serial link causes most Arduino boards to reboot.

What priority has the millis() function and what priority has the pyserial functions

The value is updated by an interrupt and is returned by the millis() function when requested so unless interrupts are turned off it will be correct. I know nothing about pyserial.

"I solved this already UKHeliBob"
Could you share your solution? Please.,

ok I found something to switch this command off

http://forum.arduino.cc/index.php?topic=18371.0

I hope it will run.. =)

thanks alot!

I could imagine that pyserial is running with an interrupt, too.

I dont know what priority they have.. I think this could be interesting.