message:
How to exit a function if conditions are met

Hello I want to exit a function if conditions are meet .

I have this code inside the `loop()`

    if (t.hour == 7 && t.min == 16) {
      if(moistureOneSensorValue >= 700 ){
         RelayOne();
      }
    }

If its `true` it will call the `RelayOne()` function and open the solenoid valve
inside the `relayOne()` fucntion i have also code for waterflow sensor

below is the relayOne function code for opening the valve and getting data from waterflow

     void RelayOne(){

    //Serial.println("Valve Open");
    digitalWrite(RELAY1, 0); //OPEN VALVE
    digitalWrite(WATERFLOW1, HIGH);//READY WATER FLOW FOR SENSING
    //WATER FLOW

    if((millis() - oldTime) > 1000)    // Only process counters once per second
      {
        // Disable the interrupt while calculating flow rate and sending the value to
        // the host
        detachInterrupt(sensorInterrupt);

        // Because this loop may not complete in exactly 1 second intervals we calculate
        // the number of milliseconds that have passed since the last execution and use
        // that to scale the output. We also apply the calibrationFactor to scale the output
        // based on the number of pulses per second per units of measure (litres/minute in
        // this case) coming from the sensor.

        flowRate = ((1000.0 / (millis() - oldTime)) * pulseCount) / calibrationFactor;

        //Serial.print(pulseCount);

        // Note the time this processing pass was executed. Note that because we've
        // disabled interrupts the millis() function won't actually be incrementing right
        // at this point, but it will still return the value it was set to just before
        // interrupts went away.

        oldTime = millis();

       //  Serial.print("::");
        // Serial.print(oldTime);
        // Divide the flow rate in litres/minute by 60 to determine how many litres have
        // passed through the sensor in this 1 second interval, then multiply by 1000 to
        // convert to millilitres.

        flowMilliLitres = (flowRate / 60) * 1000;

        // Serial.print(flowMilliLitres);
        // Add the millilitres passed in this second to the cumulative total

        totalMilliLitres += flowMilliLitres;

        unsigned int frac;

        // Print the cumulative total of litres flowed since starting
        Serial.print("  Output Liquid Quantity: ");             // Output separator
        Serial.print(totalMilliLitres);
        Serial.println("mL");

        //setPointForN1 = EEPROM.get(0, WATEREQFORN1) / 2;

       if(totalMilliLitres >= setPointForN1 ){
           closeSolenoidValve();

          }

         // Reset the pulse counter so we can start incrementing again
        pulseCount = 0;

        // Enable the interrupt again now that we've finished sending output
        attachInterrupt(sensorInterrupt, pulseCounter, FALLING);
      }

      if(flowMilliLitres == 0){
         totalMilliLitres = 0;
      }

    }

this line of code will supposedly close the valve but its not working

    `if(totalMilliLitres >= setPointForN1 ){
               closeSolenoidValve();

              }`

the problem is that it will wait for 1 minute before closing the valve even tho the set point already reach .

Below is My full code

    #include <EEPROM.h>

    #include <TimeAlarms.h>
    #include <Wire.h>
    #include <dht.h>
    #include <DS3231.h>

    // Init the DS3231 using the hardware interface
    DS3231  rtc(SDA, SCL);
    //RTC_DS1307 rtc;

    Time  t;

    dht DHT;

    //PINS
    #define MOISTURE1 A15
    #define MOISTURE2 A14

    #define RELAY1 7
    #define RELAY2 6
    #define ALARM 13
    #define DHT11_PIN A11

    int relayState1 = 1;
    int relayState2 = 1;
    //WATER FLOW VARIABLES

    byte sensorInterrupt = 0;  // 0 = digital pin 2
    byte sensorInterrupt2 = 1;  // 0 = digital pin 3
    byte  WATERFLOW1 = 2;
    byte  WATERFLOW2 = 3;

    // The hall-effect flow sensor outputs approximately 4.5 pulses per second per
    // litre/minute of flow.
    float calibrationFactor = 4.5;

    volatile byte pulseCount;
    volatile byte pulseCount2;
    //For Waterflow sensor pin 13
    float flowRate;
    float frac;
    unsigned int flowMilliLitres;
    unsigned long totalMilliLitres;

    //For Waterflow sensor pin 12
    float flowRate2;
    float frac2;
    unsigned int flowMilliLitres2;
    unsigned long totalMilliLitres2;

    unsigned long setPointForN1;
    unsigned long setPointForN2;

    unsigned long oldTime;

    unsigned long oldTime2;

    ///END OF WATER FLOW VARIABLES

    unsigned int val;
    int DELAYNI = 1000;

    //Sensor Variables

    int  moistureOneSensorValue;
    int  moistureTwoSensorValue;
    int  waterLevelSensorValue;
    int  humiditySensorValue;
    int  tempSensorValue;

    //FOR EEPROM
    unsigned int WATEREQFORN1;
    unsigned int WATEREQFORN2;
    unsigned long DELAYINTERVALOFDATA;
    unsigned long prevMillis = 0;

    unsigned long interval;

    // -------------------------------------------------------------------
    // SETUP    SETUP    SETUP    SETUP    SETUP    SETUP    SETUP    SETUP
    // -------------------------------------------------------------------

    void setup() {

      // put your setup code here, to run once:

      // Setup Serial connection
      Serial.begin(9600);
      rtc.begin();
      Wire.begin();

       //EEPROM

      //int eepromSize=EEPROM.length();
      //Serial.print("EEPROM found, size=");
     // Serial.println(eepromSize);
        // Get the last fade value (as an integer)
      //EEPROM.get(0, WATEREQFORN1);
      //Serial.print("Last Value N1: ");
     // Serial.println(WATEREQFORN1);

     // EEPROM.get(3, WATEREQFORN2);
     // Serial.print("Last Value N2: ");
     // Serial.println(WATEREQFORN2);

    pinMode(MOISTURE1, INPUT);
    pinMode(MOISTURE2, INPUT);
    pinMode(WATERFLOW1, INPUT);
    pinMode(WATERFLOW2, INPUT);
    pinMode(DHT11_PIN, INPUT);
    pinMode(RELAY1, OUTPUT);
    pinMode(RELAY2, OUTPUT);

    //WATER FLOW
      pulseCount        = 0;
      flowRate          = 0.0;
      flowMilliLitres   = 0;
      totalMilliLitres  = 0;

      oldTime           = 0;
       attachInterrupt(sensorInterrupt, pulseCounter, FALLING);

      pulseCount2        = 0;
      flowRate2          = 0.0;
      flowMilliLitres2   = 0;
      totalMilliLitres2  = 0;

      oldTime2           = 0;
      attachInterrupt(sensorInterrupt2, pulseCounter2, FALLING);

      digitalWrite(RELAY1, 1);
      digitalWrite(RELAY2, 1);
    }

    void loop() {

      // put your main code here, to run repeatedly:
      t = rtc.getTime();
    //DateTime now = rtc.now();
    //This will get data send from the Desktop Application
    char inc;
      while (Serial.available()) { // Get characters
        inc = Serial.read();
        if (inc >= '0' && inc <= '9') {
          val = 10*val + (inc-'0');
        } else {
          switch (toupper(inc)) {
          case 'A':
            Serial.print("Case A got ");
            Serial.println(val);
            WATEREQFORN1 = val;

                EEPROM.put(0, WATEREQFORN1);
                //Serial.print("DATA SAVE TO EEPROM");

            break;
          case 'B':
            Serial.print("Case B got ");
            Serial.println(val);
             WATEREQFORN2 = val;
             EEPROM.put(5, WATEREQFORN2);
             //Serial.print("DATA SAVE TO EEPROM");

            break;
          case 'D':
            Serial.print("Case D got ");
            Serial.println(val);
            DELAYINTERVALOFDATA = val;
            EEPROM.put(10,DELAYINTERVALOFDATA);
            break;

          default :
            ; // handle blanks, returns, etc
          }
          val = 0;  // Set val to zero after any non-digit
        }//END of SWITCH
      }//END of WHILE

       moistureOneSensorValue = analogRead(MOISTURE1);
       moistureTwoSensorValue = analogRead(MOISTURE2);

     // -------------------------------------------------------------------
     // Alarm Every Morning 7 AM Check If The Soil is DRY if DRY it will water
     // -------------------------------------------------------------------
    if (t.hour == 0 && t.min == 49) {
      if(moistureOneSensorValue >= 700 ){
         RelayOne();

      }
      //if(moistureTwoSensorValue >= 700 ){
      //  RelayTwo();
     // }
    }else{
       digitalWrite(RELAY1, 1); //CLOSE VALVE

    }
    // -------------------------------------------------------------------
    // Alarm Every Afternoon 4 PM and Check if the soil is DRY if DRY it will water
    // -------------------------------------------------------------------

    if (t.hour == 16 && t.min == 00 && moistureOneSensorValue >= 700 ) {
      if(moistureOneSensorValue >= 700 ){
         RelayOne();
         digitalWrite(RELAY1, 1);
      }
      if(moistureTwoSensorValue >= 700 ){
         RelayOne();
      }
    }
     readAllSensorStatus();

    //Setting alarm/timer at every 2:32:53pm,
    //in other words you can insert t.dow for every Thursday?, t.date for specific date?
    //  {Serial.println("RELAY ON");

    //Lets say that your component is wired to pin 99 and be switched on for 5 seconds,
    //whatever you want to do with it

      // Wait one second before repeating :)
     // delay (1000);
     if(RELAY1 == LOW){
          digitalWrite(RELAY1, 1);
     }
    }

    void readAllSensorStatus(){
       unsigned long currentMillis = millis();

       interval = EEPROM.get(10,DELAYINTERVALOFDATA);
       if(currentMillis - prevMillis > interval) {
            prevMillis = currentMillis;
      //moistureSensorValue >= 700 DRY
      //
      //moistureSensorValue < 700 && moistuteSensorValue >= 300 Moist soil
      //
      //moistureSensorValue < 300 soggy soil
      //
      //Moisture
     moistureOneSensorValue = analogRead(MOISTURE1);
     moistureTwoSensorValue = analogRead(MOISTURE2);
     //Humidity and Temperature
     int chk = DHT.read11(DHT11_PIN);

     humiditySensorValue = DHT.humidity;
     tempSensorValue = DHT.temperature;
     //Water LEvel

      String LineOne = "-";
      String SensorValue = moistureOneSensorValue + LineOne + moistureOneSensorValue + LineOne + humiditySensorValue + LineOne + tempSensorValue;

      Serial.println(SensorValue);
      Serial.println(t.hour+LineOne+t.min);
       }

    }
    void closeSolenoidValve(){
       digitalWrite(RELAY1, 1); //Close

    }
    void RelayOne(){

    //Serial.println("Valve Open");
    digitalWrite(RELAY1, 0); //OPEN VALVE
    digitalWrite(WATERFLOW1, HIGH);//READY WATER FLOW FOR SENSING
    //WATER FLOW

    if((millis() - oldTime) > 1000)    // Only process counters once per second
      {
        // Disable the interrupt while calculating flow rate and sending the value to
        // the host
        detachInterrupt(sensorInterrupt);

        // Because this loop may not complete in exactly 1 second intervals we calculate
        // the number of milliseconds that have passed since the last execution and use
        // that to scale the output. We also apply the calibrationFactor to scale the output
        // based on the number of pulses per second per units of measure (litres/minute in
        // this case) coming from the sensor.

        flowRate = ((1000.0 / (millis() - oldTime)) * pulseCount) / calibrationFactor;

        //Serial.print(pulseCount);

        // Note the time this processing pass was executed. Note that because we've
        // disabled interrupts the millis() function won't actually be incrementing right
        // at this point, but it will still return the value it was set to just before
        // interrupts went away.

        oldTime = millis();

       //  Serial.print("::");
        // Serial.print(oldTime);
        // Divide the flow rate in litres/minute by 60 to determine how many litres have
        // passed through the sensor in this 1 second interval, then multiply by 1000 to
        // convert to millilitres.

        flowMilliLitres = (flowRate / 60) * 1000;

        // Serial.print(flowMilliLitres);
        // Add the millilitres passed in this second to the cumulative total

        totalMilliLitres += flowMilliLitres;

        unsigned int frac;

        // Print the cumulative total of litres flowed since starting
        Serial.print("  Output Liquid Quantity: ");             // Output separator
        Serial.print(totalMilliLitres);
        Serial.println("mL");

        setPointForN1 = EEPROM.get(0, WATEREQFORN1) / 2;

       if(totalMilliLitres >= setPointForN1 ){
           //closeSolenoidValve();
            digitalWrite(RELAY1, 1); //OPEN VALVE
          return loop();
          }

         // Reset the pulse counter so we can start incrementing again
        pulseCount = 0;

        // Enable the interrupt again now that we've finished sending output
        attachInterrupt(sensorInterrupt, pulseCounter, FALLING);
      }

      if(flowMilliLitres == 0){
         totalMilliLitres = 0;
      }

    }

    void RelayTwo(){

    digitalWrite(RELAY2, 0);
    digitalWrite(WATERFLOW2, HIGH);//READY WATER FLOW FOR SENSING
    //WATER FLOW

    if((millis() - oldTime2) > 1000)    // Only process counters once per second
      {
        // Disable the interrupt while calculating flow rate and sending the value to
        // the host
        detachInterrupt(sensorInterrupt2);

        // Because this loop may not complete in exactly 1 second intervals we calculate
        // the number of milliseconds that have passed since the last execution and use
        // that to scale the output. We also apply the calibrationFactor to scale the output
        // based on the number of pulses per second per units of measure (litres/minute in
        // this case) coming from the sensor.

        flowRate2 = ((1000.0 / (millis() - oldTime2)) * pulseCount2) / calibrationFactor;

        //Serial.print(pulseCount);

        // Note the time this processing pass was executed. Note that because we've
        // disabled interrupts the millis() function won't actually be incrementing right
        // at this point, but it will still return the value it was set to just before
        // interrupts went away.

        oldTime2 = millis();

       //  Serial.print("::");
        // Serial.print(oldTime);
        // Divide the flow rate in litres/minute by 60 to determine how many litres have
        // passed through the sensor in this 1 second interval, then multiply by 1000 to
        // convert to millilitres.

        flowMilliLitres2 = (flowRate2 / 60) * 1000;

        // Serial.print(flowMilliLitres2);
        // Add the millilitres passed in this second to the cumulative total

        totalMilliLitres2 += flowMilliLitres2;

        unsigned int frac2;

        // Print the cumulative total of litres flowed since starting
        //Serial.print("  Output Liquid Quantity: ");             // Output separator
        //Serial.print(totalMilliLitres2);
        //Serial.println("mL");

       setPointForN2 = EEPROM.get(5, WATEREQFORN2) / 2;

       if(totalMilliLitres >= setPointForN2 ){
           Serial.println("Solenoid Close Set Point Reach");
           digitalWrite(RELAY2, 1); //CLOSE VALVE
        }

         // Reset the pulse counter so we can start incrementing again
        pulseCount2 = 0;

        // Enable the interrupt again now that we've finished sending output
        attachInterrupt(sensorInterrupt2, pulseCounter2, FALLING);
      }

      if(flowMilliLitres2 == 0){
         totalMilliLitres2 = 0;
      }

    }

    /*
    Insterrupt Service Routine
     */
    void pulseCounter()
    {
      // Increment the pulse counter
      pulseCount++;
    }

    void pulseCounter2()
    {
      // Increment the pulse counter
      pulseCount2++;
    }

body:
This may not be a direct answer to the question, in the sense that I
cannot tell you where exactly is the bug in your program. But hopefully
it will help you getting a program that does work. I tried to find the
bug, but it's quite hard. When reading your code, I could not stop
asking myself “Why is this so convoluted?”. As a general rule, a simple
program is easier to get working than a complex program. So I would ask
you: why don't you try something simple instead?

The first thing that stroke me is that it seems you did not realize that
the pulse count from the flow sensor is a direct measurement of the
volume that went through it. You are timing the pulses in order to
convert a pulse count into a pulse rate, then you convert that into a
flow rate, then you integrate the flow rate rate to get the volume. All
this is unnecessary complication: just count the pulses, the count
**is** a water volume, albeit in an unusual unit.

Second thing is the logic of the whole program. It should be clear at
first sight under what conditions the watering starts and under what
conditions it stops. This is best done with a [finite state machine][]
with two state: either we are watering the plants or we are not. The
state variable is then a boolean, and the logic could written along
those lines:

    void loop()
    {
        // Should we start watering?
        if (!watering) {
            if (some_condition()) {
                start_watering();
                watering = true;
            }
        }

        // Should we stop watering?
        else {
            if (some_other_condition()) {
                stop_watering();
                watering = false;
            }
        }
    }

Something explicit like this is generally easier to read, to understand
and to debug. And likely to be less buggy in the first place.

Third thing, you seems to be doing too much stuff at once: controlling
two different pumps, monitoring a DHT sensor, updating the setpoints...
You should try to get a _minimal program_ working, and only then start
to add more stuff. The more functionality you add, the more complex the
program gets. Don't expect something complex to just work: you should
really get a simple version working first, and only then build on that.

Here is a proposed simplified version for your program. Absolutely not
tested: it is just meant to get you started.

    #include <EEPROM.h>
    #include <DS3231.h>

    const uint8_t RELAY_PIN = 7;
    const uint8_t MOISTURE_PIN = A15;
    const uint8_t FLOW_SENSOR_PIN = 2;
    const uint8_t SENSOR_INTERRUPT = 0;
    const float PULSES_PER_ML = (4.5*60)/1e3;  // 0.27 pulses/mL
    const int MOISTURE_THRESHOLD = 700;

    uint16_t wateringPulseCount;  // required pulses of water to deliver
    DS3231  rtc(SDA, SCL);

    /***********************************************************************
     * Handling of pulse counts.
     */

    volatile uint16_t pulseCount;

    // Interrupt handler.
    void pulseCounter()
    {
        pulseCount++;
    }

    // Safely read the current pulse count.
    static inline uint16_t getPulseCount()
    {
        noInterrupts();
        uint16_t pulseCountCopy = pulseCount;
        interrupts();
        return pulseCountCopy;
    }

    /***********************************************************************
     * Main program.
     */

    void setup()
    {
        pinMode(RELAY_PIN, OUTPUT);
        pinMode(MOISTURE_PIN, INPUT);
        pinMode(FLOW_SENSOR_PIN, INPUT);

        // Initialize the watering limit as a pulse count.
        uint16_t wateringVolume;
        wateringPulseCount = EEPROM.get(0, wateringVolume) * PULSES_PER_ML;
    }

    void loop()
    {
        static bool watering;  // are we watering now?

        // Start watering at 07:00 if the soil is dry.
        Time t = rtc.getTime();
        if (!watering && t.hour == 7 && t.min == 0) {
            if (analogRead(MOISTURE_PIN) > MOISTURE_THRESHOLD) {
                pulseCount = 0;
                attachInterrupt(SENSOR_INTERRUPT, pulseCounter, FALLING);
                digitalWrite(RELAY_PIN, LOW);  // open valve
                watering = true;
            }
        }

        // Stop watering after the required volume.
        if (watering) {
            if (getPulseCount() >= wateringPulseCount) {
                digitalWrite(RELAY_PIN, HIGH);  // close valve
                detachInterrupt(SENSOR_INTERRUPT);
                watering = false;
            }
        }
    }

Note that the pulse count has to be read with interrupts disabled, but
you should **not** detach the interrupt handler. Detaching the handler
means you will miss pulses, wheres disabling the interrupts only delays
their handling until you enable them again. You won't miss pulses unless
to keep the interrupts disabled for too long (which you shouldn't do).

[finite state machine]: https://hackingmajenkoblog.wordpress.com/2016/02/01/the-finite-state-machine/


sender: user

message:
ATmega328P SPI Slave

I was scrolling through the ATmega328P datasheet when I came across a rather fascinating statement about the way in which the data part of the SPI interface is buffered. I can't seem to understand why the double input buffer is necessary. The following statement can be found on page 161 ([Datasheet][1]):

> The system is single buffered in the transmit direction and double buffered in the receive direction. This
means that bytes to be transmitted cannot be written to the SPI Data Register before the entire shift cycle
is completed. When receiving data, however, a received character must be read from the SPI Data
Register before the next character has been completely shifted in. Otherwise, the first byte is lost.

Can someone please briefly explain to me why the double input buffer is necessary?

  [1]: http://www.atmel.com/images/Atmel-8271-8-bit-AVR-Microcontroller-ATmega48A-48PA-88A-88PA-168A-168PA-328-328P_datasheet_Complete.pdf

sender: assistant

body:
You have control over when you place a byte in the TX buffer and control over when you read a byte from the RX buffer. You don't have control over when the master sends data to you, though, so somewhere is needed to store that incoming data until you read it. Since the master can start sending another byte before you have read the last one it's critical that the receiving shift register is separate from the register you read the shifted in data from.  Only when the complete byte has been shifted in does it get copied to the receive buffer, so that another shifting in can begin.

When transmitting you don't need to worry about that since what you write into the TX buffer is what is about to be shifted out. You don't write anything else until it's time to send the next byte, at which point the TX register is empty anyway.


message:
My button stays on high if I press it once, what did I do wrong?

If I press my button once, I get characters on all of the 32 character places and I get an infinite tone with my piezo. Can someone help me with this?

[![Arduino circuit][1]][1]

    #include <LiquidCrystal.h>

    const int buttonPin = A0;
    int buttonState = 0;
    LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
    byte run1c[8] = {
      B00000,
      B01100,
      B01100,
      B00000,
      B01110,
      B11100,
      B01110,
      B10010,
    };

    byte run2c[8] = {
      B00000,
      B01100,
      B01100,
      B00000,
      B11100,
      B01110,
      B11100,
      B10010,
    };

    byte jumpc[8] = {
      B01100,
      B01100,
      B00000,
      B11110,
      B01101,
      B11111,
      B10000,
      B00000,
    };

    byte jumpLowerc[8] = {
      B01110,
      B11100,
      B01110,
      B10000,
      B00000,
      B00000,
      B00000,
      B00000,
    };

    byte groundc[8] = {
      B11111,
      B11111,
      B11111,
      B11111,
      B11111,
      B11111,
      B11111,
      B11111,
    };

    byte rightGroundc[8] = {
      B00011,
      B00011,
      B00011,
      B00011,
      B00011,
      B00011,
      B00011,
      B00011,
    };

    byte leftGroundc[8] = {
      B11100,
      B11100,
      B11100,
      B11100,
      B11100,
      B11100,
      B11100,
      B11100,
    };

    void setup() {
      lcd.createChar(0, run1c);
      lcd.createChar(1, run2c);
      lcd.createChar(2, jumpc);
      lcd.createChar(3, jumpLowerc);
      lcd.createChar(4, groundc);
      lcd.createChar(5, rightGroundc);
      lcd.createChar(6, leftGroundc);
      Serial.begin(9600);
      lcd.begin(16, 2);
      pinMode(buttonPin, INPUT);
    }

    void loop() {
      buttonState = digitalRead(buttonPin);
      if(buttonState == HIGH){
        tone(8, 400);
        lcd.setCursor(1,0);
        lcd.write(byte(2));
        digitalWrite(buttonState, LOW);
      } else {
        lcd.setCursor(1,1);
        lcd.write(byte(0));
      }
    }

  [1]: https://i.stack.imgur.com/cWNYp.png

body:
From what I can tell from your drawing, you have both sides of your button tied to 5V.  The green wire on one side and the blue wire through the resistor on the other.  So yes, the button will always read HIGH.

Instead, remove the resistor, tie one side of the button to the pin and the other side to ground.  Use INPUT_PULLUP in your pinMode cal instead of just INPUT.  Now a pressed button will read LOW and not pressed will read HIGH, so you'll have to reverse your logic in your code.  But the wiring will be much nicer.


body:
In your code you check the button state and if it is high you set the tone.

In the else section you do nothing with the tone.

Hence, once on, it will always stay on.


message:
Help understanding circuit for button example

I´m working on the button example
.Basically, i don't quite get the use of this connection.
[![enter image description here][2]][2]

Also, the breadboard i'm using is not quite the ones i see on most tutorials.
[![enter image description here][3]][3]

is there any 'mapping' i could make between them?

I really appreciate any help you can provide.

  [2]: https://i.stack.imgur.com/XH1Jh.png
  [3]: https://i.stack.imgur.com/MnJns.jpg

body:
The connection in that picture is pointless.  They are just putting power and ground on the top set of rails, but they aren't using it.

Your breadboard has only one rail on either side.  So you'll have to designate one for power and one for ground and you'll need some slightly longer wires for some of the connections.


message:
nRF24l01+ Outputting Garbage Values

I just purchased a set of 10 nRF24l01+ modules with a breakout board that looks like this:

[![nRF24l01+ module][1]][1]

Note: This is the nRF24l01+ chip, not a clone Si24Ri. Also, I'm using an Arduino Mega.

I'm following the Sparkfun tutorial here:
https://learn.sparkfun.com/tutorials/nrf24l01-transceiver-hookup-guide

The wires are hooked up like so:

- 3.3V → VCC
- GND → GND
- PWM 8 → IRQ
- PWM 9 → CE
- PWM 10 → CSN
- PWM 11 → MOSI
- PWM 12 → MISO
- PWM 13 → SCK

I've verified the two modules are hooked up as they should be. I'm using the *GettingStarted* example program for both units. Whenever I go into the serial monitor when connected to the transmitter, I get garbage values like `<¯�SžRÖ` being output. Whenever I try to transmit a message by entering `t`, nothing gets returned. The same problem is happening on the receiver end.

As for troubleshooting:

 - I've wiggled all of the jumper cables to verify a stable connection.
 - I've swapped out the modules I was using with others from the package (twice) so the modules probably aren't bad.
 - After reading that a capacitor is sometimes needed to provide a smoother voltage to the module, I upped the voltage from the 3.3V the Arduino was providing to a stable 3.5V from an external variable power supply to account for any small voltage dips. I don't have any capacitors available to me at the moment, so I figured this would be the next best option.

Unfortunately, my RF modules are still not correctly transmitting any data, and I don't know where to go from here.

  [1]: https://i.stack.imgur.com/sdHYa.jpg

body:
Check these things first:

 - Is your power supply give a constant 3.3V and a minimum of 0.5A(500mA)?
 - Does your code work for others?
 - Are you on the right serial baud rate?
 - Is the path from the radio to the Arduino as short as possible?
 - Are your MISO and MOSI wires twined into each other?

If none of these things help then, please tell me what library you are using. I had a lot of issues with the RF24 library so maybe try using the NRFLite library.


message:
Firmata: how to set a particular pin to high on boot?

I'm working on a project that use [J5][1], so is using the standard firmata, this project is using an opto 4 channel relay, when the board is booting the pins state are set to low, so as soon as I power the board my relay goes to a close state and make my motor run... this is a wrong behaviour for my purpose. How can I avoid that? By googleing around I stumble acros this:

[A possible solution][2]

but I can't uderstand if this is what I'm looking for.. plus I need only the PIN 7 to be set high on boot, any help please?

**EDIT: SCHEMATICS**

[4 Channel 5V Relay Module][3]

[![enter image description here][4]][4]

  [1]: http://johnny-five.io/
  [2]: https://github.com/firmata/arduino/blob/master/examples/StandardFirmata/StandardFirmata.ino#L290-L295
  [3]: http://wiki.sunfounder.cc/index.php?title=4_Channel_5V_Relay_Module
  [4]: https://i.stack.imgur.com/7zQwm.jpg

body:
It would seem you are right. If I understood the source correctly,
Firmata initializes all digital pins as OUTPUT LOW. Hard to believe, as
this seems like a silly thing to do... My understanding is that:

1. `setup()` calls `systemResetCallback()` in order to set the initial
   pin configuration ([line 779][])
2. `systemResetCallback()` loops over all pins and calls
   `setPinModeCallback(i, OUTPUT)` for every pin `i` that is not an
   analog pin ([line 732][])
3. `setPinModeCallback()` calls `pinMode()` to set the pin to OUTPUT
   ([line 325][]).

If my understanding is correct, then the simplest solution would seem to
patch `systemResetCallback()` and replace `OUTPUT` by `INPUT` on
line 732.

[line 779]: https://github.com/firmata/arduino/blob/master/examples/StandardFirmata/StandardFirmata.ino#L779
[line 732]: https://github.com/firmata/arduino/blob/master/examples/StandardFirmata/StandardFirmata.ino#L732
[line 325]: https://github.com/firmata/arduino/blob/master/examples/StandardFirmata/StandardFirmata.ino#L325


body:
Just put `digitalWrite(anyPin,HIGH)` in `void setup()` this will make that specific pin `HIGH` to reset. It works for me.

```
void setup()
{
  digitalWrite(8,HIGH);
  Firmata.setFirmwareVersion(FIRMATA_FIRMWARE_MAJOR_VERSION, FIRMATA_FIRMWARE_MINOR_VERSION);

  Firmata.attach(ANALOG_MESSAGE, analogWriteCallback);
  Firmata.attach(DIGITAL_MESSAGE, digitalWriteCallback);
  Firmata.attach(REPORT_ANALOG, reportAnalogCallback);
  Firmata.attach(REPORT_DIGITAL, reportDigitalCallback);
  Firmata.attach(SET_PIN_MODE, setPinModeCallback);
  Firmata.attach(SET_DIGITAL_PIN_VALUE, setPinValueCallback);
  Firmata.attach(START_SYSEX, sysexCallback);
  Firmata.attach(SYSTEM_RESET, systemResetCallback);

  // to use a port other than Serial, such as Serial1 on an Arduino Leonardo or Mega,
  // Call begin(baud) on the alternate serial port and pass it to Firmata to begin like this:
  // Serial1.begin(57600);
  // Firmata.begin(Serial1);
  // However do not do this if you are using SERIAL_MESSAGE

  Firmata.begin(57600);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for ATmega32u4-based boards and Arduino 101
  }

  systemResetCallback();  // reset to default config
}
```


message:
Problem regarding getting split data of JSON - Another issue

In my recent project, I'm working with Arduino and JSON. I've successfully split the JSON data I want. My JSON data length is fixed. So, I used the `length()` function and I'm getting the length of my data.

Now, my input JSON data is:

    {"TPS":"0.40","MAP":"0.95","LOAD":"14"}

Using the `length()` function, its length is `39`.

But when I use an `if` statement like `if(len == 39)` and put my logic inside this, I'm not getting the split data. Below is my whole code.

Here, I'm displaying my data on LCD.

    #include<LiquidCrystal.h>

    LiquidCrystal lcd(12, 11, 7, 6, 5, 4);
    String data_TPS_Json = "";
    String data_MAP_Json = "";
    String data_LOAD_TM_Json = "";
    String response = "";
    bool begin = false;
    int counter = 0;
    int len = 0;
    char in;
    float TPS_Json;
    float MAP_Json;
    float LOAD_TM_Json;

    void setup() {
      Serial.begin(9600);
      lcd.begin(16, 2);
    }

    void loop() {
      while(Serial.available() || !begin) {
        in = Serial.read();
        if (in == '{') {
          begin = true;
        }
        if(begin) {
          counter++;
          response += (in);
          len = response.length();
          if(len == 39) {
            if(counter >= 9 && counter <= 12) {
              data_TPS_Json += (in);
            }
            if(counter >= 22 && counter <= 25) {
              data_MAP_Json += (in);
            }
            if(counter >= 36 && counter <= 37) {
              data_LOAD_TM_Json += (in);
            }
          }
        }

        if(in == '}') {
          break;
        }
        delay(1);
      }
      TPS_Json = data_TPS_Json.toFloat();
      MAP_Json = data_MAP_Json.toFloat();
      LOAD_TM_Json = data_LOAD_TM_Json.toFloat();
      lcd.setCursor(0, 0);
      lcd.print(TPS_Json);
      lcd.setCursor(8, 0);
      lcd.print(MAP_Json);
      lcd.setCursor(0, 1);
      lcd.print(LOAD_TM_Json);
    }

body:
I don't think your loop handles the situation where the data comes in too slowly. Looking at your `while` condition:

    while(Serial.available() || !begin)

Once you receive the start char, this becomes:

    while(Serial.available())

Now, if there is a delay in the serial buffer, the loop exits before you have the entire message.

You should change the loop so it only ends when you have all 39 chars.

    void loop() {
        while (39 != response.length()) {  // Keep going until full msg {
            // Check for data in serial buffer
            if (Serial.available()) {
                in = Serial.read();
                .....
            }
            // No data?
            else {
                delay(10);
            }
        }

        TPS_Json = data_TPS_Json.toFloat();
        MAP_Json = data_MAP_Json.toFloat();
        .....
    }


body:
Finally, I got the solution. Using `substring()` function, I can able to split my data.

Here, suppose I have two input data with fixed length.

    {"TPS":"0.40","MAP":"0.95","LOAD":"14"}

    {"LOAD":"2.40","RPM":"4200","INJECTION_TIME":"4.87"}

So, using `length()` function I got the length of both data. So, I can able to differentiate the different data. In my previous code, I use counter and according to counter index I split my data. But somehow it does not work. So, after using `substring()` function I got the same result even better.

And below is my whole arduino code:

    #include<LiquidCrystal.h>

    LiquidCrystal lcd(12, 11, 7, 6, 5, 4);

    String data_TPS_Json = "";
    String data_MAP_Json = "";
    String data_LOAD_TM_Json = "";

    String data_LOAD_RI_Json = "";
    String data_RPM_Json = "";
    String data_INJECTION_TIME_Json = "";

    String response = "";
    bool begin = false;

    char in;
    int len = 0;

    float TPS_Json;
    float MAP_Json;
    float LOAD_TM_Json;

    float LOAD_RI_Json;
    float RPM_Json;
    float INJECTION_TIME_Json;

    void setup()
    {
      Serial.begin(9600);
      lcd.begin(16, 2);
    }

    void loop()
    {
      while(Serial.available() || !begin)
      {
          in = Serial.read();

          if (in == '{')
          {
            begin = true;
          }

          if(begin)
          {
            response += (in);
          }

          if(in == '}')
          {
            break;
          }

          delay(1);
      }

      len = response.length();

      if(len == 39)
      {
        data_TPS_Json = response.substring(8, 12);
        data_MAP_Json = response.substring(21, 25);
        data_LOAD_TM_Json = response.substring(35, 37);

        jsonMapTps();
      }

      if(len == 52)
      {
        data_LOAD_RI_Json = response.substring(9, 13);
        data_RPM_Json = response.substring(22, 26);
        data_INJECTION_TIME_Json = response.substring(46, 50);

        jsonRpmLoad();
      }
    }

    void jsonMapTps()
    {
        TPS_Json = data_TPS_Json.toFloat();
        MAP_Json = data_MAP_Json.toFloat();
        LOAD_TM_Json = data_LOAD_TM_Json.toFloat();

        lcd.setCursor(0, 0);
        lcd.print(TPS_Json);
        lcd.setCursor(8, 0);
        lcd.print(MAP_Json);
        lcd.setCursor(0, 1);
        lcd.print(LOAD_TM_Json);
    }

    void jsonRpmLoad()
    {
        LOAD_RI_Json = data_LOAD_RI_Json.toFloat();
        RPM_Json = data_RPM_Json.toFloat();
        INJECTION_TIME_Json = data_INJECTION_TIME_Json.toFloat();

        lcd.setCursor(0, 0);
        lcd.print(LOAD_RI_Json);
        lcd.setCursor(8, 0);
        lcd.print(RPM_Json);
        lcd.setCursor(0, 1);
        lcd.print(INJECTION_TIME_Json);
    }


message:
Advanced I/O shifting bits

I wanted to tinker around more with the 8-bit shift register (74HC595) so I tried to make a simple LED display and after reading about some shift commands I got lost and didn't understand much...

Let's start simple...

from what I read -- you can send out Binary data 1s and 0s --- **does the shift regsiter read it as on and off?** the shift register I'm using which is probably the same thing with others but it has 8 pins that can be used as output --- **how does it output the data?** --- does it output (example) 10100110 which shifts to the right as if `00000000 -> 10000000 -> 11000000 -> 01100000 -> 00110000 -> 10011000 -> 0100110 -> 10100110` through the pins one by one? **like pin 1 would get *0* first then *0* will move to pin 2 and pin 1 will get a *1*?** (still using 10100110 by example above ^ )

Also what would the code look like? how does `shiftOut()` and `shiftIn()` work exactly? does all of this have something to do with `pulseIn()`? what do the bitwise operators like `>>` and `<<` or `~` to name a few exactly do?

let's say I made 8 leds hooked up to one of each output pin of the shift-register --- **how do I give data to the register?** what commands should I use to give data? --- from what I understood I can output `01011011` right? if so, **how does the shift-register output it?** and if (Assumingly) it does output it like on and off would it *eventually* turn out as if `LED1 = OFF` `LED2 = ON` `LED3 = OFF` `LED4 = ON` `LED5 = ON` `LED6 = OFF` `LED7 = ON` `LED8 = ON` as if I entered in `01011011`?

***tl;dr***

***how do 8-bit shift registers work and how do you make codes work with them*** xP

body:
For the 74HC595 in combination with the Arduino, the best way to check is to use the default example by Arduino:

[ShiftOut][1]

  [1]: https://www.arduino.cc/en/Tutorial/ShiftOut

With the ShiftOut you can shift the bits into the IC which will make the correct LEDs light up (or not).

Probably you can lit up a LED when passing a HIGH, but you will know very easily by trying the example and check some values/for loops to make them dynamically lighting.

Probably after playing with the example, it will give you much more insight than describing the details here.

Update:

- Try first with 00000000 and 11111111 and 8 leds, so you know if 0 will be OFF and 1 will be ON.
- Than try with eg 10101010 and 8 leds ... than you know if the first or the last will be on or off.
- pulseIn is unrelated
- The operators >> and << are so called bit shift operators. Like 1 << 3 gives 8, the binary value 0000001 is shifted 3 bits left resulting in 00001000 which has value 8.
- ~ is the not operator -> which reverses bits.
- The shiftOut function can be used to send data to the 74HC595N.
- And to be honest, how does it work ... does it really matter for now? First see what the result is, how to use it. Later you can get into details. Start simple first.


message:
Arduino + L9637 K-Line reader - 10400 baud on SoftwareSerial?

I know this question has been asked many times before in different flavours, but all of the previous questions I have found seem to pre-date the current SoftwareSerial library, which afaik now (unlike when the previous questions were asked) allows any baud rate to be set as it calculates the values for the timings.

So I currently have the L9637 monolithic bus driver connected to pins D0 and D1 of my Arduino Uno. I am trying to create an ECU reader to communicate with my car over the KW1281 protocol, and from testing I have discovered I need to do the 5 baud init and then communicate at 10,400 baud.

First off I want to say I have successfully managed to run the 5 baud init. Now, I realise the pins (D0 & D1) are capable of hardware serial, however when trying to use the hardware serial I couldn't get any connection to the car. I think it's because the hardware serial doesn't like the pin modes to be changed after setup - however this is required to perform the 5 baud init. So I have decided to use the SoftwareSerial library for the following 10,400 baud communication.

With this library I successfully receive three (incorrect) response bytes from the ECU when setting a baud rate of 9600, however the response bytes - despite being correct in the number of them (3) - are wrong in terms of their value and seem to just be zero values.

Now as my car requires 10,400 baud communication, I instead setup the serial port to 10,400 baud. I know from experience that using 9600 baud will give incorrect response bytes and 10400 baud solves this. So I expected this would work and solve my problem, however it didn't. I still get 3 bytes containing 0. Just to be clear the three correct values should be: 55 01 8A

So I was wondering:

1. Am I right in assuming the SoftwareSerial library will work for any baud rate, even 10,400?
2. If yes to point 1, can anyone suggest why I might be getting data bytes containing 0 instead of the correct values?

As the full code is too long to post, the code for setting up the UART at 10,400, and then receiving the bytes is as follows:

    #include <Wire.h>
    #include <SoftwareSerial.h>

    SoftwareSerial obd(pinKLineRX, pinKLineTX, false); // RX, TX, inverse logic
    obd.begin(baudrate);

    uint8_t data = 0;
    int recvcount = 0;
    char s[3];

    while (obd.available())
    {
       uint8_t data = obd.read();
       s[recvcount] = data;
       recvcount++;
    }

And then to print the data I do the following:

    #include <Adafruit_GFX.h>
    #include <UTFTGLUE.h>

    UTFTGLUE lcd(0x9488,A2,A1,A3,A4,A0);

    char textout[30];
    int xVal = 50;
    cursorY = 10;
    for (int i=0; i < size; i++)
    {
      uint8_t data = s[i];

      sprintf(textout, "%i ", data);
      lcd.print(textout, xVal, cursorY);
      xVal += 10;
    }

    cursorY += 10;

The output on the LCD is

> 0 0 0

When it should be

> 55 01 8A

body:
I've found 9600 baud to be the receive limit among _standard_ baud rates (transmission can go faster). You're proposing an 8% increase over 9600 which sounds like it has a good chance of working but you'll need to experiment to find out.

You also asked why might your data (on the LCD) be wrong.

You'll do your sanity a big favor and do two separate experiments:

 - First, get known data (literal strings or terminal input) to display correctly on your LCD, before you try to use the LCD to confirm or debug your communications.

 - Second, get SoftwareSerial running (or find out that it doesn't...) at 10400 baud. In fact try to get up to, say, 12000 baud, or at least push the rate to find out where it starts to fail so you know how much head-room you'll have at 10,400. The simplest way would be to use two Arduinos if you have access to another one. Again, use your terminal or some literal strings on MCU 'A' to send to MCU 'B', MCU 'B' should receive a line and echo it back to 'A', who prints it on its terminal. Printing it on 'B's terminal wouldn't be a bad idea either.

You'll be in a lot better position to combine the two techniques once you have confidence that each one works; especially if you copy-and-paste known-working code segments.


body:
I tried using MIDI data with the software library. However, I also got problems with missing and/or corrupted messages. MIDI has a fixed baudrate of 31,250 baud. As long as I did not sent too much, everything was ok, but sending continuous messages (within the 31,250 baud rate spec) I got into problems. It seems that the input buffer was too full and/or no time to process them.

The default buffer for the serial (software serial) buffer was 64 bytes. I increased it to 128, but saw no difference. Making the buffer higher probably just would delay the time until messages are corrupted.

What you can do is:

- Use a non Arduino device with multiple UARTs (no experience with that)
- There seems to exists a 328PB version of the Uno which has two UARTs (but it maybe a kind of niche device, possibly with support problems)
- What I did was using a Mega, it has 4 UARTs.
- Using multiple Uno's and/or Mega's connected to eachother, giving 1 resp. 4 UARTs


message:
Servomotor and music shield

I’m trying to make an art sculpture, with an Arduino-uno, a servomotor and a seeduino musicshield v2.0.
I’m making the servo motor moving a stick with the attached fans of the servo, and I want to  synchronize the servo motor with the music shield  and when the motor is stopped(about one minute), the music(about one minute of music) will play and when de motor is moving the music will be stopped.

I'm super noobie with the code. I tried something like this
but, is not moving at all, neither my servo or my musicshield  when I write this:

    #include <SD.h>
    #include <SPI.h>
    #include <arduino.h>
    #include <MusicPlayer.h>

    #include <Servo.h>
    Servo myservo;

    int val;//for the servo

    void setup() {
      //setup for the music shield
      Serial.begin(9600);
      player.begin();  //will initialize the hardware and set default mode to be normal.
      player.addToPlaylist("a.mp3");
      //setup for the servo
       myservo.attach( 9 );
    }
    void loop() {
      mover();
      if ( val == 90) {
        music();
      }
    }

    void mover () {
      val = 0;// start point
      myservo.write(val);
      delay(800);

      val = 90;
      myservo.write(val);
      delay(60000);//wait for 1 min
    }

    void music () {

      player.play();
    }

when I write this my servo moves, but obviously my music wouldn't play

    #include <SD.h>
    #include <SPI.h>
    #include <arduino.h>
    #include <MusicPlayer.h>

    #include <Servo.h>
    Servo myservo;

    int val;//for the servo

    void setup() {
      //setup for the music shield
     Serial.begin(9600);
      player.begin();  //will initialize the hardware and set default mode to be normal.
      player.addToPlaylist("a.mp3");
      //setup for the servo
       myservo.attach( 9 );
     }

    void loop() {
    mover();

     }

     void mover () {
    val = 0;// start point
    myservo.write(val);
    delay(800);

    val = 90;//
    myservo.write(val);
    delay(60000);//wait for 1 min
    }

    void music () {

      player.play();  //do some leisurely job
    }

And the music will play when I write this, obviously the servomotor don't move, so I'm  think I have a problem mixing my servomotor and the musicshield(seeeduino music shield v2.0, and I want the music start when my servo motor is in this point of val=90 delay(60000)

     #include <SD.h>
        #include <SPI.h>
        #include <arduino.h>
        #include <MusicPlayer.h>

        #include <Servo.h>
        Servo myservo;

        int val;//for the servo

        void setup() {
          //setup for the music shield
         Serial.begin(9600);
          player.begin();  //will initialize the hardware and set default mode to be normal.
          player.addToPlaylist("a.mp3");
          //setup for the servo
           myservo.attach( 9 );
          }

        void loop() {

       player.play();
         }

        void mover () {
        val = 0;// start point
        myservo.write(val);
        delay(800);

        val = 90;//
        myservo.write(val);
        delay(60000);//wait for 1 min
        }

body:
Is this the MusicPlayer.h that you have?  [https://github.com/Seeed-Studio/Music_Shield][1]

From the description it says:

> The music player reads data from SD card and then feed into the VS1053 chip via SPI bus. This is done in TIMER1's ISR with a interval of 2ms. This job has a high priority and uses the cpu exclusively. In the spare cpu time, player does some process control, like play/pause.

That's the same timer that Servo.h uses.  So the two libraries are not compatible.  You could try using ServoTimer2 library or rewriting this library to get the 2ms timer with Timer 2.

  [1]: https://github.com/Seeed-Studio/Music_Shield


message:
What is the purpose of the I/O pin capacitor on the AVR microcontroller?

What is the purpose of the capacitor on the I/O pins on the ATmega328 (I imagine it's on other AVR microcontrollers as well)? Is it to reduce noise from other parts of the microcontroller?

[![i/o pin schematic][1]][1]

  [1]: https://i.stack.imgur.com/mIA54.png

body: To make explicit the implicit parasitic capacitance on the pin.


body:
The pin does not have a capacitor added to the integrated circuit (IC). Rather this capacitor is drawn to show that the input has capacitance that you need to be aware of.

The input drives a MOSFET - and as we know, MOSFETs have some parasitic capacitance.

For more information on parasitic capacitance of MOSFETs see these pages:

 - [MOS Transistor parasitic capacitances - OnMyPHD.com][1]
 - [MOSFET Parasitic Capacitance and Its Temperature Characteristic - ROHM][2]

  [1]: http://www.onmyphd.com/?p=mosfet.parasitic
  [2]: https://techweb.rohm.com/knowledge/si/s-si/03-s-si/4873


message:
Can i create a function inside of void setup()?

Can i create a function inside of void setup()
to recall in loop() function

body:
No. You do not create functions within functions.

You can create a function, and then call it both from `setup()` and `loop()` if you so wish.


body:
You can create functions within a function if the particular c compiler supports it - gcc, the compiler used by arduino,  does. But not all c compilers support that.

Whether you can create a function within a function that recalls loop() depends on your meaning of "recall".


body:
Defining a function within a function is not supported in C or C++. If it were supported in a way consistent with the rest of the language, the inner function would be local to the outer function, just as local variables are, so not callable or even visible from outside the outer function.

Your loop() function (or any other function) could, however, call the setup() function as long as you want to execute setup() again in its entirety. That means that any initialization you perform in setup() would be repeated each time you call it.


body:
You have asked two questions here.  In the title, can you define a function inside of setup():  Yes.

But that is the "scope" of where it can be used.

In Loop() it won't exist, ("xxx undefined in this scope") so the answer to what you ask in the text is No.


message:
Connecting an Arduino Nano, Mega and LCD via I2C works but fails when shutting down Mega

I have connected an Arduino Nano, Mega and a LCD via I2C/TWI (SDA/SCL).

The Nano is playing the master while Arduino Mega and LCD are slaves. This works well till I power off the Arduino Mega. Of cause I don't expect the Mega to answer.

In particular the SCL line seems to pull-down the connection. Disconnecting SCL from the Mega will reestablish the connection to the LCD. I added two pull-up resistors 4.7k to both SDA SCL but no improvement from that.

Is there no way than physically disconnecting the lines?

body:
See
https://arduino.stackexchange.com/questions/31924/how-to-setup-an-i2c-bus-which-stays-valid-if-a-slave-is-powered-down-or-fails

Basically I2C uses pull-ups to have all lines HIGH until any device bring it LOW. Arduino uses INPUT_PULLUP / OUTPUT+LOW states for this. But if you switch Arduino off (turn off Vcc), internal diodes cut the power on pins to Vcc (which is zero) +diode voltage (which is small), effectively to logical LOW. And I2C see that as the device is activelly sending LOW all the time - so communication is blocked.

If you just add pullup resistors, you either have them high enought so it not prevent this state or you have them low enought to draw the lines HIGH even when there is LOW on device, which prevents other devices to draw them LOW for communication. You need "cut off" such incactive lines - either physically disconnect (pull wires from connector - such as if you just get the Mega out of socket, or use some relays powered from Mega Vcc, which disconnet them when the power goes out) or electrically disconnect - using some circuits designed for it. There are some already sold or you can create your own to the same efect (if you are skilled in this area - otherwise it is much easier and faster to pay for some already made solution)


body: There are I2C Multiplexers/Switches that you can use to disconnect automatically such as the PCA9540. I do not know if they are available on breakout boards.


message:
Switch setting 'running' state boolean doesn't hold

I have a rotary encoder and I want to use the switch to stop the rest of my code running, essentially switching off what I have going on.

I have this

    boolean running = true;

    void setup() {
      pinMode(swPin, INPUT);
      digitalWrite(swPin, HIGH);;
    }

    void loop() {

      if(digitalRead(swPin) == LOW) {
        running = !running;
      }

      if(running) {
        ...
      }
    }

When I enter the if statement catching the switch press running does become false and the rest of the code is stopped. However, once released; running is becoming true again and the rest starts again.

I guess it is because the rotary encoder isn't fixed in the LOW state but I expected the running variable to be set to false and remain since it is declared outside of the loop().

Any guidance would be much appreciated!!

body:
Thanks to @Manjenko's comment I was able to see my error.

Here is my solution:

    boolean running = true;
    int swReading;
    int swPrevious = LOW;

    void setup() {
      pinMode(swPin, INPUT);
      digitalWrite(swPin, HIGH);;
    }

    void loop() {

      swReading = digitalRead(swPin);

      if(swReading == LOW && swPrevious == HIGH) {
        running = !running;
      }
      swPrevious = swReading;

      if(running) {
        ...
      }
    }


message:
Can I include a header file into a new header file?

Can I include a header file into a new header file that I created? I put `#include <MCP23S17.h>`. I want to create a another header file.

body: Yes, a header can include another header.  But if you are using the Arduino IDE and the headers aren't in the same folder, then you'll also need an #include line for it in the .ino file.


body:
Why not just include both in the final program?

Happens all the time.

DHT.h needs AdaFruit_Sensor.h, for instance, so you just include both.

First AdaFruit
then DHT


message:
How to use variables and functions across multiple .ino files

I have 2 .ino files (2 tabs) for one Arduino project/sketch: MySketch_File1.ino and MySketch_File2.ino.

I declared in MySketch_File2 variables and functions which I want to use in MySketch_File1, but I get this error massage:

> error: 'a' was not declared in this scope

    //MySketch_File1.ino
    void setup(){
    Serial.begin(9600);
    Serial.println(String(a));
    }

    void loop(){

    }

Second file:

    //MySketch_File2.ino
    int a;

How can I declare variables and functions one time in one .ino file and use it across multiple .ino files?

body:
In Arduino the `sketch.ino` is the main (and only) program, which runs on the processor.

If you upload another sketch to HW, then the previous one is overwritten and does not longer exist on the HW. So there is no way, they can share variables, as they never are run at the same time.
(You can store some values to EEPROM or to external devices, but it is other thing).

What you probabely want to do is use the second file as a `library`, which is collection of variables and functions, that more then one program can use. Anyway what is used is the text of the library, not the values assigned to variables in one `sketch.ino` - so other `sketch.ino` using the same library would have the functions and variables of the same name accessible, but as it is compiled to othe program, the values assigned in one sketch would not be visible in other sketch.

Can you specify, why you want to use variables and functions accross multiple .ino files?

If it is just to not have type it again and again and fix found bugs in each aned every copy separately, then you are looking for `libraries`.

If you want to share also values (like read and compute value in one .ino then upload another .ino and use the result) you are looking for `persistent storages` (EEPROM on the chip, SD card via some reader or something like that.

If you want have more Arduinos running at the same time and sharing some values, you are looking for `networks`, like I2C, Serial communication, Ethernet and such.

If you want run mor programs on one arduino at the same time, you are looking for `multitasking` where each program is interrupted repeatedly and other one is continued, fast enought to user not notice, or for creatinig more functions and call them from loop() one after one to eg. read sensors, then light LEDs then run motors. `State automats` can make your way here easier.


body:
When you compile multiple files in the Arduno IDE the files first get concatenated together.

It happens in alphabetical order, *except* the main INO file (the one named the same as the folder it's in) is placed first.

In C the order in which things appear in the file matters. Basically you have to make sure that things (like variables, functions, etc) are defined *before* they are used.

This gets more complex when you have a hidden thing like file concatenation messing things up.

The Arduino IDE tries to hide some of it from you too by making *function prototypes*, so it doesn't matter what order you define functions in - however that "helpfulness" means you don't learn about the proper structure of a C program.

So what can you do? Well, simply make sure that all your global variables are defined in the *main* file, unless you know they are only going to be used within the file they are defined in.


body:
Arduino ide has terrible project mgmt capabilities. So two solutions.

1. Switch to a real ide.
2. Use an extern atteibute.


body:
It is simplest to put only one .ino file in a directory with the filename. https://arduino.stackexchange.com/questions/32619/why-does-an-ino-file-have-to-be-in-a-folder-of-the-same-name

**Option 1 (cleanest option):** [Create a user library](https://www.arduino.cc/en/guide/libraries#toc5).

**Option 2  (workaround):** [Relative paths for #include aren't supported](https://forum.arduino.cc/index.php?topic=110950.0) but you can use a symlink to make it appear that there is the same header file in every directory:

    sketch1/
      sketch1.ino
      mylib.h
    sketch2/
      sketch2.ino
      mylib.h (this is a symlink to sketch1/mylib.h)

**Option 3:** Avoid Arduino IDE entirely and build using avr-gcc. Example: http://thinkingonthinking.com/an-arduino-sketch-from-scratch/ and https://arduino.stackexchange.com/questions/21492/will-a-ino-arduino-sketch-compile-directly-on-gcc-avr/21515 This is much more complicated, but supports bigger projects using Makefiles.


body: You can make this easier by naming only the main sketch file '.ino', and naming all other code files as '.cpp'. The compiler has to know about 'a' before you use it, so declare 'a' in the .ino file as `extern int a;' before its first use, to tell it what 'a' is. Not having that is the reason for the error message.


message:
Programming Arduino via ICSP

I'm trying to programming Arduino Nano with another Arduino Nano via ICSP. I have a 6-pin cable directly connected to the ICSP's pin of the second board:

    ICSP NANO ISP 1
    pin1 pin2 pin3
    pin4 pin5 pin6

    ICSP NANO 2 (to be programmed)
    pin1 pin2 pin3
    pin4 pin5 pin6

I have correspondingly wired pin 1 (ICSP) of nano1 to pin 1 (ICSP) Nano 2, pin 2 (ICSP) of nano 1 to pin 2 (ICSP) Nano 2, etc.

I make this step before flashing: getting the Arduino ISP with example sketch ArduinoISP, plug off the Arduino ISP and attach the 6-pin cable to the ICSP port of the second board, plug Arduino ISP to the USB port, in the *Tools* menu select *Arduino as ISP*, load with external programmer, and fail...

This is the log:

    avrdude: Version 6.3, compiled on Sep 12 2016 at 17:24:16
             Copyright (c) 2000-2005 Brian Dean, http://www.bdmicro.com/
             Copyright (c) 2007-2014 Joerg Wunsch

             System wide configuration file is "C:\Program Files (x86)\Arduino\hardware\tools\avr/etc/avrdude.conf"

             Using Port                    : COM12
             Using Programmer              : stk500v1
             Overriding Baud Rate          : 19200
             AVR Part                      : ATmega328P
             Chip Erase delay              : 9000 us
             PAGEL                         : PD7
             BS2                           : PC2
             RESET disposition             : dedicated
             RETRY pulse                   : SCK
             serial program mode           : yes
             parallel program mode         : yes
             Timeout                       : 200
             StabDelay                     : 100
             CmdexeDelay                   : 25
             SyncLoops                     : 32
             ByteDelay                     : 0
             PollIndex                     : 3
             PollValue                     : 0x53
             Memory Detail                 :

                                      Block Poll               Page                       Polled
               Memory Type Mode Delay Size  Indx Paged  Size   Size #Pages MinW  MaxW   ReadBack
               ----------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- ---------
               eeprom        65    20     4    0 no       1024    4      0  3600  3600 0xff 0xff
               flash         65     6   128    0 yes     32768  128    256  4500  4500 0xff 0xff
               lfuse          0     0     0    0 no          1    0      0  4500  4500 0x00 0x00
               hfuse          0     0     0    0 no          1    0      0  4500  4500 0x00 0x00
               efuse          0     0     0    0 no          1    0      0  4500  4500 0x00 0x00
               lock           0     0     0    0 no          1    0      0  4500  4500 0x00 0x00
               calibration    0     0     0    0 no          1    0      0     0     0 0x00 0x00
               signature      0     0     0    0 no          3    0      0     0     0 0x00 0x00

             Programmer Type : STK500
             Description     : Atmel STK500 Version 1.x firmware
             Hardware Version: 2
             Firmware Version: 1.18
             Topcard         : Unknown
             Vtarget         : 0.0 V
             Varef           : 0.0 V
             Oscillator      : Off
             SCK period      : 0.1 us

    avrdude: AVR device initialized and ready to accept instructions

    Reading | ################################################## | 100% 0.02s

    avrdude: Device signature = 0x000000 (retrying)

    Reading | ################################################## | 100% 0.02s

    avrdude: Device signature = 0x000000 (retrying)

    Errore durante il caricamento dello sketch
    Reading | ################################################## | 100% 0.02s

    avrdude: Device signature = 0x000000
    avrdude: Yikes!  Invalid device signature.
             Double check connections and try again, or use -F to override
             this check.

    avrdude done.  Thank you.

body:
I suggest you to try and read the [Arduino page][1] about ArduinoISP.

Particularly, you will notice that pins 11, 12, 13 and Vcc and GND are all common, BUT the reset pin is not common to both boards. So I suggest you to detach the pin 5 of ICSP from the ArduinoISP board and connect it to its pin 10. Or, if you prefer, connect

    ISP - Target
    +5V - +5V
    GND - GND
    11  - 11
    12  - 12
    13  - 13
    10  - RST

Then try again

  [1]: https://www.arduino.cc/en/Tutorial/ArduinoISP


message:
Read only selected Packet SoftwareSerial

I am reading data from RS485 which is in the following format:

<!-- language: lang-c -->

    void sendkwh()
    {
      RS485Serial.write((byte)0x01); // Meter Address
      RS485Serial.write((byte)0x03); // Read Function Code
      RS485Serial.write((byte)0x40); // Register Address Variable (Start address high bit)
      RS485Serial.write((byte)0x34); // Register Address Variable (Start address low bit)
      RS485Serial.write((byte)0x00); // Register Quantity (High Bit)
      RS485Serial.write((byte)0x02); // Register Quantity (Low Bit)
      RS485Serial.write((byte)0x90); // CRC check code (CRC code Low bit)
      RS485Serial.write((byte)0x05); // CRC check code (CRC code High bit)
    }

and I need to read only the 4th and 5th frame of the packet. I am doing it the following way:

<!-- language: lang-c -->

    RS485Serial.listen();
      if (RS485Serial.available() > 0)
       {

        if(RS485Serial.read() == 0x01)
        {
        for(int i=0; i<4; i++) {

       byte discard = RS485Serial.read();

       }
        byteReceived = RS485Serial.read(); // 4th frame
        byteReceived2 = RS485Serial.read(); // 5th frame

which is working fine. I wanted to know if there is a method to discard the packets without loop?

As in I have changed the `sendkwh()` as below:

<!-- language: lang-c -->

    byte SendKWh[] = { 0x01, 0x03, 0x40, 0x34, 0x00, 0x02, 0x90, 0x05 };
    RS485Serial.write(SendKWh, sizeof(SendKWh));

But don't know how to proceed with tapping the 4th and the 5th frame. Your help is appreciated.

body:
Your reading methodology is flawed from the start and you need to completely change how you do things.  First off, you wait until there is *at least* one byte in the incoming buffer, then if that byte is `0x01` you then try and read 5 more bytes - even if there is only (say) 2 bytes in the buffer.

Instead you need to set up a *sliding window* for receiving the data. A sliding window is basically an array that is the same size as the data you are receiving, and as bytes become available they work their way down from the "top" to the "bottom" of the array. When the contents of the array match a certain pattern you know it is a "good" packet and you can use the data form it.

For example, you may have something like:

<!-- language: lang-c -->

    uint8_t window[8];

    void loop() {
        if (RS485Serial.available()) {
            uint8_t b = RS485Serial.read();
            // Slide the contents of the array down
            for (uint8_t i = 0; i < 7; i++) {
                window[i] = window[i+1];
            }
            // Insert at the top
            window[7] = b;

            // If the array starts with 0x01,0x03,0x40,0x34...
            if ((window[0] == 0x01) && (window[1] == 0x03) &&
                (window[2] == 0x40) && (window[3] == 0x34)) {
                // Do something with window[4] and window[5]
            }
        }
    }

You could also add checking the CRC to that by comparing the calculated CRC for the incoming packet (however that is done in this protocol) with the last two bytes of the array.


message:
Pass changing analog value from void loop to library .h file

How would I go about passing a void loop analog read value to a library .h file?
I've tried it but it only reads the pot position as soon as I plug the arduino in and does not change once booted up.

arduino main sketch file code;

    #include "Arduino.h"
    #include "common.h"
    #include "synth.h"
    #include "serial-in.h"
    #include "audio-out.h"

    void setup() {
      Synth<0>::initialize();
      SerialIn<0>::open();
      AudioOut<0>::open();
    }

    void loop() {
      int val = analogRead(A0);
      int val1 = analogRead(A1);
      int val2 = analogRead(A2);
      int val3 = analogRead(A3);
      int val4 = analogRead(A4);
      while (true) {
        if (SerialIn<0>::available()) {
          uint8_t b = SerialIn<0>::read();
          Synth<0>::receive_midi_byte(b);
        }

        int8_t level = Synth<0>::clock();
        AudioOut<0>::write(level);
      }
    }

.h file code

    #pragma once

    // #define private public  // for tests

    #include "common.h"

    // associations of units
    #define IOsc        Osc
    #define IFilter     Filter
    #define IAmp        Amp
    #define IEG         EG
    #define IVoice      Voice
    #define ISynthCore  SynthCore

    #include "osc.h"
    #include "filter.h"
    #include "amp.h"
    #include "eg.h"
    #include "voice.h"
    #include "synth-core.h"

    template <uint8_t T>
    class Synth {
    public:
      INLINE static void initialize() {
        ISynthCore<0>::initialize();
        int val = analogRead(A0);
        int val1 = analogRead(A1);
        int val2 = analogRead(A2);
        int val3 = analogRead(A3);
        int val4 = analogRead(A4);
        // Preset
        ISynthCore<0>::control_change(OSC_MODE      , 0  );
        ISynthCore<0>::control_change(OSC_COLOR     , val);
        ISynthCore<0>::control_change(MOD_RATE      , 8  );
        ISynthCore<0>::control_change(MOD_DEPTH     , val1);
        ISynthCore<0>::control_change(LPF_CUTOFF_ENV, val2);
        ISynthCore<0>::control_change(LPF_RESONANCE , val3);
        ISynthCore<0>::control_change(ENV_A         , val4 );
        ISynthCore<0>::control_change(ENV_D_R       , 1 );
      }

      INLINE static void receive_midi_byte(uint8_t b) {
        ISynthCore<0>::receive_midi_byte(b);
      }

      INLINE static int8_t clock() {
        return ISynthCore<0>::clock();
      }
    };

body:
First of all, the `while(true)` loop in the `loop` function is wrong. You will need to put in the `loop` only the code which needs to be repeatedly called. So

    void loop() {
      if (SerialIn<0>::available()) {
        uint8_t b = SerialIn<0>::read();
        Synth<0>::receive_midi_byte(b);
      }

      int8_t level = Synth<0>::clock();
      AudioOut<0>::write(level);
    }

Then, I haven't understood where the analog read values are used. Moreover the fact that in the initialization you read the analog values and in the loop you expect them to be passed is inconsistent. From what I read, the values should be passed to `control_change`; you can do one of these things, in my opinion:

1) manage the analog reading from the main:

    void setup() {
     Synth<0>::initialize(analogRead(A0), analogRead(A1), analogRead(A2), analogRead(A3), analogRead(A4));
     SerialIn<0>::open();
     AudioOut<0>::open();
    }

    void loop() {
     Synth<0>::change_OSC_COLOR(analogRead(A0));
     Synth<0>::change_MOD_DEPTH(analogRead(A1));
     ...

     if (SerialIn<0>::available()) {
      uint8_t b = SerialIn<0>::read();
      Synth<0>::receive_midi_byte(b);
     }

     int8_t level = Synth<0>::clock();
     AudioOut<0>::write(level);
    }

    // in h file

    INLINE static void initialize(int val, int val1, int val2, int val3, int val4) {
     ISynthCore<0>::initialize();

     change_OSC_MODE(0);
     change_OSC_COLOR(val);
     change_MOD_RATE(8);
     change_MOD_DEPTH(val1);
     change_LPF_CUTOFF_ENV(val2);
     change_LPF_RESONANCE(val3);
     change_ENV_A(val4);
     change_ENV_D_R(1);
    }

    INLINE static void change_OSC_MODE(int value) {
     ISynthCore<0>::control_change(OSC_MODE, value);
    }

    INLINE static void change_OSC_COLOR(int value) {
     ISynthCore<0>::control_change(OSC_COLOR, value);
    }

    INLINE static void change_MOD_RATE(int value) {
     ISynthCore<0>::control_change(MOD_RATE, value);
    }

    ...

or, alternatively,

    ...
    void loop() {
     Synth<0>::change_param(OSC_COLOR, analogRead(A0));
     Synth<0>::change_param(MOD_DEPTH, analogRead(A1));
     ...

    }

    // in h file

    INLINE static void initialize(int val, int val1, int val2, int val3, int val4) {
     ISynthCore<0>::initialize();

     change_param(OSC_MODE, 0);
     change_param(OSC_COLOR, val);
     ...
    }

    INLINE static void change_param(uint8_t param, int value) {
     ISynthCore<0>::control_change(param, value);
    }

(I prefer the firsti since you can prevent the user from using some parameters)

2) manage the analog reading from the library:

    void setup() {
     Synth<0>::initialize();
     SerialIn<0>::open();
     AudioOut<0>::open();
    }

    void loop() {
     Synth<0>::updateAnalog();

     if (SerialIn<0>::available()) {
      uint8_t b = SerialIn<0>::read();
      Synth<0>::receive_midi_byte(b);
     }

     int8_t level = Synth<0>::clock();
     AudioOut<0>::write(level);
    }

    // in h file
    INLINE static void initialize() {
     ISynthCore<0>::initialize();
     updateAnalog();
    }

    INLINE static void updateAnalog() {
     int val = analogRead(A0);
     int val1 = analogRead(A1);
     int val2 = analogRead(A2);
     int val3 = analogRead(A3);
     int val4 = analogRead(A4);
     ISynthCore<0>::control_change(OSC_MODE      , 0  );
     ISynthCore<0>::control_change(OSC_COLOR     , val);
     ISynthCore<0>::control_change(MOD_RATE      , 8  );
     ISynthCore<0>::control_change(MOD_DEPTH     , val1);
     ISynthCore<0>::control_change(LPF_CUTOFF_ENV, val2);
     ISynthCore<0>::control_change(LPF_RESONANCE , val3);
     ISynthCore<0>::control_change(ENV_A         , val4 );
     ISynthCore<0>::control_change(ENV_D_R       , 1 );
    }

Each method has advantages or disadvantages... You should pick the one more suitable for you


body:
> How would I go about passing a void loop analog read value to a library .h file?

What you wanted to do makes little sense. But it is certainly doable. The simplest would be to use an "extern" variable as a bridge.


message:
Decoupling cap for self-powered LED matrix and LED strip

Should I add a decoupling capacitor to [my RGB 16x32 LED matrix powered directly via the 5V pin][1]?

When I display a spectrogram, the current load is fluctuating quickly in the **100-250 mA** range (on average, the full range is 50-300 mA).

If yes, which capacitor should I pick for this purpose?

I have 0.01 μF, 0.1 μF ceramic and 1 μF, 2.2 μF, 4.7 μF, 10 μF, 100 μF electrolytic caps.

EDIT: I'm also interested to know about [this WS2812B LED strip][2] i've connected to the 5 V pin to another Arduino.

After reducing the brightness it has similar current consumption and fluctuation of the LED matrix.

In [this tutorial they suggest to add a 1000 μF cap][3], but in my case the currents are much smaller.

  [1]: https://arduino.stackexchange.com/questions/36094/directly-powering-a-single-32x16-rgb-led-matrix-without-external-psu
  [2]: https://www.aliexpress.com/item/WS2812B-5050-RGB-LED-Flexible-Strip-1M-5M-30-60-144-150-300LED-Waterproof-Non-Waterproof/32800442714.html
  [3]: https://learn.sparkfun.com/tutorials/ws2812-breakout-hookup-guide

body: No, there is no need. The matrix already has plenty of decoupling on it, including a large electrolytic for the incoming power and a small ceramic on each of the chips.


message:
After update via ICSP can't use usb for Serial Reading and Usb for programming board

after update software on my arduino Nano board via ICSP i can't use USB for serial monitor and update software, why?

body:
Assuming you have reprogrammed the Arduino Nano's Atmel processor (an ATmega328) directly using the processor's ICSP pins, you may have erased the [Arduino boot loader][1] from the processor.  In such a case you no longer have an Arduino.  Rather you have an ATmega328 processor surrounded by some hardware.

To recover you need to [reprogram the ATmega328 processor with the Arduino boot loader][2].

  [1]: https://www.arduino.cc/en/hacking/bootloader
  [2]: https://www.arduino.cc/en/Tutorial/ArduinoToBreadboard


message:
Problem with measuring vibrations (Arduino UNO + step motor + accelerometer)

I'm trying to measure vibrations of the motor's shaft that is oscillating due to an eccentric load. For that, I am using the MPU 6050 6 axis accelerometer. The motor is a NEMA 17 stepper, connected to Arduino UNO via EasyDriver v4.4.
I first uploaded my code for the stepper, where I have 2 buttons to control the rotation direction (if you press the left, it goes clockwise and if you press the right button it goes counter clockwise). This code works fine.
Later I uploaded the code only for the accelerometer and it worked fine, however when I'm trying to combine both so that the vibrations could be measured while the motor is running, apparently, I'm losing steps of the motor. Here is the code:

    #include<Wire.h>
    const int MPU_addr = 0x68; // I2C address of the MPU-6050
    int16_t AcX, AcY, AcZ, Tmp, GyX, GyY, GyZ;

    #define RPMS                300.0
    #define STEP_PIN                9
    #define DIRECTION_PIN           8
    #define GO_PIN_L                3
    #define GO_PIN_R                4

    #define STEPS_PER_REV         200
    #define MICROSTEPS_PER_STEP     8
    #define MICROSECONDS_PER_MICROSTEP   (1000000/(STEPS_PER_REV *
    MICROSTEPS_PER_STEP)/(RPMS / 60))

    uint32_t LastStepTime = 0;
    uint32_t CurrentTime = 0;

    int Distance = 0;

    void setup() {
      Wire.begin();
      Wire.beginTransmission(MPU_addr);
      Wire.write(0x6B);  // PWR_MGMT_1 register
      Wire.write(0);     // set to zero (wakes up the MPU-6050)
      Wire.endTransmission(true);
      Serial.begin(9600);

      pinMode(STEP_PIN, OUTPUT);
      pinMode(DIRECTION_PIN, OUTPUT);
      digitalWrite(STEP_PIN, LOW);
      digitalWrite(DIRECTION_PIN, LOW);
      pinMode(GO_PIN_L, INPUT);
      pinMode(GO_PIN_R, INPUT);
    }

    void loop() {
      Distance = Distance + 1;   // record this step
      if (digitalRead(GO_PIN_L) == LOW)
      {
        CurrentTime = micros();
        digitalWrite(8, LOW);
        if ((CurrentTime - LastStepTime) > MICROSECONDS_PER_MICROSTEP)
        {
          LastStepTime = CurrentTime;
          digitalWrite(STEP_PIN, HIGH);
          delayMicroseconds((MICROSECONDS_PER_MICROSTEP * 0.9) / 2);
          digitalWrite(STEP_PIN, LOW);
          delayMicroseconds((MICROSECONDS_PER_MICROSTEP * 0.9) / 2);
        }
      }
      if (digitalRead(GO_PIN_R) == LOW)
      {
        CurrentTime = micros();
        digitalWrite(8, HIGH);
        if ((CurrentTime - LastStepTime) > MICROSECONDS_PER_MICROSTEP)
        {
           LastStepTime = CurrentTime;
          digitalWrite(STEP_PIN, HIGH);
          delayMicroseconds((MICROSECONDS_PER_MICROSTEP * 0.9) / 2);
          digitalWrite(STEP_PIN, LOW);
          delayMicroseconds((MICROSECONDS_PER_MICROSTEP * 0.9) / 2);
        }
      }
    //  Wire.beginTransmission(MPU_addr);
    //  Wire.write(0x3B);  // starting with register 0x3B (ACCEL_XOUT_H)
    //  Wire.endTransmission(false);
    //  Wire.requestFrom(MPU_addr, 14, true); // request a total of 14 registers
    //  float AcX = Wire.read() << 8 | Wire.read(); // 0x3B (ACCEL_XOUT_H) & 0x3C (ACCEL_XOUT_L)
    //  float AcY = Wire.read() << 8 | Wire.read(); // 0x3D (ACCEL_YOUT_H) & 0x3E (ACCEL_YOUT_L)
    //  float AcZ = Wire.read() << 8 | Wire.read(); // 0x3F (ACCEL_ZOUT_H) & 0x40 (ACCEL_ZOUT_L)
    //  Tmp = Wire.read() << 8 | Wire.read(); // 0x41 (TEMP_OUT_H) & 0x42 (TEMP_OUT_L)
    //  // GyX=Wire.read()<<8|Wire.read();  // 0x43 (GYRO_XOUT_H) & 0x44 (GYRO_XOUT_L)
    //  // GyY=Wire.read()<<8|Wire.read();  // 0x45 (GYRO_YOUT_H) & 0x46 (GYRO_YOUT_L)
    //  // GyZ=Wire.read()<<8|Wire.read();  // 0x47 (GYRO_ZOUT_H) & 0x48 (GYRO_ZOUT_L)
    //  Serial.print("AcX = "); Serial.println(AcX / 16384);
    //  Serial.print(" AcY = "); Serial.println(AcY / 16384);
    //  Serial.print(" AcZ = "); Serial.println(AcZ / 16384);
    //  Serial.print(" Tmp = "); Serial.print(Tmp / 340.00 + 36.53);
    //  Serial.println("");
    //  // Serial.print(" | GyX = "); Serial.print(GyX);
    //  // Serial.print(" | GyY = "); Serial.print(GyY);
    //  // Serial.print(" | GyZ = "); Serial.println(GyZ);
    //  delay(333);
    }

So the commented portion of the code is used to read and print accelerations. Since this is in the same loop as the code for the motor, I'm sure that the delay(333) has a negative effect, but also when I tried step-by-step to include lines of code for accelerometer, the motor slowly started to losing speed and steps...

Does anyone of you have a clue how this could be done so that both devices (the motor with EasyDriver v 4.4 and the accelerometer) could run simultaneously since there can't be 2 void loops? I don't know how I could timewise separate their individual codes since I need to monitor the motor with the accelerometer...
Kind regards,

Luka

body:
This is common problem, how to do two (and more) things with waiting, without blocking `delay` (the simplest way is in example `BlinkWithoutDelay`)

- You wait for motor microsteps (with delayMicroseconds)
- You wait between reading MCU (with delay(333))
- You spend time sending Transmission over Wire (that is relatively slow) and getting answer `requestFrom` (also slow)
- You spend time sending prints over Serial

Each of this is blocking delay of some kind under Arduino (and writing the transmission in non-blocking way is not an easy task)

You should use some kind of `state automaton` (google that) for that (or more such automats - each for one task), to overcome the blocking nature of the steps.

basically you can have lot of loops running together in this manner:

    long state1_micros,state2_micros,state3_micros; // last time it happened
    long state1_delay,state2_delay,state3_delay; // how long wait for next step
    #define LOOP1_STEP1 1
    #define LOOP1_STEP2 2
    #define LOOP1_STEP3 3
    #define LOOP2_STEP1 1
    #define LOOP2_STEP2 2
    #define LOOP2_STEP3 3
    #define LOOP2_STEP4 4
    #define LOOP2_STEP5 5
    #define LOOP2_STEP6 6
    #define LOOP2_STEP7 7
    void setup(){
    ...
     long current_micros=micros() ; or millis, if less precision needed
     state1=LOOP1_STEP1;
     state1_micros=current_micros;
     state1_delay=0;
     state2=LOOP2_STEP1;
     state2_micros=current_micros;
     state2_delay=0;
     // state3=LOOP3_STEP1;
     // state3_micros=current_micros;
     // state3_delay=0;
    }

    void loop(){
     long current_micros=micros() ; or millis, if less precision needed
     if (state1==LOOP1_STEP1 && current_micros-state1_micros>=state1_delay) {
       //state1 paused for at least state1_delay
       if (/*some condition for leave state1 step1  like (digitalRead(GO_PIN_L) == LOW)*/) {
         state1=LOOP1_STEP2;// next step
         state1_micros+=/*some delay like MICROSECONDS_PER_MICROSTEP */;
         /* do action for STEP1, like  digitalWrite(8, LOW); */
        }
      }
     if (state1==LOOP1_STEP2 && current_micros-state1_micros>=state1_delay) {
       //state1 paused for at least state1_delay
       if (/*some condition for leave state1 step2  like (True)*/) {
         state1=LOOP1_STEP3;//next step
         state1_micros =/*some delay like(MICROSECONDS_PER_MICROSTEP * 0.9) / 2) */;
         /* do action for STEP2, like  digitalWrite(STEP_PIN, HIGH); */
        }
      }
     if (state1==LOOP1_STEP3 && current_micros-state1_micros>=state1_delay) {
       //state1 paused for at least state1_delay
       if (/*some condition for leave state1 step3  like (True)*/) {
         state1=LOOP1_STEP1;//next step
         state1_micros =/*some delay like(MICROSECONDS_PER_MICROSTEP * 0.9) / 2) */;
         /* do action for STEP2, like  digitalWrite(STEP_PIN, LOW); */
        }
      }
    ////////
     if (state2==LOOP2_STEP1 && current_micros-state2_micros>=state2_delay) {
       //state2 paused for at least state2_delay
       if (/*some condition for leave state2 step1  like (digitalRead(GO_PIN_L) == LOW)*/) {
         state1=LOOP2_STEP2;// next step
         state1_micros+=/*some delay like 100*1000 (333/3) */;
         /* do action for STEP1, like
      Wire.beginTransmission(MPU_addr);
      Wire.write(0x3B);  // starting with register 0x3B (ACCEL_XOUT_H)
      Wire.endTransmission(false);
      Wire.requestFrom(MPU_addr, 14, true); // request a total of 14 registers
      float AcX = Wire.read() << 8 | Wire.read(); // 0x3B (ACCEL_XOUT_H) & 0x3C (ACCEL_XOUT_L)
      float AcY = Wire.read() << 8 | Wire.read(); // 0x3D (ACCEL_YOUT_H) & 0x3E (ACCEL_YOUT_L)
      float AcZ = Wire.read() << 8 | Wire.read(); // 0x3F (ACCEL_ZOUT_H) & 0x40 (ACCEL_ZOUT_L)
      Tmp = Wire.read() << 8 | Wire.read(); // 0x41 (TEMP_OUT_H) & 0x42 (TEMP_OUT_L)
      // GyX=Wire.read()<<8|Wire.read();  // 0x43 (GYRO_XOUT_H) & 0x44 (GYRO_XOUT_L)
      // GyY=Wire.read()<<8|Wire.read();  // 0x45 (GYRO_YOUT_H) & 0x46 (GYRO_YOUT_L)
      // GyZ=Wire.read()<<8|Wire.read();  // 0x47 (GYRO_ZOUT_H) & 0x48 (GYRO_ZOUT_L)
     */
        }
      }
     if (state2==LOOP2_STEP2 && current_micros-state2_micros>=state2_delay) {
       //state2 paused for at least state2_delay
       if (/*some condition for leave state1 step2  like (True)*/) {
         state2=LOOP2_STEP3;//next step
         state2_micros +=/*some delay like 10*1000 (10ms) */;
         /* do action for STEP2, like  Serial.print("AcX = "); Serial.println(AcX / 16384);  */
        }
      }
     if (state2==LOOP2_STEP3 && current_micros-state2_micros>=state2_delay) {
       //state2 paused for at least state2_delay
       if (/*some condition for leave state2 step3  like (True)*/) {
         state2=LOOP2_STEP4;//next step
         state2_micros +=/*some delay like 10*1000 (10ms) */;
         /* do action for STEP3, like Serial.print(" AcY = "); Serial.println(AcY / 16384); */
        }
      }
     if (state2==LOOP2_STEP4 && current_micros-state2_micros>=state2_delay) {
       //state2 paused for at least state2_delay
       if (/*some condition for leave state2 step4  like (True)*/) {
         state2=LOOP2_STEP5;//next step
         state2_micros +=/*some delay 10*1000 (10ms) */;
         /* do action for STEP4, like  Serial.print(" AcZ = "); Serial.println(AcZ / 16384); */
        }
      }
     if (state2==LOOP2_STEP5 && current_micros-state2_micros>=state2_delay) {
       //state2 paused for at least state2_delay
       if (/*some condition for leave state2 step5  like (True)*/) {
         state2=LOOP2_STEP6;//next step
         state2_micros +=/*some delay 10*1000 (10ms) */;
         /* do action for STEP5, like  Serial.print(" AcZ = "); Serial.println(AcZ / 16384); */
        }
      }
     if (state2==LOOP2_STEP6 && current_micros-state2_micros>=state2_delay) {
       //state2 paused for at least state2_delay
       if (/*some condition for leave state2 step6  like (True)*/) {
         state2=LOOP2_STEP7;//next step
         state2_micros +=/*some delay 10*1000 (10ms) */;
         /* do action for STEP6, like  Serial.println(""); */
        }
      }

     if (state2==LOOP2_STEP7 && current_micros-state2_micros>=state2_delay) {
       //state2 paused for at least state2_delay
       if (/*some condition for leave state2 step7  like (True)*/) {
         state2=LOOP2_STEP1;//start over
         state2_micros +=/*some delay (333-100-4*10)*1000 (rest to 333ms) */;
         /* do action for STEP7, like  nothing*/
        }
      }
    /////
    /* if we have more automatons, like stat3, stat4 and so on, put it her */
    } // end loop()


body:
Thank you **gilhad** and **Jot** for your time, I really appreciate it. However, my best friend who happens to be an electric guru as far as I am concerned, proposed an ever more elegant solution to this multi-tasking problem.
He proposed to use timer settings in the void setup, like this:

    #include<Wire.h>
    const int MPU_addr = 0x68; // I2C address of the MPU-6050
    int16_t AcX, AcY, AcZ, Tmp, GyX, GyY, GyZ;

    #define RPMS                300.0
    #define STEP_PIN                9
    #define DIRECTION_PIN           8
    #define GO_PIN_L                3
    #define GO_PIN_R                4

    #define STEPS_PER_REV         200
    #define MICROSTEPS_PER_STEP     8
    #define MICROSECONDS_PER_MICROSTEP   (1000000/(STEPS_PER_REV * MICROSTEPS_PER_STEP)/(RPMS / 60))

    uint32_t LastStepTime = 0;
    uint32_t CurrentTime = 0;

    int Distance = 0;

    void setup() {
      bitClear(SREG, 7);
      pinMode(10, OUTPUT);

      TCCR1A = 0;
      TCCR1B = 0;
      TCNT1 = 0;
      TCCR1A = _BV(COM1B1) | _BV(WGM10) | _BV(WGM11);
      TCCR1B = _BV(WGM12) | _BV(WGM13) | _BV(CS10); //prescaler 1, fast PWM, OCR1A as TOP
      OCR1A = 2423; //timer šteje do 444, tako dobim PWM frekvenco 36,363kHz
      OCR1B = int(OCR1A / 2); //prilagajam duty cyle, naj bo kar 50%

      bitSet(SREG, 7); //global interrupt enable

      Wire.begin();
      Wire.beginTransmission(MPU_addr);
      Wire.write(0x6B);  // PWR_MGMT_1 register
      Wire.write(0);     // set to zero (wakes up the MPU-6050)
      Wire.endTransmission(true);
      Serial.begin(9600);

      pinMode(DIRECTION_PIN, OUTPUT);
      digitalWrite(DIRECTION_PIN, LOW);
      pinMode(GO_PIN_L, INPUT);
      pinMode(GO_PIN_R, INPUT);
    }

    void loop() {
      Distance = Distance + 1;   // record this step
      if (digitalRead(GO_PIN_L) == LOW)
      { TCCR1A = 0;
        TCCR1B = 0;
        TCNT1 = 0;
        delay(100);
        TCCR1A = _BV(COM1B1) | _BV(WGM10) | _BV(WGM11);
        TCCR1B = _BV(WGM12) | _BV(WGM13) | _BV(CS10); //prescaler 1, fast PWM, OCR1A as TOP
        OCR1A = 2423; //timer šteje do 444, tako dobim PWM frekvenco 36,363kHz
        OCR1B = int(OCR1A / 2); //prilagajam duty cyle, naj bo kar 50%

        digitalWrite(8, LOW);
      }
      if (digitalRead(GO_PIN_R) == LOW)
      {
        TCCR1A = 0;
        TCCR1B = 0;
        TCNT1 = 0;
        delay(100);
        TCCR1A = _BV(COM1B1) | _BV(WGM10) | _BV(WGM11);
        TCCR1B = _BV(WGM12) | _BV(WGM13) | _BV(CS10); //prescaler 1, fast PWM, OCR1A as TOP
        OCR1A = 2423; //timer šteje do 444, tako dobim PWM frekvenco 36,363kHz
        OCR1B = int(OCR1A / 2); //prilagajam duty cyle, naj bo kar 50%

        digitalWrite(8, HIGH);
      }
      Wire.beginTransmission(MPU_addr);
      Wire.write(0x3B);  // starting with register 0x3B (ACCEL_XOUT_H)
      Wire.endTransmission(false);
      Wire.requestFrom(MPU_addr, 14, true); // request a total of 14 registers
      float AcX = Wire.read() << 8 | Wire.read(); // 0x3B (ACCEL_XOUT_H) & 0x3C (ACCEL_XOUT_L)
      float AcY = Wire.read() << 8 | Wire.read(); // 0x3D (ACCEL_YOUT_H) & 0x3E (ACCEL_YOUT_L)
      float AcZ = Wire.read() << 8 | Wire.read(); // 0x3F (ACCEL_ZOUT_H) & 0x40 (ACCEL_ZOUT_L)
      Tmp = Wire.read() << 8 | Wire.read(); // 0x41 (TEMP_OUT_H) & 0x42 (TEMP_OUT_L)
      // GyX=Wire.read()<<8|Wire.read();  // 0x43 (GYRO_XOUT_H) & 0x44 (GYRO_XOUT_L)
      // GyY=Wire.read()<<8|Wire.read();  // 0x45 (GYRO_YOUT_H) & 0x46 (GYRO_YOUT_L)
      // GyZ=Wire.read()<<8|Wire.read();  // 0x47 (GYRO_ZOUT_H) & 0x48 (GYRO_ZOUT_L)
      Serial.print("AcX = "); Serial.println(AcX / 16384);
      Serial.print(" AcY = "); Serial.println(AcY / 16384);
      Serial.print(" AcZ = "); Serial.println(AcZ / 16384);
      Serial.print(" Tmp = "); Serial.print(Tmp / 340.00 + 36.53);
      Serial.println("");
      // Serial.print(" | GyX = "); Serial.print(GyX);
      // Serial.print(" | GyY = "); Serial.print(GyY);
      // Serial.print(" | GyZ = "); Serial.println(GyZ);
      delay(333);
    }
So the portion in void setup:

      bitClear(SREG, 7);
      pinMode(10, OUTPUT);

      TCCR1A = 0;
      TCCR1B = 0;
      TCNT1 = 0;
      TCCR1A = _BV(COM1B1) | _BV(WGM10) | _BV(WGM11);
      TCCR1B = _BV(WGM12) | _BV(WGM13) | _BV(CS10); //prescaler 1, fast PWM, OCR1A as TOP
      OCR1A = 2423; //timer counts to 444, PWM frequency is thereby 36,363kHz
      OCR1B = int(OCR1A / 2); //duty cyle is 50%

      bitSet(SREG, 7); //global interrupt enable

rotates the step motor WITHOUT any code in the void loop, void loop is only used to change the rotation direction of the motor by using the buttons that I incorporated (GO_PIN_L and GO_PIN_R) and to measure the acceleration with the accelerometer.

I hope this helps to anyone that might have similar problems.
Kind regards,

Luka


message:
Issue with Speck cipher on Arduino UNO

I found a library for the Speck cipher here: https://github.com/Chien-Ning/ArduinoCrypto

And I'm trying to use but haven't had much luck. My code is the following:

    #include <SPECK_AVR.h>
    #include <SPECK_spec.h>

    #include "SPECK_AVR.h"

    void setup() {
      // put your setup code here, to run once:

      SpeckTxtLen = 32;
      SpeckKeyLen = 64;
      speckTxtKey[]= 0x65, 0x74, 0x69, 0x4c, 0x19, 0x18, 0x11, 0x10, 0x09, 0x08, 0x01, 0x00;

      speckKey();
      speckEnc();

      Serial.println("");
      for (int i = 0; i < SpeckTxtLen/8; i++){
      Serial.print(speckTxtKey[i], HEX);
      Serial.print(", ");
      }
    }

    void loop() {
      // put your main code here, to run repeatedly:

    }

And I'm getting this error:

    error: lvalue required as left operand of assignment

and

    error: expected primary-expression before ']' token

Do you think I'm missing something in the usage of this library?

Thanks in advance

body:
    speckTxtKey[]= 0x65, 0x74, 0x69, 0x4c, 0x19, 0x18, 0x11, 0x10, 0x09, 0x08, 0x01, 0x00;

That's not how you assign an array.
And you never defined a type for the array.

It sould be:

    byte speckTxtKey[] = {0x65, 0x74, 0x69, 0x4c, 0x19, 0x18, 0x11, 0x10, 0x09, 0x08, 0x01, 0x00};

**EDIT**:

I checked the source of the library to figure out how to use it, but it doesn't seem the library is meant for actual use.

`SpeckTxtLen` and `SpeckKeyLen` are macros inside *SPECK_AVR.h*, which are supposed to be changed there, not in your code.

The library also defines `speckTxtKey` inside *SPECKenc_AVR.cpp* with predefined test data based on the chosen length.

This library looks like a test implementation of the speck cipher, which was just dumped onto GitHub.


message:
Loop code without manually pressing the button

In a piece off code I am modifying I have a button connected to start the code and then it resets its self afterwards. Is they a way to make the arduino loop that code without manually pressing the button again?

This is a section off the code:

<!-- language: lang-c++ -->

    #include <Adafruit_NeoPixel.h>
    #ifdef __AVR__
      #include <avr/power.h>
    #endif
    #define PIN 6
    #define BUTTON_PIN 9

    Adafruit_NeoPixel strip = Adafruit_NeoPixel(120, PIN, NEO_GRB + NEO_KHZ800);

    bool oldState = HIGH;
    int showType = 0;

    void(* resetFunc) (void) = 0; //declare reset function @ address 0

    void setup() {
      pinMode(BUTTON_PIN, INPUT_PULLUP);
      strip.begin();
      strip.show(); // Initialize all pixels to 'off'
    }

    void loop() {
      // Get current button state.
      bool newState = digitalRead(BUTTON_PIN);

      // Check if state changed from high to low (button press).
      if (newState == LOW && oldState == HIGH) {
        // Short delay to debounce button.
        delay(20);
        // Check if button is still low after debounce.
        newState = digitalRead(BUTTON_PIN);
        if (newState == LOW) {
          showType++;
          if (showType > 9)
            showType=0;
          startShow(showType);
        }
      }

      // Set the last button state to the old state.
      oldState = newState;
    }

    void startShow(int i) {
      colorWipe(strip.Color(75, 0, 0), 50); // Red
      colorWipe(strip.Color(0, 75, 0), 50); // Green
      colorWipe(strip.Color(0, 0, 75), 50); // Blue
      theaterChase(strip.Color(75, 75, 75), 50); // White
      theaterChase(strip.Color(75, 0, 0), 50); // Red
      theaterChase(strip.Color(0, 0, 75), 50); // Blue
      rainbow(20);
      rainbowCycle(20);
      theaterChaseRainbow(50);
      resetFunc();  //call reset
    }

Thanks Reece

body:
As pointed out by Delta\_G, there is no point in resetting your program.
What you should do is think your program in terms of the Arduino logic:

1. You put in `setup()` the code you want to run when your program
   starts.
2. You put in `loop()` the code you want to run over and over again.

In this case `loop()` is fairly simple, as the stuff you want to run
over and over again is the animation, thus:

<!-- language-all: c++ -->

    void loop() {
      colorWipe(strip.Color(75, 0, 0), 50); // Red
      colorWipe(strip.Color(0, 75, 0), 50); // Green
      colorWipe(strip.Color(0, 0, 75), 50); // Blue
      theaterChase(strip.Color(75, 75, 75), 50); // White
      theaterChase(strip.Color(75, 0, 0), 50); // Red
      theaterChase(strip.Color(0, 0, 75), 50); // Blue
      rainbow(20);
      rainbowCycle(20);
      theaterChaseRainbow(50);
    }

Note that I removed the call to `resetFunc()`.

The stuff you want to do at startup is the initialization. Oh, wait. In
a comment you wrote “I want to wait for the button press”. So this also
has to be done before the program starts looping. Hence your `setup()`
should initialize stuff, _then_ wait for the button press:

    void setup() {
      // Initialize the strip to all piwels off.
      strip.begin();
      strip.show();

      // Wait until the button is pressed.
      pinMode(BUTTON_PIN, INPUT_PULLUP);
      while (digitalRead(BUTTON_PIN) == HIGH)
          ; // do nothing
    }