Search code examples
serial-portarduinobufferdelayarduino-uno

Arduino Uno - Light Switch


The function of the program I am writing is to stream incoming analog data from a sensor to a program on my computer across the USB port. For a little fun, I've decided to add a button to the program that will turn on/off a lamp. The lamp will be connected to a relay, which is connected to the arduino. I know how to go about programming it, but I want to know if this will interrupt the sensor data transfer?

I will get the current state of the light (HIGH(1) or LOW(0)) from the arduino when the button is pressed, then write to the arduino (HIGH(1) or LOW(0)) depending on the current state. I have a 5 second delay between each loop of the arduino program, for reasons related to the sensor output; however, I think I'm going to have to change this so that when the button is pressed, it is not missed by the arduino loop, or is that not possible?

I thought I read somewhere that you can't transmit/receive streaming data on the same serial line...in which case, I will need the Mega.


Solution

  • You have to remember and think of the Arduino as a single threaded device. While it is doing anything it is not able to do anything else. Period! In regard to the serial port however, the buffer will still accept incoming data on RX, however if an overflow situation occurs whilst blocked, management is impossible.

    See the following taken directly from the Arduino reference

    Certain things do go on while the delay() function is controlling the Atmega chip however, because the delay function does not disable interrupts. Serial communication that appears at the RX pin is recorded, PWM (analogWrite) values and pin states are maintained, and interrupts will work as they should. Reference

    Now in saying that when you are setting the delay to 5 seconds between loops ( delay(5000) ) you are essentially blocking it from doing anything else almost full stop.

    The Arduino framework exposes a a counter ( millis() ) that basically runs from the moment of boot for roughly 50 days in increments of one (1) millisecond. See Arduino - millis()

    In your application you would define (remember) what loop you were due to run & when the said loop had finished so to not allow the other loop to run until the millis() counter was a defined amount more than your count. (Remember to define the count as a long)

    Then what you do is move your loops out into separate functions that will only execute if the if statement return true...

    for example...

    long interval = 5000; // Define interval outside of the main loop
    long previousCount = 0; // Used to store milli count when finished
    int loopPosition = 1;
    
    void loop()
     {
       if ((long)millis() - previousCount >= 5000 )
          // This if statement will only return true every 5 seconds (5000ms)
         {
            if (loopPosition == 1) 
              {
                function_One();
                previousCount = millis(); // Redefine previousCount to now
                loopPosition++; // Increment loop position
              }
    
            else if (loopPosition == 2)
              {
                function_Two();
                previousCount = millis();
                loopPosition--; // Decrement loop position
              }
    
         }
    
     // Do Anything Here You Want
     // - While ever the if statement above returns false
     //   the loop will move to this without hesitation so
     //   you can do things like monitor a pin low / high scenario.     
    
     }
    
    void function_One()
     {
       // Do Your First Loop
     }
    
    void function_Two()
     {
       // Do Your Second Loop
     }
    

    The above will stop any delay you are using from blocking awesomeness, and to more of a point, almost make delay obsolete if implemented correctly under the right scenarios.

    In regard to your serial data comment, like i said at the top of this article, the Arduino can only do one thing at a time. Transmitting and receiving at exactly the same time is impossible even with the Mega. In saying that a board like the 'Uno' for example is only capable of one serial interface, where as the 'Mega' is capable of four.

    Best of luck....
    NB- For a beginner reading this, the following tutorial / example covers what i have above in fairly simple terms and is a great building block for further awesomeness! Arduino - Blink Without Delay