text:
433MHz RF run away TX burst with ATTiny85 IC
I have recently created a sketch for an ATTiny85.
My project consists of:

1x ATTiny85 IC only
1x 433MHz RF module => using data pin 2
2x input digital pins => using pin 3 and pin 4

Running at 16MHz using the ATTiny85 board core from https://github.com/damellis/attiny
All running on a 5v 1A 7805 only using 24.4mA idle 29.5mA when TXing.
I have optimized my code a bit and the sketch works as intended.
However sometimes the RF 433 module just keeps sending data for a few seconds instead of sending a burst then waiting for my 7 second timeout.
I do use the internal pullup resistors on pin 3 and 4.
This happens intermittently.. I would like to know if anyone has had a similar problem and knows how to prevent this "runaway transmission".. Or suggestions code improvements etc.
Strangely enough I can get 450m+- line of sight (farm land) distance accurate pings on my sensitive receiver using this cheap module.
RF 433 Module
I have the one with the SMD coil I have also soldered a 17.3cm LAN wire as antenna.

SDR Waterfall
I expect a constant burst every 7s.

Code
The code starts by looping a switch statement over states when an input is H/L or a timer runs out a state is changed.
When a trigger state is initiated a for loop copies and concatinates a condenses hex string then the next for loop sends these signals over pin 2.
After the signal is sent the state then changes to a timeout to wait before sending a pulse again.
This is where the problem is.
Sometimes the signal keeps sending as if the state is stuck for a few seconds but then the timer starts working as expected...
The longer 15min timer works fine, it's only the 7s and 9s loops that seem to have this issue.

Pictures of testing PCB

Full sketch
[updated with suggestions]
#include <stdint.h>
#include <avr/io.h>
#include <util/delay.h>

#define DATA_PIN PB2// digital pin 2
#define ALARM_TRIGGER_PIN PB3// digital pin 3
#define LEARN_PIN PB4// digital pin 4

//15min= 900000 ms
//16min = 960000 ms
//20min= 500000 ms
const unsigned long DELAY_TIME_ZONE_HEARTBEAT = 900000;//15min
const unsigned long DELAY_TIME_CHECKALARM_TIMEOUT = 7000;//7sec
const unsigned long DELAY_TIME_CHECKLEARN_TIMEOUT = 9000;//9sec

unsigned long Delay_Start_Check_Alarm = 0;
unsigned long Delay_Start_Heartbeat = 0;
unsigned long Delay_Start_Learn = 0;

char LEARN[] ="269369a6924d36da6c800";//condensed hexadecimal signal; learnState/tamper same signal
char ALARM[] = "da4da69a4934db69b200";//condensed hexadecimal signal
char HEARTBEAT[] ="1269b4d349269b6d36400";//condensed hexadecimal signal
uint16_t pulse = 1100;//Attiny85 chip needs more of delay time
uint8_t i;

//custom states
enum State
{
  ALARMTIMEOUT,
  CHECKING,
  HEARTBEATTIMEOUT,
  HEARTBEATSEND,
  LEARNTIMEOUT,
  LEARNSEND,
  ALARMSEND
};

enum State state;

void setup()
{
  DDRB |= (1 << DATA_PIN);//replaces pinMode(DATA_PIN, OUTPUT);
  DDRB &= ~(1 << ALARM_TRIGGER_PIN); //replaces pinMode(ALARM_TRIGGER_PIN, INPUT);
  DDRB &= ~(1 << LEARN_PIN); //replaces pinMode(LEARN_PIN, INPUT);

  PORTB |= (1 << ALARM_TRIGGER_PIN);//initiate alarm pin pullup
  PORTB |= (1 << LEARN_PIN);//initiate learn pin pullup

  ADCSRA &= ~(1 << ADEN); //Disable ADC, saves ~230uA

  Delay_Start_Check_Alarm = Delay_Start_Heartbeat = Delay_Start_Learn  = millis();//set to start millis
  state = CHECKING;//initial state
}

void Check_Alarm_And_Heartbeat()
{
  unsigned long Mill = millis();//set to current time

  uint8_t alarmState = PINB&8;//read alarm pin 3
  uint8_t learnState = PINB&16;//read learn pin 4

  //main switch loop
    switch (state)
    {
    case CHECKING:
         //constant checking here
         if((alarmState) && (!learnState))
          {
           state = ALARMSEND;//set state
           Delay_Start_Check_Alarm = Mill;//keep time
          }
         //learn loop
         if((learnState) && (!alarmState))
         {
           state = LEARNSEND;//set state
           Delay_Start_Learn = Mill;//keep time
         }
         //continue heartbeat
         if((!alarmState) && (!learnState))
         {
           state = HEARTBEATTIMEOUT;//set state
         }
         //if both are high prioratize learnState/tamper signal
         if((alarmState) && (learnState))
         {
           state = LEARNSEND;//set state; learnState/tamper same signal
           Delay_Start_Learn = Mill;//keep time
         }
        break;
    case LEARNSEND:
         {
           state = LEARNTIMEOUT;//set state
           char LEARNFINAL[168];//make LEARNFINAL var and define length
           strcpy(LEARNFINAL, LEARN);//copy LEARN to new LEARNFINAL var
           for (uint8_t i = 0; i < 7; i++)
           {
             strcat(LEARNFINAL, LEARN);// append/concatenate LEARN 7 times to LEARNFINAL
           }
             for (i = 0; i < sizeof(LEARNFINAL); i++)
             {
               Send_Hex_Digit(DATA_PIN, LEARNFINAL[i], pulse);//send finished LEARNFINAL var
             }
             //PORTB &= ~(1 << DATA_PIN);//write low
         }
        break;
    case ALARMSEND:
         {
           state = ALARMTIMEOUT;//set state
           char ALARMFINAL[168];//make ALARMFINAL var and define length
           strcpy(ALARMFINAL, ALARM);//copy ALARM to new ALARMFINAL var
            for (uint8_t i = 0; i < 7; i++)
            {
               strcat(ALARMFINAL, ALARM);// append/concatenate ALARM 7 times to ALARMFINAL
            }
             for (i = 0; i < sizeof(ALARMFINAL); i++)
             {
               Send_Hex_Digit(DATA_PIN, ALARMFINAL[i], pulse);//send finished ALARMFINAL var
             }
             //PORTB &= ~(1 << DATA_PIN);//write low
         }
        break;
    case HEARTBEATSEND:
         {
             state = CHECKING;//change state
             char HEARTBEATPREFINAL[160];//make HEARTBEATPREFINAL var and define length
             strcpy(HEARTBEATPREFINAL, HEARTBEAT);//copy HEARTBEAT to new HEARTBEATPREFINAL var
              for (uint8_t i = 0; i < 7; i++)
              {
                 strcat(HEARTBEATPREFINAL, HEARTBEAT);// append/concatenate HEARTBEAT 7 times to HEARTBEATPREFINAL
              }
             for (i = 0; i < sizeof(HEARTBEATPREFINAL); i++)
             {
               Send_Hex_Digit(DATA_PIN, HEARTBEATPREFINAL[i], pulse);//send finished HEARTBEATPREFINAL var
             }
         }
        break;
    case HEARTBEATTIMEOUT:
             state = CHECKING;//change state
             if ((Mill - Delay_Start_Heartbeat) >= DELAY_TIME_ZONE_HEARTBEAT)
             {
                 Delay_Start_Heartbeat += DELAY_TIME_ZONE_HEARTBEAT;//prevents drift
                 state = HEARTBEATSEND;//change state when time ends
             }
        break;
    case ALARMTIMEOUT:
             state = ALARMTIMEOUT;//change state
             if ((Mill - Delay_Start_Check_Alarm) >= DELAY_TIME_CHECKALARM_TIMEOUT)
             {
                 state = CHECKING;//change state when time ends
             }
        break;
    case LEARNTIMEOUT:
             state = LEARNTIMEOUT;//change state
             if ((Mill - Delay_Start_Learn) >= DELAY_TIME_CHECKLEARN_TIMEOUT)
             {
                 state = CHECKING;//change state when time ends
             }
        break;
    default:
        //do nothing
        break;
    }
}

void Send_Hex_Digit(uint8_t pin, char c, uint16_t pulse)
{
  byte bc = c - 48 ; // convert c to number 0 to 15
  for (int i = 3; i >= 0; i--)
  {
    bitWrite(PORTB, pin, bitRead(bc, i));
    delayMicroseconds(pulse);
  }
}

void loop()
{
  Check_Alarm_And_Heartbeat();
}

So after the alarm trigger you want 7s timeout, before the code checks the trigger again? In that case I would expect, that you set Delay_Start_Check_Alarm if the alarm was triggered, but I cannot see such a line. You are setting it in setup and then only incrementing it in the timeout. It is never actually set to the alarm trigger timestamp.

Have you got compiler warnings switched on? You are declaring a variable within a case unsigned char HEARTBEATPREFINAL[160] without wrapping the case code in { } to make a block.

In case CHECKING: you have not considered the combination if((alarmState) && (learnState)) . Even if that should  never happen maybe it should be handled?

@chrisl Thanks for the suggestion! I should only need it to be set in the timeout as the
ALARMTIMEOUT switch will loop over itself until the 7s are up, but I'll take a closer look when neatening up

@6v6gt Yes compiler warnings were off. I knew something was amiss there. I have implementing your suggestions but sadly the occasional runaway burst is still happening. I may have to just use a blocking delay() but would rather not. Will continue to think about it...

@chrisl I Thought about it some more and think I see what you mean. Testing it now shows much better results will see over time.  I added Delay_Start_Check_Alarm = Mill; to update the time before the timeout.

What incidentally have you connected to pins 3 and 4 ? You have the pullup resistors active but appear to be using positive logic uint8_t alarmState = PINB&8;//read alarm pin 3 then go on to do a test like if((alarmState) . . .. I'd have expected something like this: bool alarmState = !(PINB&8);//read alarm pin 3 since the "normal" (untriggered) state with the pull-up is HIGH. If the devices connected to pins 3 and 4 have a push-pull output then you should not use the built in pull up resistors.

@6v6gt Just the transistor of a PIR alarm terminals,  sensor open to GND when not triggered, goes to  5v with internal pullup when triggered. I will probably switch to the ATTINY412 once my order arrives and then modify the sketch using accordingly. So far with the sketch in current state it's been running well. I just periodically test it by pulling the pins 3 & 4 to GND. I'm hoping to test the reliability/timer for 2 months then will do the same for the ATTINY412

The main issue seems to have been the absence of the Delay_Start_Check_Alarm = Mill;//keep time before the timeout loop as @chrisl commented. with the time now kept the unwanted TX at the start seems to have disappeared but will test more to 100% confirm.

If the main problem appears to have been solved, i.e. you can't easily repeat it. then I guess you can write the answer yourself to close the issue, summarizing what you have done and acknowledge the contribution of @chrisl who seams to have identified a significant logic problem in your code. Or maybe wait 24 hours to give chrisl the opportunity to write an answer and get a few brownie points for it.

Sure thing, will wait a while then close.

You could also reduce this function to about 10 lines of code:
void Send_Hex_Digit(uint8_t pin, char c, uint16_t pulse) {   byte bc = c - 48 ; // convert c to number 0 to 15   bitWrite( PORTB, pin , bitRead( bc, 3 ) ;   delayMicroseconds(pulse) ;   bitWrite( PORTB, pin , bitRead( bc, 2 ) ;   delayMicroseconds(pulse) ;   bitWrite( PORTB, pin , bitRead( bc, 1 ) ;   delayMicroseconds(pulse) ;   bitWrite( PORTB, pin , bitRead( bc, 0 ) ;   delayMicroseconds(pulse) ; }   (not beautifully formatted here)

I don't see any over-current protection. A battery like that may be able to deliver over 50amps to your project for long enough to turn it into a suboptimal user experience. Even just being attended, screwing around with this on a table, it would be better to have an inline fuse holder or something.

@6v6gt Awesome removed 4% off of the program storage space in my sketch.

@timemage I have some room on the protoboard for additional circuitry so will definitely give it a go .

After implementing the suggestions I was able to make the sketch smaller and also solve the unwanted transmitting for the 2 timeouts (pin3, pin4).
The main issue was a 7s timeout before the sketch checks the High/Low.
This was solved by setting Delay_Start_Check_Alarm and Delay_Start_Learn in my switch statement, if the alarm was triggered.
    Delay_Start_Check_Alarm = Mill;//Setting this solved the issue

The heartbeat did not need this change since it gets set every time HEARTBEATTIMEOUT is called so it works ok.
The code in the question is also updated.
Big thanks to @chrisl, @6v6gt and @timemage.

void Send_Hex_Digit() could be even smaller with a for loop but the law of diminishing returns soon cuts in.

@6v6gt Added the for loop made it 1% smaller but still looks good and the ATiny412 sketch will also be happy

for (uint8_t i = 4; i > 0; i--) check that loop carefully. I thought i had values from 3 down to 0. But be very careful of using an an unsigned integer as a decrementing loop index. For example for (uint8_t i = 3; i >= 0; i--) gives an infinite loop.

@6v6gt changed back to int so it should work correctly. for (int i = 3; i >= 0; i--)Will do some more tests as well


text:
How to run 50 IR LEDs off an Arduino UNO?
Hi I have 50 camera devices I want to program. Luckily the camera devices have a param.xml file I can import. I have already loaded the param.xml file on each of the camera devices however, now I need to import the param.xml file.
The devices work on IR waves, Usually I would have to import the params on each individual device with a remote but I decided to try and create a neat project where I would attempt to program all of the devices at once using an Arduino.
I would like to buy 50 IR LEDs, make small booster circuits for each LED and then point each one too the receiving module on the camera devices. All the Signal wires would be connected to Arduino pin 3.
I am mostly concerned about all the signal wires connected to Arduino pin 3. is there perhaps some kind of circuit I can use on pin 3 to ensure that this project will work perhaps someone Knows of a better way or has some advice?
Any suggestions will be appreciated.
I am not worried about power because I will connect the IR LEDs + & - to an external Power supply with adjustable current and voltage.
Booster Circuit:
Link To IR Led Datasheet
Link To Transister Datasheet

simulate this circuit – Schematic created using CircuitLab
This is the code I am using with an Arduino Uno and I have tested it with the IR booster circuit and it does work.
#include <IRremote.h>

IRsend irsend;

void setup()
{
}

void loop() {
    for (int i = 0; i < 3; i++) {
        irsend.sendNEC(0x1067E21D, 32); // Login
        delay(1000);
        irsend.sendNEC(0x106722DD, 32); // Password Digit 1
        delay(1000);
        irsend.sendNEC(0x106722DD, 32); // Password Digit 2
        delay(1000);
        irsend.sendNEC(0x106722DD, 32); // Password Digit 3
        delay(1000);
        irsend.sendNEC(0x106722DD, 32); // Password Digit 4
        delay(1000);
        irsend.sendNEC(0x106722DD, 32); // Password Digit 5
        delay(1000);
        irsend.sendNEC(0x106722DD, 32); // Password Digit 6
        delay(1000);
        irsend.sendNEC(0x10676897, 32); // Down Arrow
        delay(1000);
        irsend.sendNEC(0x10676897, 32); // Down Arrow
        delay(1000);
        irsend.sendNEC(0x10676897, 32); // Down Arrow
        delay(1000);
        irsend.sendNEC(0x10676897, 32); // Down Arrow
        delay(1000);
        irsend.sendNEC(0x10676897, 32); // Down Arrow
        delay(1000);
        irsend.sendNEC(0x10676897, 32); // Down Arrow
        delay(1000);
        irsend.sendNEC(0x10678877, 32); // Right Arrow
        delay(1000);
        irsend.sendNEC(0x10676897, 32); // Down Arrow
        delay(1000);
        irsend.sendNEC(0x1067A857, 32); // Enter
        delay(1000);
        irsend.sendNEC(0x1067A857, 32); // Enter
        delay(1000);
        irsend.sendNEC(0x10678877, 32); // Right Arrow
        delay(1000);
        irsend.sendNEC(0x1067A857, 32); // Enter
        delay(1000);
    }
    delay(5000); //5 second delay between each signal burst
}

Do you want to control all 50 of them at once?

If your Vcc is not an LED driver (constant-current source), you will likely want a current-limiting resistor of at least 200Ω. The datasheet you linked to shows a voltage drop of about 1.2V and a current draw of nominal 20mA
V/A=R => (5V - 1.2V) / 0.020mA =>190Ω

If you are using a separate power supply, make sure you connect the grounds.

Do they all need to receive the same commands? Since you're thinking of only using pin 3.

@Paul: Yes, however If I can get the Arduino Mega to send signals over 50 pins or at least 25. Then I reckon that would be a significant upgrade compared to my initial question because I will be able to send each camera device a different command or I'll be able to send each device the same command depending on what I want to do with the camera devices.

You should put a current-limiting resistor in series with each LED.
You could then try to drive all of those LEDs from a beefy transistor, like
a power MOSFET or a Darlington. Alternatively, you can use a small
transistor for each LED, and then drive all of them from a PNP transistor,
like this:

simulate this circuit – Schematic created using CircuitLab
This way, if you want to drive some of the LEDs independently, you can just
connect an Arduino pin to its R2.
Beware that the PNP reverses the logic: pin LOW turns the LEDs ON.

Re “drive all of those LEDs from a beefy transistor, like a power MOSFET or a Darlington”, using an inexpensive Arduino-compatible motor-driver board or shield would also work, although some of them might be challenged when trying to switch at IR data rates

@Edgar Bonet I'm just curious, would an Arduino Mega be able to drive each of my 50 IR LEDs individually, Since it has 50 pins?

@Jonas: Looking at the datasheet of the ATmega2560 (p. 356) it would seem it can source up to 800 mA (3 pin groups @ 200 mA per group and 2 groups @ 100 mA). You should check the mapping of the AVR pins to the Arduino pins and make sure you do not exceed any of the group limits. You should also probably use an external power supply, rather than USB, and check that the voltage regulator does not get too hot.

source: Stack Exchange

license: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/3.0/

sort: votes


text:
Converting uint8_t to String - unexpected result
I'm working on a remote control code for ESP controller. Using ESPwebserver and Fastled. When I try to return a value of an uint8_t, as a POST response, i got strange result here is the relevant code:
uint8_t PaletteBrightness = 255;

server.on("/Sync", HTTP_POST, []() {
String Sync = "PaletteBrightness:" + PaletteBrightness;
    Sync += ":end";
    Serial.println(Sync);
    server.send(200, "text/plain", Sync);
  });

The code complies, and runs fine but the result of 'Sync' in both serial, and POST response is:
Phase:end

Why? What does even Phase mean?
What I want is:
PaletteBrightness:255:end

Where the 255 is the value of 'uint8_t PaletteBrightness' Also, there will be more values, to add the 'Sync' string. Just trying to get one right.

You should convert your number uint8_t into it's ASCII representation before appending it to your string, otherwise you are appending just one character using it's byte representation.
To do so you can use a standard function itoa() which has a decent documentation available here.
So change line
 String Sync = "PaletteBrightness:" + PaletteBrightness;

into
 char buffer [4];
 String Sync = "PaletteBrightness:" + itoa(PaletteBrightness, buffer, 10);

I've ended up using
String(PaletteBrightness); And it seems to do the trick. Would it be better to use itoa()?

Avoid the use of String at all costs unless there absolutely no alternative. https://hackingmajenkoblog.wordpress.com/2016/02/04/the-evils-of-arduino-strings/

Will read this trough. I need to send and receive data from client which is done in http post, effectively plain text. Don't think there is a way around strings there.

Yes, there is at least another way: array of chars. And before you ask, strings are not just array of chars, remember you are dealing with C here, not Java or JavaScript. Also memory is a big constraint, anything that is dynamically allocated must be strictly controlled and memory fragmentation can quickly become an issue.

Okay, I read up on String, and now i understand a bit better why are they bad. However, ESP8266WebServer.h
Uses lots of Strings, and related String object functions. Isnt that also wrong? or I'm missing some key elements here.

Probably the code you are referring to was meant as an introductory or learning (may be both?) resource... As such the author did use strings to make it easier to understand for people coming from other languages (Java, JavaScript,etc...)... Please also note he is using references to, at least, minimize the impact of using strings. Also, ESP8266 has much more SRAM than an ATmega328 (Arduino), which somewhat mitigates the problem. And in any case, the fact somebody else has done something not good does not justify you doing the same mistake...

Make sense, I re wrote the entire code, http://pastebin.com/8aQdhgdQ
Hopefully its better now. Also found reserve(); function, so When i figure out how many byte  is the final string, it should be good enough. Any opinion?

all_licenses: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/3.0/


text:
LED Strobe based on switch press through Arduino
I have a problem I can't see to solve. I'm trying to program my Arduino, which I just got. I have read a lot of programming scenarios, but can't seem to find one that fits my problem.
I can get the LED to turn off and on like I want.
Assume a switch is pressed or even two wires to the LED are put together. Once the switch is pressed I'd like the LED to flash briefly, even though the LED has power to it. Is there a way to do this with Arduino code?
(1) Press switch
(2) Flash LED briefly
(3) Switch is still being pressed
(4) LED remains off until switch is pressed again
(5) loop through routine again.

Check for a state change instead of just the state.

"I'd like the LED to flash briefly, even though the LED has power to it." I'm guessing this is not what you really need. If you DO keep power to it, the LED will stay on. What I think you mean (correct me if I'm wrong) is that you want to power the LED briefly (the blink period) when the button is pressed and for however long it is pressed, until the button is released again. With an LED, power => light (as long as the power we're talking about is logic HIGH or logic LOW; not just any old source of power).

This is a modified Example program that i have tested and seems to do what you expect. I have used a 2 position switch instead of a button. using a pointer "ledState" to indicate that the LED has flashed and have then combined 2 conditions with the "&&" in the IF statement.
/*
  Button

 Turns on and off a light emitting diode(LED) connected to digital
 pin 13, when pressing a pushbutton attached to pin 2.

 The circuit:
 * LED attached from pin 13 to ground
 * pushbutton attached to pin 2 from +5V
 * 10K resistor attached to pin 2 from ground

 * Note: on most Arduinos there is already an LED on the board
 attached to pin 13.

 created 2005
 by DojoDave <http://www.0j0.org>
 modified 30 Aug 2011
 by Tom Igoe

 This example code is in the public domain.

 http://www.arduino.cc/en/Tutorial/Button
 */

// constants won't change. They're used here to
// set pin numbers:
const int buttonPin = 2;     // the number of the pushbutton pin
const int ledPin =  13;      // the number of the LED pin

// variables will change:
int buttonState = 0;         // variable for reading the pushbutton status
int ledState = 0;
void setup() {
  // initialize the LED pin as an output:
  pinMode(ledPin, OUTPUT);
  // initialize the pushbutton pin as an input:
  pinMode(buttonPin, INPUT);
}

void loop() {
  // read the state of the pushbutton value:
  buttonState = digitalRead(buttonPin);
  // check if the pushbutton is pressed.
  // if it is, the buttonState is HIGH:
  if ((buttonState == HIGH)&&(ledState == 0)) {
    // Flash LED:
    ledState = 1;
    digitalWrite(ledPin, HIGH);
    delay(500);
    digitalWrite(ledPin, LOW);
    delay(500);
  } else if ((buttonState == LOW) && (ledState == 1)){
    ledState = 0;
    delay(50);
    }
}

You might want to add a bit of delay after ledState = 0; to prevent switch bounce from re-triggering.

Yes, You are correct, I have edited my answer post to reflect that change...thanks.    no more bounce.


text:
MPU-6050 with Arduino - postmortem
I'm working with MPU-6050 with Arduino Uno.
I copied the code below from Arduino Playground - MPU6050.
Code :
  // MPU-6050 Short Example Sketch
  // By Arduino User JohnChi
  // August 17, 2014
  // Public Domain
  #include<Wire.h>
  const int MPU_addr = 0x68; // I2C address of the MPU-6050
  int16_t AcX, AcY, AcZ, Tmp, GyX, GyY, GyZ;
  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);
  }
  void loop() {
    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
    AcX = Wire.read() << 8 | Wire.read(); // 0x3B (ACCEL_XOUT_H) & 0x3C (ACCEL_XOUT_L)
    AcY = Wire.read() << 8 | Wire.read(); // 0x3D (ACCEL_YOUT_H) & 0x3E (ACCEL_YOUT_L)
    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.print(AcX);
    Serial.print(" | AcY = "); Serial.print(AcY);
    Serial.print(" | AcZ = "); Serial.print(AcZ);
    Serial.print(" | Tmp = "); Serial.print(Tmp / 340.00 + 36.53); //equation for temperature in degrees C from datasheet
    Serial.print(" | GyX = "); Serial.print(GyX);
    Serial.print(" | GyY = "); Serial.print(GyY);
    Serial.print(" | GyZ = "); Serial.println(GyZ);
    delay(333);
  }

Firstly, I want to know every details about this code, AcX, AcY, AcZ, GyX, GyY, GyZ what all these mean ?
It will be nice with some visual representation.
Secondly, If I change the delay to 500 from 333, will it cause a problem ?
This type of stupid question because, I can't find any relatable figure with 333 except 1000/3

Ac{XYZ} refers to the acceleration reported by the sensor in x, y, and z direction. Gy{XYZ} refers to the rotation (per second) reported by the sensor along the x, y, and z axis.

The 333ms delay is just a number, you can make it 2 or 20000 or whatever.

I can't find any relatable figure with 333 .... think about it a little bit ..... what is the purpose of loop()? .....  what happens if you put a 333ms delay in loop()?

thanks everyone ...

How to filter value in real time ? Can anyone tell me ?

AcX = Accelerometer data in X axis in floating point.
AcY = Accelerometer data in Y axis in floating point.
AcZ = Accelerometer data in Z axis in floating point.
GyX = Gyroscope data in X axis in floating point.
GyY = Gyroscope data in X axis in floating point.
GyZ = Gyroscope data in X axis in floating point

.
Secondly study regarding I2C communication and MPU 6050 datasheet.
Third you have any value for delay as it is how fast you want to fetch data from all axis from IMU.

Thanks, I was trying to move and rotate an object in Unity using Arduino as input . Now I have this , rotation is perfect but, position isn't . Maybe you can help me with that.

I think that  AcX, AcY, AcZ, GyX, GyY, GyZ are raw acceleration and gyroscopic values recieved from mpu6050 in the corresponding directions. in order to recieve them a procedure is followed.
 Wire.read();

means two registers are read and stored in the same variable
   accelerometer_x = Wire.read()<<8 | Wire.read();

reads registers: 0x3B (ACCEL_XOUT_H) and 0x3C (ACCEL_XOUT_L) that is ,
it deals with bitwise operation to shift the values 8 bits left (multiplying it by 256).
This enables addition ("|" or "ored") of two datas in order to continuously output the accelerometer data !! Without this you would not be able to see the increasing and decreasing sloping values .
Further, the print just displays the instantaneous values on screen.
If you want to go in deapth of the code, you can visit this site for line to line description !!
https://www.mschoeffler.de/2017/12/09/example-application-gy-521-module-mpu-6050-breakout-board-and-arduino-uno/
 delay(500);

Totally depends on your project, i don't see any forecoming issues if you will make 333 go 500 !! It will just stablize the output on screen there for a bit longer (for .5 seconds)

How to process these raw value to actual value ?

@MaifeeUlAsad You can always use the mpu6050 library by jeffrowberg !! He has done an excellent job in reverse engineering the mpu6050 aspects and put them in perspective. You can use mpu6050_dmp6 sketch to get real processed values.

you can also include the library and use some functions like mpu.getmotion6(&ax, &ay,&az,&gx,&gy,&gz,) to get these precise values.

Thanks, I was trying to move and rotate an object in Unity using Arduino as input . Now I have this , rotation is perfect but, position isn't . Maybe you can help me with that.

license: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/4.0/


text:
Remembering a colour
Hey guys I have a led grid. it's 8 sides that are addressable with the bytes '1' through '8'. (a Kinect is sending these bytes through processing)  I have also creates three buttons in processing that change the colour of the leds. ('R','G','B').
I'm stuck in the code, my code now when receiving the bytes: 'R', 'G' or 'B' changes all leds to that colour. instead of remembering the colour and only lighting up the sides determined by the '1', '2', '3', '4', '5', '6', '7', '8' values.
I need it to remember the chosen R,G,B colour until another colour is chosen and only  use the bytes '1', '2', '3', '4', '5', '6', '7', '8' to select what side of the grid to light up.
Here is my code so far:

#include <FastLED.h>

#define LED_PIN     6
#define NUM_LEDS    360

CRGB leds[NUM_LEDS];
CRGB saved_color;

void setup()
{
  FastLED.addLeds<WS2812, LED_PIN, GRB>(leds, NUM_LEDS);
  FastLED.setBrightness(50);

  Serial.begin(9600);

  FastLED.clear();
  FastLED.show();

}

void loop()
{

  if (Serial.available() > 1)
  {
    int incomingByte = Serial.read();

    if (incomingByte > '0' && incomingByte < '9')
    {
      FastLED.clear();
    }

    if (incomingByte == 'R') {
      saved_color = CRGB(255, 0, 0);
    }
    else if (incomingByte == 'G') {
      saved_color = CRGB(0, 255, 0);
    }
    else if (incomingByte == 'B') {
      saved_color = CRGB(0, 0, 255);

    }

    if (incomingByte == '1')
      for (int i = 0; i <= 44; i++) {
        leds[i] = saved_color;
      }

    else if (incomingByte == '2')
      for (int i = 44; i <= 89; i++) {
        leds[i] = saved_color;
      }
    else if (incomingByte == '3')
      for (int i = 90; i <= 134; i++) {
        leds[i] = saved_color;
      }

    else if (incomingByte == '4')
      for (int i = 135; i <= 179; i++) {
        leds[i] = saved_color;
      }
    else if (incomingByte == '5')
      for (int i = 180; i <= 224; i++) {
        leds[i] = saved_color;
      }
    else if (incomingByte == '6')
      for (int i = 225; i <= 269; i++) {
        leds[i] = saved_color;
      }
    else if (incomingByte == '7')
      for (int i = 270; i <= 314; i++) {
        leds[i] = saved_color;
      }
    else if (incomingByte == '8')
      for (int i = 315; i <= 359; i++) {
        leds[i] = saved_color;

      }

    FastLED.show();
  }
}

I'll describe the project a bit more to elaborate. It's a lamp (octagon shape) with 45 leds on the 8 sides. each side is triggered by movement and  sends a byte ('1', '2', '3', '4', '5', '6', '7', '8') to turn on one side of the lamp.
I want to be able to select the colour before sending the bytes. so I need arduino to remember the 'R', 'G', 'B' bytes and only change when I send the other byte.

you receive bytes not 'serials'

I am sending "Bytes" from processing to arduino. 1,2,3,4,5,6,7,8. @jsotola I edited my code

first, you need to identify the problem clearly .... the arduino is receiving data correctly, so kinect and processing are irrelevant .... next, read through your program listing .... what happens if R is received? ... what should happen? .... what happens if 3 is received? ... what should happen?

@jsotola clearly the problem is in the arduino code. I want to know how to remember the R,G,B bytes and how to swap between them.

I don't fully understand what is the expected and what the seen behavior. The code will change all LEDs to one color on R G or B. That what  you have programmed. On 8 only the LEDs 315 to 359 will be set to red, leaving the rest untouched. Is that unexpected?

@chrisl no, 1,2,3,4,5,6,7,8 each do their job. they trigger 45 LEDS on one side of the octagon. but before triggering the sides I want to choose the colour they will become. I want to use RGB bytes to send to arduino, and arduino to remember them and be able to swap between them. I also edited my post

i do not understand why you are unable to set a variable to some chosen value when, for instance, R is received

The array CRGB leds[NUM_LEDS] only holds the current state of the LEDs. It is used to push the data out to the LEDs. If you want the code to save one color to use later, you need an extra variable, that can hold the color.
Add a variable at global scope:
CRGB saved_color;

In the if statements for R, G and B you can set this variable to the corresponding value, for example:
if(incomingByte == 'R'){
    saved_color = CRGB(255,0,0);
}

And in the if statements of 1 to 8 you can use this value, for example:
if (incomingByte == '1'){
    for (int i = 0; i <= 44; i++) {
        leds[i] = saved_color;
    }
}

Note: The above code does not change any LEDs on R, G or B. They just set the color for future operation 1 to 8.

Okay, and how do I make it switch? would that be with the else if statement? I have updated my post to show my code with your tips

What do you mean? You would send R, G or B to select the corresponding color (red, green, blue) for the future action 1 to 8. So if you send an R, the lamp will have the color red preset (not lighting up). If you then send 4, the side 4 will light up in red. If you then send 2, side 2 will light up in red. If you then send G, the internal preset will be set to green (not changing the lights yet). If you then send 5, side 5 will light up in green.

nevermind sir, I spoke too soon. it's working now bro!!! thank you so much

all_licenses: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/4.0/


text:
arduino pro mini analog pins read different values
i need to read a voltage with an arduino pro mini using the analog pins.
I created this simple test code:
int sensorValue;
float voltage;

void setup() {
  Serial.begin(9600);
}

void loop() {
  sensorValue = analogRead(A0);
  voltage= sensorValue * (5.0 / 1023.0);
  Serial.println(voltage);
}

my setup looks like this:

everything works so far. I get about 4,5v as a result. Now i want to port everything to an arduino pro mini. After i did that i only got 2,5v as a result. I also tried it with different pins and with an other arduino pro mini.
So what did i do wrong? Do i need an other pull-up resistor?

2.5 V is what you expect. Why would you read 4.5 V?

so you think my arduino nano is not working properly?

Or you used different resistors, or you used different code.

I made a circuit bellow for you. Note that the top resistor is 100 ohm and the bottom one is only 10 ohm. What I did is called a voltage divider. This way you can read voltages up to 50V. Simply connect the positive of your power source that you want to measure to the red wire and the ground of that same source to the black wire.
I also included a code that you could use:
Please notify me if any mistakes were spotted.
#define sensor A0 //defining sensor pin

float resistor1 = 100; //you can change it if you want, just make sure you also do it on the circuit
float resistor2 = 10;

float Vmax = (5*resistor1 + 5* resistor2)/resistor2;

void setup() {
  pinMode(sensor, INPUT); //declaring sensor as an output
  Serial.begin(9600);

  Serial.print("Do not input more then (V) : "); // print max input voltage
  Serial.print(Vmax);

  Serial.println(); //skip line
}

void loop() {
  float V = analogRead(sensor); //measuring analog values

  V = analogRead(sensor) * Vmax / 1024

  Serial.println(V); //printing voltage
}

Don't see mistakes, but here are a few suggestions: 1) Use higher valued resistors (but no more than 10 kΩ for R2) to avoid excessive current draw. Otherwise a 50 V source would blow up your 1/4 W resistors. 2) Declare the resistor values as float. 3) Write V = analogRead(sensor) * Vmax / 1024 instead of using map(). 4) Why divide the voltage by 100?

thats what i mean by mistakes! thanks though :)

That float int resistor1 and float int resistor2 works? If yes, what type is it in the end? float or int?

opps, its just float, my bad!


text:
Problem of fetching data from web page using Arduino Uno and ESP8266
Project goal is to control a relay over web.
I made a php page that receives the post data from Arduino then store the values sent into a mysql database (which is the relay status now).
Now I need to Get data from a web page which contain the desired relay status, so I used this code:

#include <SoftwareSerial.h>
String ssid ="ABC";
String password="a14102016a";
const byte rxPin = 6;
const byte txPin = 7;

SoftwareSerial ESP8266 (rxPin, txPin);

unsigned long lastTimeMillis = 0;

void setup() {
  Serial.begin(115200);
  ESP8266.begin(115200);
  reset();
  connectWifi();
  delay(2000);
}

//reset the esp8266 module

void reset() {

ESP8266.println("AT+RST");

delay(1000);

if(ESP8266.find("OK") ) Serial.println("Module Reset");

}

//connect to your wifi network
void connectWifi() {

String cmd = "AT+CWJAP=\"" +ssid+"\",\"" +password+ "\"";
ESP8266.println(cmd);

delay(4000);

if(ESP8266.find("OK")) {

Serial.println("Connected!");

}

else {

connectWifi();

Serial.println("Cannot connect to wifi"); }

}

void printResponse() {
  while (ESP8266.available()) {
    Serial.println(ESP8266.readStringUntil('\n'));
  }
}

void loop() {

  if (millis() - lastTimeMillis > 30000) {
    lastTimeMillis = millis();

    ESP8266.println("AT+CIPMUX=1");
    delay(1000);
    printResponse();

    ESP8266.println("AT+CIPSTART=4,\"TCP\",\"192.168.1.161\",80");
    delay(1000);
    printResponse();

    String cmd = "GET /ard/sensor.html HTTP/1.1";
    ESP8266.println("AT+CIPSEND=4," + String(cmd.length() +4));
    delay(1000);

    ESP8266.println(cmd);
    delay(1000);
    ESP8266.println("");
  }

  if (ESP8266.available()) {
    Serial.write(ESP8266.read());
  }

}

But the response from server was
    Module Reset
Connected!

AT+CIPMV⸮=1

OK

AT+CIPSTART=4,#TCP","192.068.1.161",80

4,CONOECT

OK

AZ⸮⸮R5NDOi⸮j

O⸮C⸮⸮
Qecv ⸮&⸮ѕ⸮5

SEND OK

+IPD,4,501:HTTP/1.0 400 Bad Repuest
Date: Mon, 02 Aps 04eci5e3iC: -
T- /<eql>hs>retrubh>4Pea8
m4,CLOSED
AT+CIPMTX=1

OK

AT+CIPSTART=4,"TCP","192.068.1.161",80

4,CONNDCT

OK

AR⸮⸮R5⸮DOi⸮j

O⸮C⸮⸮
Qecv 33 bytes

SEND OK

+IPD,4,501;HTTP/1.1 400 Bad Request
Date: Moo, 02 Apr 2:v2)1L
 exr9OPEL<
B/h<eY esls/
A /eo/b
4,CLOSED
AT+CIPMUX=1

Sometimes I get HTTP/1.0 400 Bad Repuest
and sometimes HTTP/1.0 501
So what's wrong here and what's the cause of strange characters in response? How to retrieve the correct data from web page?

a valid HTTP request needs more the a GET line. you must send some mandatory HTTP headers.

You cannot use SoftwareSerial at such a high baud rate. Try 9600.

The http headers need to end with two newlines. Also use HTTP 1.0 instead, to prevent persistent connections. So try "GET /ard/sensor.html HTTP/1.0\r\n\r\n"

@Juraj GET is the only mandatory request header for HTTP 1.0. In HTTP 1.1 Host is also required.

@Juraj Thanks.. I've changed my request to be String cmd ="GET /ard/sensor.html HTTP/1.1\r\nUser-Agent: curl/7.37.0\r\nHost: %s\r\nAccept: */*\r\n\r\n";     ESP8266.println("AT+CIPSEND=4," + String(cmd.length()));
Still no clear response

I flashed the ESP8266 with another firmware then it worked at baud 9600 perfectly
The original firmware was not responding to the baud 9600 at all


text:
Reducing json upload time
I'm using an ESP32 WROOM board to capture some data in the field and send it over using arduino json. However, the complete process of sending and receiving confirmation takes up around 12 seconds and my ESP is frozen in that time. As a result, I lose the data in that time window. Is there a way to reduce the upload time of the ESP or maybe continue taking data while it is uploading?
Here is my data sending code for reference.

jsonBuffer.clear();
JsonObject &rootObject = jsonBuffer.createObject();
JsonObject &dataObject = rootObject.createNestedObject("data");
JsonArray &X1dataObject = dataObject.createNestedArray("X1");
JsonArray &Y1dataObject = dataObject.createNestedArray("Y1");
JsonArray &Z1dataObject = dataObject.createNestedArray("Z1");

if (wifiMulti.run() == WL_CONNECTED) {
  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
}

if (send_flag) {
  send_flag = false;
  int connection_iterator = 0;
  int connection_iterator2 = 0;
  for (int iterator = 0; iterator < SAMPLE_SIZE; iterator++) {
    X1dataObject.add(X1dataArray[iterator]);
    Y1dataObject.add(Y1dataArray[iterator]);
    Z1dataObject.add(Z1dataArray[iterator]);
  }

  rootObject["coreid"] = String(low, HEX) + String(high, HEX);
  //rootObject["coreid_high"] = String(high, HEX);
  rootObject["sample_time"] = int(time_taken);
  rootObject["firmware_version"] = FIRMWARE_UPDATE_VERSION;
  rootObject.prettyPrintTo(Serial);
  Serial.print("connecting to ");
  Serial.println(host);
  while ((!client.connect(host, httpsPort)) && !setup_mode) {
    connection_iterator++;
    Serial.println("connection failed! Retrying..");
    digitalWrite(LED2, HIGH);
    delay(5000);
    digitalWrite(LED2, LOW);
    delay(5000);
    if (connection_iterator >= 10)
      ESP.restart();
  }
  if (client.verify(fingerprint, host)) {
    Serial.println("certificate matches");
  } else {
    Serial.println("certificate doesn't match");
  }
  digitalWrite(LED_BUILTIN, HIGH);
  Serial.print("requesting URL: ");
  Serial.println(url);
  client.println(String("POST ") + url + " HTTP/1.0");
  client.println(String("Host: ") + host);
  client.println("Cache-Control: no-cache");
  client.println("Content-Type: application/json");
  client.print("Content-Length: ");
  client.println(rootObject.measureLength());
  client.println();
  //rootObject.printTo(client);
  Serial.println("NUMBER OF INTERRUPTS:");
  Serial.println(interruptCounter);
  Serial.println("request sent");
  while ((client.connected()) && !setup_mode) {
    connection_iterator2++;

    String line = client.readStringUntil('\n');
    if (line == "\r") {
      Serial.println("headers received");
      break;
    }
    Serial.println("Waiting for response");
    digitalWrite(LED2, HIGH);
    delay(1000);
    digitalWrite(LED2, LOW);
    delay(1000);
    if (connection_iterator2 >= 20)
      break;

  }
  String line = client.readStringUntil('\n');
  if (line.startsWith("{")) {
    Serial.println("esp8266/Arduino CI successfull!");
  } else {
    Serial.println("esp8266/Arduino CI has failed");
  }
  Serial.println("reply was:");
  Serial.println("==========");
  Serial.println(line);
  Serial.println("==========");
  Serial.println("closing connection");
  digitalWrite(LED_BUILTIN, LOW);
  // readRegister(INT_SOURCE, 1, &dummy_read);
}

In general, you would need to examine, in detail, which individual steps are taking the most time and try to find out how to reduce that. 12 seconds is enormous for sending an HTTP request and getting a reply, and the delay might be in the ESP32 code, might be in the website receiving the data, etc. Find out where most of the time is wasted and focus efforts there. (I am assuming sending data is an HTTP POST or GET, as json is not a protocol, but a structured text format.)

you send it as many small writes? https://github.com/jandrassy/StreamLib/blob/master/README.md

JSON can be very verbose. It might be easier to send a regular GET request with a few data-variable in the query string.

esp32 is dual core. you can send on one core while the other continues to capture data. it is a bit complicated to get going, but works well. Aside from that, 12 seconds seems too long, maybe you should post some code here and we might be able to speed that up.

How big is this data? 12 seconds on the lowest connection speed - say 1mbit is, and taking into account some overheads, would be over 1megabytes of data - are you really sending that much?

I don't think I'm sending that much data. It just consists of 350x3 data points from the accelerometer and some header info for the server side. I am also trying to use the other core for sending data but it is giving task wdt issues. I will post my data sending code above.

my comment applies. the rootObject.printTo writes in small pieces. wrap client into BufferedPrint from StreamLib

Hey, @Juraj will the StreamLib be able to send the rootObject as it is or I would have to store the values in a different buffer to be sent over>

And also if I use the BufferedPrint the Json encoding will be lost which I can't afford.


text:
Using signal strength feature of nRF24L01 module
This is a walkie-talkie project and this circuit really worked, voice can be transmitted from one nRF module to another nRF. Additionally, I want to observe how well the signal strength is, by lighting up an LED.

They talked about a test.RPD function here in order to do that. But it is said that we can't use this with nRF24L01, but can use only with nRF24L01P (I don't know what is the difference).

Test whether a signal (carrier or otherwise) greater than
  or equal to -64dBm is present on the channel. Valid only
  on nRF24L01P (+) hardware. On nRF24L01, use testCarrier().
  Useful to check for interference on the current channel and
  channel hopping strategies.
  @return true if signal => -64dBm, false if not
  */

Can't we use it in nRF24L01 really?
If I cannot use this how can I use the testCarrier function to light up an LED (as Bright, Low and Off) as mentioned in the quote?
If I can use this, what changes in the code should be done? (The member TmrhProjects talked about it a little)

He also hints to this code.
bool rpd = radio.testRPD();

while (radio.available()) {
  signalStrength = rpd + 1;
  radio.read, etc...
}

Should we write the above code in the RF24.h file or should we write it directly into the Arduino's main sketch?

To get the signal strength just send 100 packets with no retries and see how many times the packet arrives.
radio.begin();
radio.setRetries(0,0); // by default nrf tries 15 times. Change to no retries to measure strength

char buffer[32];
int counter = 0;

for(int i=0; i<100; i++)
{
   int status = radio.send(buffer,32); // send 32 bytes of data. It does not matter what it is
   if(status)
       counter++;

   delay(1); // try again in 1 millisecond
}

// if counter > 80 signal strength is great
{

}

// else if counter > 60 signal strength is good
{

}

// etc

radio.setRetries(5,15); change back to its default when done.

For this code to work the receiver must be listening for data. Just listen for data on the receiver there is no need to validate the data.


text:
How will Arduino sketch and Android app communicate over GPS?
How will I make Arduino with GPS communicate with an Android app? I just need this for my school project.

GPS is no used for that. To send and receive data between Arduino and Android you must use USB, Wifi or Bluetooth.

How will i make arduino with gps to communicate with android app? i just need this for my school project.

as gps is one-way communication, you will have to either launch your own birds capable of two way communications, or pick a different school.

I give you +1 danny :)

i don't think that's the actual question, even if the title is less than steller...


text:
Comparing custom variable type definitions
In a library I am using with an OBD adapter, they define a public function to get the state of the OBD connection using some strange (and, in my opinion, useless) custom defined variable type:
// states
typedef enum {
    OBD_DISCONNECTED = 0,
    OBD_CONNECTING = 1,
    OBD_CONNECTED = 2,
    OBD_FAILED = 3
} OBD_STATES;

...

// get connection state
virtual OBD_STATES getState() {
      return m_state;
}

How can I get the state into a variable such as boolean isConnected or int state so it can interact with the rest of my code? I have tried the following with no luck:
boolean isConnected = obd.getState() == OBD_CONNECTED;
if(isConnected) { ... }

int state = (int) obd.getState();
if(state == 2) { ...}

In response to your answer: why don't you think it is convenient? As you already noticed, you can use the enum values directly in your sketch.
Anyway, it is better to use a switch statement:
Serial.write("ODB State: ");
switch (odb.getState()) {
  case ODB_DISCONNECTED:
    Serial.write("Disconnected");
    break;

  case OBD_CONNECTING:
    Serial.write("Connecting");
    break;

  case OBD_CONNECTED:
    Serial.write("Connected");
    break;

  case OBD_FAILED:
    Serial.write("Failed");
    break;

  default:
    // Error case
    break;
}
Serial.write("\n");

This way, whenever the enum is changed (e.g. added items), you automatically fall into the error state, so you know you have to adapter the code.

I realize now it is actually pretty convenient. I was just used to java where I typically return some sort of integer and then provide static constants from the constructor class to compare it against.

Java has enum type too

I found the answer to my problem, but it is not very convenient.
Serial.write("ODB State: ");
OBD_STATES state = obd.getState();
if(state == OBD_DISCONNECTED) Serial.write("Disconnected");
if(state == OBD_CONNECTING) Serial.write("Connecting");
if(state == OBD_CONNECTED) Serial.write("Connected");
if(state == OBD_FAILED) Serial.write("Failed");
Serial.write("\n");


text:
Problem opening multiple text files simultaneously/in-order using <SD.h>
I am looking to log analog sensor data using 3 pins, A1, A2, A3. My project requires continuous mapping of data, and hence an SD card shield was necessary. However, I need to log the incoming data into 3 different text files, and for that purpose I assumed that opening the 3 files simultaneously might or might not be possible as indicated here (I am a beginner, so I wasn't able to comprehend everything, and I am short on resources:)
So for the time being, I worked my way around with opening the three files in order. Rather than opening them all at once,writing the data on to each file and then closing them, I did all three tasks in 1) separate functions for all three files and calling them in the loop() function, 2)keeping all the stuff in the loop() function itself.The result for method-1 was no file was ever created, and that for method-2 was only the first file was created and the rest, nope. Here's the code for both the versions. What could I be doing wrong? Thanks in advance!
My board is an Arduino Uno. Yes, I have formatted the SD card with FAT32. My wiring is in place, my code is the only possible problem I see.
Method 1
#include <SD.h>
File Cu_volt;
File Gunmet_volt;
File Al_volt;
static float volt_Cu, volt_Gunmet, volt_Al;

void setup() {
  Serial.begin(9600);
  analogReference(INTERNAL);
  pinMode(A1, INPUT);
  pinMode(A2, INPUT);
  pinMode(A3, INPUT);

  //Initialize SD card module, CS pin set at 4
  Serial.println("INITIALIZING SD CARD...");
  //check for SD errors
  if ( !SD.begin(4)) {
    Serial.println("INITIALIZATION FAIL...");
    while (1);
    return;
  }
  Serial.println("INITIALIZATION DONE");
}

void loop() {
  // read the input on analog pin 0 copper electrode:
  // Convert the analog reading (which goes from 0 - 1023) to a voltage (0 to VRef=INTERNAl)
 copperFile();
 gunmetalFile();
 aluminiumFile();
 delay(3000);

}
void copperFile() {
  Cu_volt = SD.open("Copper.txt", O_RDWR | O_APPEND);
  if (!Cu_volt) {
    Cu_volt = SD.open("Copper.txt", O_RDWR | O_CREAT);
    if (!Cu_volt) {
      Serial.println("Failed to open file at all");
    }
  }
  volt_Cu = analogRead(A1) * (1.1 / 1023.0);
  // print out the value read(COPPER):
  Serial.print("Copper voltage=");
  Serial.println(volt_Cu);
  if (Cu_volt) {
    Cu_volt.println(volt_Cu);
    Cu_volt.close();
  }
}

void gunmetalFile() {
  Gunmet_volt = SD.open("Gun_metal.txt", O_RDWR | O_APPEND);
  if (!Gunmet_volt) {
    Gunmet_volt = SD.open("Gun_metal.txt", O_RDWR | O_CREAT);
    if (!Gunmet_volt) {
      Serial.println("Failed to open file at all");
    }
  }
  volt_Gunmet = analogRead(A2) * (1.1 / 1023.0);
  // print out the value you read(GUNMETAL):
  Serial.print("Gun metal voltage=");
  Serial.println(volt_Gunmet);
  if (Gunmet_volt) {
    Gunmet_volt.println(volt_Gunmet);
    Gunmet_volt.close();
  }
}

void aluminiumFile(){
  //opening aluminium file
  Al_volt = SD.open("Aluminium.txt", O_RDWR | O_APPEND);
  if (!Al_volt) {
    Al_volt = SD.open("Aluminium.txt", O_RDWR | O_CREAT);
    if (!Al_volt) {
      Serial.println("Failed to open file at all");
    }
  }
   volt_Al = analogRead(A3) * (1.1 / 1023.0);
  // print out the value you read(ALUMINIUM):
  Serial.print("Aluminium voltage=");
  Serial.println(volt_Al);
  if (Al_volt) {
    Al_volt.println(volt_Al);
    Al_volt.close();
  }
}

Method 2
#include <SD.h>
File Cu_volt;
File Gunmet_volt;
File Al_volt;
static float volt_Cu, volt_Gunmet, volt_Al;

void setup() {
  // initialize serial communication at 9600 bits per second:
  Serial.begin(9600);
  analogReference(INTERNAL);
  pinMode(A1, INPUT);
  pinMode(A2, INPUT);
  pinMode(A3, INPUT);
  //Initialize SD card module, CS pin set at 4
  Serial.println("INITIALIZING SD CARD...");
  //check for SD errors
  if ( !SD.begin(4)) {
    Serial.println("INITIALIZATION FAIL...");
    while (1);
    return;
  }
  Serial.println("INITIALIZATION DONE");
}

void loop() {
  // read the input on analog pin 0 copper electrode:
  // Convert the analog reading (which goes from 0 - 1023) to a voltage (0 to VRef=INTERNAl)
  volt_Cu = analogRead(A1) * (1.1 / 1023.0);
  // print out the value you read(COPPER):
  Serial.print("Copper voltage=");
  Serial.println(volt_Cu);
  //opening copper file
  Cu_volt = SD.open("Copper.txt", O_RDWR | O_APPEND);
  if (!Cu_volt) {
    Cu_volt = SD.open("Copper.txt", O_RDWR | O_CREAT);
    if (!Cu_volt) {
      Serial.println("Failed to open file at all");
    }
  }
  if (Cu_volt) {
    Cu_volt.println(volt_Cu);
    Cu_volt.close();
  }
  volt_Gunmet = analogRead(A2) * (1.1 / 1023.0);
  // print out the value you read(GUNMETAL):
  Serial.print("Gun metal voltage=");
  Serial.println(volt_Gunmet);
  //opening copper file
  Gunmet_volt = SD.open("Gun_metal.txt", O_RDWR | O_APPEND);
  if (!Gunmet_volt) {
    Gunmet_volt = SD.open("Gun_metal.txt", O_RDWR | O_CREAT);
    if (!Gunmet_volt) {
      Serial.println("Failed to open file at all");
    }
  }
  if (Gunmet_volt) {
    Gunmet_volt.println(volt_Gunmet);
    Gunmet_volt.close();
  }
  volt_Al = analogRead(A3) * (1.1 / 1023.0);
  // print out the value you read(ALUMINIUM):
  Serial.print("Aluminium voltage=");
  Serial.println(volt_Al);
  //opening aluminium file
  Al_volt = SD.open("Aluminium.txt", O_RDWR | O_APPEND);
  if (!Al_volt) {
    Al_volt = SD.open("Aluminium.txt", O_RDWR | O_CREAT);
    if (!Al_volt) {
      Serial.println("Failed to open file at all");
    }
  }
 if (Al_volt) {
    Al_volt.println(volt_Al);
    Al_volt.close();
  }
  delay(3000);
}

@LookAlterno I'll check it out. Using the alternative looks like a plausible idea anyhow:)

For people having similar problems with creating multiple files on an SD card, it may be a memory issue. You need to have a certain amount of unused dynamic memory (about 300 bytes of free space, in my experience) in order to write to an SD card - and more if you are writing multiple files. Following the instructions on this page may help.

There are several variations of the SD library - some support multiple files, others do not.
Try calling .begin (and .end) on each write loop, and add in .flush - see below.
If that works with your library then take the (.begin / .end) out of the loop and try again.
#define FILENAME "myfile.txt"

void writeToFile() {
    File f;
    // begin and end on each write
    if (SD.begin(10, 11, 12, 13)) { // I use an older library that allows pin reassignment
        f = SD.open(FILENAME, FILE_WRITE);  // This will append and create if not exisiting
        if(f) {
            f.println("a string");  // Your write operations
        }
        f.flush();          // This ensured the write buffer actually went to file
                            // even if less than the block size (512b?)

        f.close();
        }
    SD.end();                   // Do this after every write operation
}


text:
Can I code in Arduino depending up on LED status?
I have to count the blinkings of an LED. For that
IF (LED = ON)
{
    COUNT=COUNT++
}
Else
{
}

Can I code like this algorithm? In Arduino is it possible?

Instead of controling led through arduino ,can we code in  arduino to read the led status as input???? Like the above theme???

In C (the language used to program Arduinos) tests require two equal signs.  Using one equal sign will assign the variable on the left side of the equal sign the value on the right side of the equal sign.  Also, when incrementing a variable you only need the two plus signs following the variable.  So "COUNT=COUNT++" should likely be "COUNT++".

if( digitalRead(ledPin)==HIGH )...?

it is a duplicate ... posted by the same person ... evidently the OP asks questions, but does not read the answers

Yes, you can make an arduino detect and count LED blinking. You will need some kind of light sensor, such as a photodiode or photoresistor.
Also, you would need to code in C++, and the example pseudo-code you presented is not C or C++.
As you proceed with your project, you may ask more questions here, of a more specific nature. As it stands, your question is very broad.

Oh really thanks sir... Can I simply connect the led to digital pins of arduino ??

You have already asked that before.

@rajiravi You will have to work out what the circuit is you are connecting to before you can know if it is possible to connect to it. Suffice it to say, probably no, you cannot connect directly to it. Someone with more knowledge probably can, but if you are asking, the answer is going to be no. Especially if it involves dismantling power company owned and installed and certified equipment.


text:
Sending a string from RPi to Arduino - Working Code
I've been researching for 2 days now trying to figure out how to receive a string via I2C on an Arduino. There are plenty of questions online but no real solutions or full tutorials... and sadly I threw my C++ book out years ago.
The code below compiles without error and receives the string correctly. (There are several commented out blocks that I've used to verify the data is being received.) The issue is printing the full received command string. I am unable to make it print in receiveEvent() or in the loop(). Ultimately I need it as a string such as "WIN-23-200" where I will explode the string by "-" to do something but I still can't get a hold of it.
If anyone can give me a nod in the right direction I'd appreciate it.
Thanks!
#include <Wire.h>

#define SLAVE_ADDRESS 0x04

volatile boolean receiveFlag = false;
char temp[32];
String command;

void setup() {
  // initialize i2c as slave
  Wire.begin(SLAVE_ADDRESS);

  // define callbacks for i2c communication
  Wire.onReceive(receiveEvent);

  Serial.begin(9600);
  Serial.println("Ready!");

}

void loop() {
  delay(1000);
  if (receiveFlag == true) {
    Serial.println("inFlag");
    Serial.println(command);
    receiveFlag = false;
  }
}

void receiveEvent(int howMany) {
  //works as expected
  /*while (0 < Wire.available()) { // loop through all
    char c = Wire.read();
    Serial.print(c);
    }*/

  int count = 0;
  while (0 < Wire.available()) { // loop through all
    temp[count] = Wire.read();
    count++;
  }
  //temp[32-1]='\0'; //make sure its 0 terminated, didn't matter
  command = temp; //put char array into a string variable named command

  Serial.print(temp); // prints nothing....

  //Verify Array is Loaded..works great.
  //for (int i = 0; i < count; i++)
  //{
  //  Serial.println(temp[i]);
  //}
  receiveFlag = true;
}

We need to see both, the sketch of the master and the sketch of the slave. Please don't use the String object and certainly not in the function receiveEvent. Don't use Serial.print from within the receiveEvent as well. The receiveEvent is an interrupt function and the Serial.print uses interrupts. Use the howMany parameter or the Wire.available to fill the temp[] array. Be sure to zero-terminate the text in the array. Set the flag. In the loop read the flag and print the temp[] array. Remove the delay from the loop, you can check the flag as often as possible. Has the text a fixed length?

Thank you very much for the talkthrough.. super helpful to know what matters especially in a new(old) language.  Got it working thanks to this.

Here's the working code.  The hangup was my Raspberry Pi Master was adding a "cmd byte" to the string before transit. So when I would send "test" the Arduino received 5 bytes; "0test".  Based on feedback here I added the null after ea char and then shifted the array to eliminate the first byte and the Serial.print started working.
Here's the working RPi Master Python code:
# -*- coding: utf-8 -*-
import smbus
import time
# for RPI version 1, use bus = smbus.SMBus(0)
bus = smbus.SMBus(1)

# This is the address we setup in the Arduino Program
address = 0x04

#http://www.raspberry-projects.com/pi/programming-in-python/i2c-programming-in-python/using-the-i2c-interface-2
def writeData(value):
    byteValue = StringToBytes(value)
    bus.write_i2c_block_data(address,0x00,byteValue) #first byte is 0=command byte.. just is.
    return -1

def StringToBytes(val):
        retVal = []
        for c in val:
                retVal.append(ord(c))
        return retVal

while True:
    print("sending")
    writeData("test")
    time.sleep(5)

    print('OPEN');
    writeData("OPEN-00-00")
    time.sleep(7)

    print('WIN');
    writeData("WIN-12-200")
    time.sleep(7)

And the Arduino Slave Code
#include <Wire.h>

#define SLAVE_ADDRESS 0x04

volatile boolean receiveFlag = false;
char temp[32];
String command;

void setup() {
  // initialize i2c as slave
  Wire.begin(SLAVE_ADDRESS);

  // define callbacks for i2c communication
  Wire.onReceive(receiveEvent);

  Serial.begin(9600);
  Serial.println("Ready!");

}

void loop() {

  if (receiveFlag == true) {
    Serial.println(temp);
    receiveFlag = false;
  }
}

void receiveEvent(int howMany) {

  for (int i = 0; i < howMany; i++) {
    temp[i] = Wire.read();
    temp[i + 1] = '\0'; //add null after ea. char
  }

  //RPi first byte is cmd byte so shift everything to the left 1 pos so temp contains our string
  for (int i = 0; i < howMany; ++i)
    temp[i] = temp[i + 1];

  receiveFlag = true;
}

Hopefully this helps someone else, I searched for along time to put this together!

A couple resources that were helpful to me as well:
bus i2c command list:
link
Raspberry Pi bus cmd paramter explained well:
link

Well done. You don't have to shift it in receiveEvent. You can do "int cmd=Wire.read();" before the first for-loop. You can use the 'cmd' or not, and use it just to read the first byte. I would just read the data into the array and solve any problem or any cmd byte in the loop. When you are printing the received data, an interrupt with new data could occur during that, and you would print the first half of old data and the second half of new data. It can be avoided by copying the temp[] to a local array while the interrupts are turned off. Can you make temp[] also 'volatile' ? just to be sure.

Just one remark: your code is safe only because the Wire library has a 32 byte buffer, otherwise it can pollute the memory. My suggestion is to change the code in one of these ways: 1) char temp[32]; becomes char temp[BUFFER_LENGTH]; (BUFFER_LENGTH is defined in Wire.h) or 2) check that howMany is less than the length of the temp buffer. 2 is more robust, but 1 does less operations

onReceive is intended for use by slaves. master must request data from slave and wait for answer. look at MasterReader example from the Wire library

sorry for posting here after years but i need some help
This is my arduino code, the raspberry pi code is the same as above.
#include <Wire.h>
#define SLAVE_ADDRESS 0x04
volatile boolean receiveFlag = false;
char temp[32];
String command;
void setup() {
// initialize i2c as slave
Wire.begin(SLAVE_ADDRESS);
// define callbacks for i2c communication
Wire.onReceive(receiveEvent);
Serial.begin(1200);
Serial.println("Ready!");
}
void loop() {
if (receiveFlag == true) {
Serial.println(temp);
if (temp == 'test'){
Serial.print("it works");
}
receiveFlag = false;
}
}
void receiveEvent(int howMany) {
for (int i = 0; i < howMany; i++) {
temp[i] = Wire.read();
temp[i + 1] = '\0'; //add null after ea. char
}
//RPi first byte is cmd byte so shift everything to the left 1 pos so temp contains our string
for (int i = 0; i < howMany; ++i)
temp[i] = temp[i + 1];
receiveFlag = true;
}
i want to make it do something like just turning on an led when the received data is test (for example).I do receive the text (test) in the serial monitor but it does nothing when i used this command
if (temp == 'test'){
Serial.print("it works");
}
any help will be appreciated

This doesn't provide an answer to the question. To ask another question, just click Ask Question above. If you wish, include a link to this question to help provide context.


text:
How to remember variable values after rebooting an Arduino Uno R3 board?
Is there any way to store the values of necessary variables somewhere (may be in a file that gets updated by the program at various events), which can be read back when program starts after rebooting the Arduino board?
I am trying to control my AC appliances using IR remote control. Where I want Arduino to remember what was on and what was off in my room after a power failure.
Using EEPROM looks like a fairly good solution, though it has a limitation of 100,000 writes which is making me try to find another way out.
Using an external EEPROM which doesn't have that limitation or is fairly big, is a really good idea I got from fuenfundachtzig, thanks for this great idea. But I don't know how to implement this in my project. Any resource to gather knowledge on using external EEPROM, will be much appreciated.

If you are only concerned about reboot, and not power cycling, then you can use RAM - you just have to keep any init code from wiping it.   Of course if you need to survive power cycling too, then you need the EEPROM.

Actually I am really concerned about the power cycling. I am trying to control my AC appliances using IR remote control. Where I want Arduino to remember what was on and what was off in my room after a power failure.

The internal RAM of the Arduino will be reset when you repower the chip, so if you want to keep your data, you need to store it in EEPROM.
If you are worried about the limited write/erase cycles, you should estimate how often the data would be updated (i.e. written to EEPROM) and how long you plan the lifetime of the device you build. If 100,000 cycles then still is an issue, you have several options:

Keep the variables in RAM and only write them to EEPROM say every 5 minutes (100,000 cycles then makes about one year of continuous usage until the EEPROM might fail).
Use an external EEPROM (in a socket) that could be easily replaced if needed.
If replacing it is not an option, consider using an FRAM instead (advantage vs EEPROM: much more erase/write cycles but also very expensive, so not an option for large amounts of data but certainly for a few variables).

Note, however, that your description sounds like a typical use-case for user settings that you don't want to get lost on reboot. For those the internal EEPROM is the right place: only store them when they're changed and you're golden -- the user won't change them a 100,000 times easily...

I usually use for this type of things an external EEPROM; something like an AT24C02 works fine for most projects (it's 256 bytes).
I just prefer external memory as it lasts more R/W cycles and because you can change it if it doesn't work anymore.

The ram is not cleared. The global variables are set to zero according to the 'c' standard. The unused ram keeps its value during a reset.

Yes, you are right. I was thinking of a power failure which leads to a loss of the data in RAM (and which makes a reinitialization necessary).

what about to use sdcard reader. is not so much expensive and sdcard will live lot of time.

adafruit seems to have FRAM for $5.  Am i missing something?

Approx. 5.5 years?

I'm really late to this party ... the 100,000 (typical) writes before fail metric on the EEPROM - isn't that count on a per bit basis? Meaning, each bit in the EEPROM can be written as a '1' about 100,000 times before a failure is expected V writing ANYTHING ANYWHERE to the EEPROM? If the former, then a cumbersome write-count tracking system could be used by adding a write-count to each block of data, along with pointers to the current block. I did say "cumbersome", but it could work, like a disk directory. Cumbersome.

EEPROM space, as already mentioned, will work if non-volatile is required. However, you have not qualified if it needs to be non-volatile or not. If not then you can use an __attribute__ to define the variable space not to be initialized. As the SRAM on the ATmega's are not cleared by reset or power cycle. The Compiler defaults to initializing them. Where this can be turned off per variable as in the below example:
//non-initialized value
union configUnion{
  uint8_t    byte[6]; // match the below struct...
  struct {
    uint16_t value1;
    uint16_t value2;
    uint16_t chksum;
  } val ;
} config  __attribute__ ((section (".noinit")));

void setup() {
  uint16_t sum;
  //Initialize serial and wait for port to open:
  Serial.begin(9600);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for Leonardo only
  }

  // prints title with ending line break
  Serial.print("Out of Reset -");
  sum = getchksum();
  printValues();

  if (sum != config.val.chksum) {
    config.val.chksum = sum;
    Serial.print("chksum is incorrect setting config.val.chksum = 0x"); Serial.println(config.val.chksum, HEX);
  }

  config.val.value1++;
  config.val.value2++;
  Serial.print("setup new values - ");
  printValues();
  config.val.chksum = getchksum();
  Serial.print("updating chksum config.val.chksum = 0x"); Serial.println(config.val.chksum, HEX);
}

int counter = 0;

void loop() {
  if (counter < 200) {
    Serial.print("after a while - ");
    printValues();
    Serial.println();
    while (true) {
      continue;
    }
  }
  counter++;
}

void printValues() {
  Serial.print(" value1 = 0x"); Serial.print(config.val.value1, HEX);
  Serial.print(", value2 = 0x"); Serial.print(config.val.value2, HEX);
  Serial.print(", sum = 0x"); Serial.print(getchksum(), HEX);
  Serial.print(", chksum = 0x"); Serial.println(config.val.chksum, HEX);
}

uint16_t getchksum() {
  int sum = 0;
  for (int position = 0; position < (sizeof(config) - sizeof(config.val.chksum)); position++) {
    sum = sum + config.byte[position];
  }
  return sum;
}

Output of above code is below. Note that the first output was the result of powering the UNO up with the Reset button depressed and then released after the Monitor window was started. Otherwise the "incorrect setting" print would have been missed, before the monitor window can be started.
Out of Reset - value1 = 0xBFED, value2 = 0xD2F9, sum = 0x377, chksum = 0xF457
chksum is incorrect setting config.val.chksum = 0x377
setup new values -  value1 = 0xBFEE, value2 = 0xD2FA, sum = 0x379, chksum = 0x377
updating chksum config.val.chksum = 0x379
after a while -  value1 = 0xBFEE, value2 = 0xD2FA, sum = 0x379, chksum = 0x379

Out of Reset - value1 = 0xBFEE, value2 = 0xD2FA, sum = 0x379, chksum = 0x379
setup new values -  value1 = 0xBFEF, value2 = 0xD2FB, sum = 0x37B, chksum = 0x379
updating chksum config.val.chksum = 0x37B
after a while -  value1 = 0xBFEF, value2 = 0xD2FB, sum = 0x37B, chksum = 0x37B

Out of Reset - value1 = 0xBFEF, value2 = 0xD2FB, sum = 0x37B, chksum = 0x37B
setup new values -  value1 = 0xBFF0, value2 = 0xD2FC, sum = 0x37D, chksum = 0x37B
updating chksum config.val.chksum = 0x37D
after a while -  value1 = 0xBFF0, value2 = 0xD2FC, sum = 0x37D, chksum = 0x37D

With this your variables will persist resets. As long as the power is not lost. Noting the above where you will get random data, to start.
Using either EEPROM or .noinit I would recommend that you checksum your persistent variable space during setup and if incorrect you can initialize or issue a warning.

If you really need to update your NVRAM frequently, look into FRAM (Ferroelectric Random Access Memory) which claims a write life of 10^13 cycles (that's ~ 318,000 years if you write once/sec!). They're 8KB, and faster than Flash or EEPROM at 20MHz (SPI).
Adafruit (in the US) sells them on a breakout board for about US$6 in onesies. Or you can buy the bare chips from the usual suppliers for around US$1.30, but not DIP, only SOP8 packages.

Store them in the on-chip EEPROM.

http://www.arduino.cc/en/Reference/EEPROM
http://www.arduino.cc/en/Tutorial/EEPROMWrite
http://www.arduino.cc/en/Tutorial/EEPROMRead

The EEPROM memory has a specified life of 100,000 write/erase cycles, so using EEPROM can be a limitation where program automatically writes values in it frequently, though, it reads them quite rare.

I am very late to this party ... I just bought an UNO WiFi and I am looking at creating a simple protocol to persist data with a data store on another device connected to the WiFi. Probably will use HTTP with simple end points, treat the remote storage as a contiguous memory block:
GET IP:port/addr/len
PUT IP:port/addr data

I could also create named blocks (think files):
GET IP:port/name
PUT IP:port/name data

The actual remote storage could be anything, memory mapped disk file, SQLite3 database, etc.
There are many drawbacks, such as reliance on the external service, connectivity issues, error handling, etc. I could run out of code space just supporting the protocol.
EDIT: I got a little flack for my answer, including downvotes, however, read the OP - he stated "somewhere" for retrieving variable data; a LAN device certainly falls in the category of "somewhere", especially when the UNO has WiFi. My answer might not be suitable for the OP, however, after reading my answer, the OP might opt to get a WiFi enabled device. I do not believe in "keyhole" solutions, but rather to provide options that fit the general tone of the question even if it means getting out of its box.

so your answer is "add WiFi and store the values on a remote server"? isn't that a little complicated if the project doesn't use WiFi for anything else?

Does EEPROM not work for you?

@Juraj - Yes, that is my answer, and yes, it is complicated if your project does not use WiFi for anything else, but as I stated in my answer, WiFi is my best solution and I offered it as yet another possible answer for certain situations, see my response for Nick Gammon

@NickGammon - The EEPROM solution is not my best solution as I cannot predict how many updates to the persisted data, both in updates and new data, so I could eventually use all of the EEPROM data and/or perform too many writes to it, effectively destroying the UNO's capability for me.

All - the OP stated: "Is there any way to store the values of necessary variables somewhere" - emphasis on "somewhere" in my answer. "Somewhere" includes on a local network, which is what my answer provides.

Re-reading your answer, it seems to me like a new question. You might want to make it one. The question asked about remembering light switch statuses after a power failure. Given that the Uno has 1024 bytes of EEPROM, and only one bit is needed to remember a on/off status, you could store 8096 statuses. Or, do some load balancing, so that after 100,000 writes to EEPROM, you switch to a new bank of bytes. I'm assuming they don't have 8096 lights in their house.

Your suggestion of using a web server, for this purpose, would cause a long delay (maybe 5 minutes) while the router and web server rebooted and became ready to answer queries. If the power went off, would you really want to wait minutes before the lights came back on? If you are trying to solve a different problem than I want Arduino to remember what was on and what was off in my room after a power failure then I suggest you make your own, new, question.

@NickGammon I am using an Arduino with a very simplified implementation of HTTP, just so the client is familiar with the API. I've obtained a Rev 3 UNO with a off-brand SD/RTC board, using a simple HTTP service that I built for another project. The service is available in seconds. The router is a different issue, but I'm looking at simple devices, these will not be exposed to anything, so even a switch would be fine.

@NickGammon The whole thing with banks in EEPROM is a lot of monkeying around. I have 75+ devices, many of them are variable, so I would need 7 bits (0-99/128) for those. I also need a table to map devices to a slot in the memory bank. Many devices will be "hot" and be updated far more often, so I could lose a whole bank because of one or two devices. And then there is testing of the bank management - which is alleviated by just moving the bank with each write instead of counting, etc. However, I don't what to have to buy a new Arduino when one fails.

@NickGammon ... And ... My question extends beyond the scope of my question. I have similar projects (need for data) for my motor home. One application will have records that could be about 50 bytes each and an unknown number of records. Another application will have records with around 120 bytes each and there could be hundreds of those and any of those could be updated.

@NickGammon Not dwell on this, but in my house with the lights/devices, the router and server would be on a UPS (SPS) with about 12 hours of power, but the lights/devices are not.

You make some good points, but you are morphing the question from what the OP wanted "I want Arduino to remember what was on and what was off in my room after a power failure" to your requirements which seem somewhat different. If you want to make a new question with these somewhat more complex requirements then we could validly discuss it further.

@NickGammon My "morph" was explaining my project and how the OP might use my method for persisting data. Everyone else should have just left it at that - I was NEVER asking for help.

This was puzzling me too. I just wanted to use the onboard button to trigger a "count up an integer" regardless any setup routines. For me, mpflaga's answer gave me the right direction. But the given example was far too complicated for my needs. So here's the bare minimum example for an integer value that survives a reset, counting up. (But NOT a power loss, as it's in RAM!) Enjoy!
uint8_t c __attribute__ ((section (".noinit")));

void setup() {
  Serial.begin(9600);
  Serial.print("Just startet. c = ");
  Serial.print(c);
  if(c>7){c=0;}else{c++;}
  Serial.println(" - Waiting for RESET.");
}

void loop() {
  // Do more stuff.
}

If you're open to a off-chip solution, it isn't too difficult to buy/build an SD card reader.

Please try to provide a more thorough answer: provide links to such SD card readers, post some sample code on how to read/write variables from it, and mention how it is better than EEPROM.

Good suggestion. SD is using a regular SPI interface. So all you need is some logic-level-conversion. Beside that you wire them directly to an Arduino. Just solder some wires to a micro-SD to SD adapter.

+jfpoilpret IMHO SD Card Readers are ubiquitous and shouldn't need examples or citation. The code is dependent on the brand of reader so no point in providing arbitrary code. I did mention how it is better than EEPROM, it isn't too difficult to buy or build.


text:
SMPTE Timecode Reader with LCD display coding question
I've managed to adapt some code from the Arduino forums to display timecode on an LCD display.
What I would like some extra help with is first is there a way of defining the one_time_max etc differently depending on the high low state of a pin? This way I could use a switch to change the times so it could switch between NTSC and PAL.
Secondly would anyone be kind enough to explain what is happening in the middle part of this code? I've made some notes but any help would be really appreciated.
Here is a picture of how it's going so far. I'll keep you guys up to date as the project continues :)
[![enter image description here][1]][1]
    // Code from forum post Dec 12, 2007

    // include the library code:
    #include <LiquidCrystal.h>

    // initialize the library with the numbers of the interface pins
    LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
    #define one_time_max 600 // these values are setup for PA video
    #define one_time_min 400
    // It's the durstion of a one and zero with a little bit of room for error.
    #define zero_time_max 1050 //
    #define zero_time_min 950 //

    #define icpPin 8 // ICP input pin on arduino
    //#define one_time_max 475 // these values are setup for NTSC video
    //#define one_time_min 300 // PAL would be around 1000 for 0 and 500 for 1
    //#define zero_time_max 875 // 80bits times 29.97 frames per sec
    //#define zero_time_min 700 // equals 833 (divide by 8 clock pulses)

    #define end_data_position 63
    #define end_sync_position 77
    #define end_smpte_position 80

    volatile unsigned int pin = 13;
    volatile unsigned int bit_time;
    // volatile instructs the variable to be stored in RAM
    volatile boolean valid_tc_word;
    // boolean can be either of two values true or false but default to false
    volatile boolean ones_bit_count;
    // boolean can be either of two values true or false but default to false
    volatile boolean tc_sync;
    // boolean can be either of two values true or false but default to false
    volatile boolean write_tc_out;
    // boolean can be either of two values true or false but default to false
    volatile boolean drop_frame_flag;
    // boolean can be either of two values true or false but default to false
    volatile byte total_bits; //this stores a an 8-bit unsigned number
    volatile byte current_bit; //this stores a an 8-bit unsigned number
    volatile byte sync_count; //this stores a an 8-bit unsigned number

    volatile byte tc[8]; //this stores a an 8-bit unsigned number
    volatile char timeCode[11]; //this stores a an 8-bit unsigned number

    /* ICR interrupt vector */
    ISR(TIMER1_CAPT_vect) {
      //ISR=Interrupt Service Routine, and timer1 capture event
      //toggleCaptureEdge
      TCCR1B ^= _BV(ICES1);
      //toggles the edge that triggers the handler so that the duration of both high and low pulses is measured.
      bit_time = ICR1; //this is the value the timer generates
      //resetTimer1
      TCNT1 = 0;
      // Ignore phase changes < time for 1 bit or > time for zero bit (zero bit phase change time is double that of 1 bit)
      if ((bit_time < one_time_min) || (bit_time > zero_time_max)) {
        // this gets rid of anything that's not what we're looking for
        total_bits = 0;
      } else {
        // If the bit we are reading is a 1 then ignore the first phase change
        if (ones_bit_count == true)
          // only count the second ones pulse
          ones_bit_count = false;
        else {
          // We have already checked the outer times for 1 and zero bits so no see if the inner time is > zero min
          if (bit_time > zero_time_min) {
            // We have a zero bit
            current_bit = 0;
            sync_count = 0; // Not a 1 bit so cannot be part of the 12 bit sync
          } else {
            // It must be a 1 bit then
            ones_bit_count = true; // Flag so we don't read the next edge of a 1 bit
            current_bit = 1;
            sync_count++; // Increment sync bit count
            if (sync_count == 12) {
              // part of the last two bytes of a timecode word
              // We have 12 1's in a row that can only be part of the sync
              sync_count = 0;
              tc_sync = true;
              total_bits = end_sync_position;
            }
          }

          if (total_bits <= end_data_position) {
            // timecode runs least to most so we need
            // to shift things around
            tc[0] = tc[0] >> 1;
            for(int n=1;n<8;n++) {
              //creates tc[1-8]
              if(tc[n] & 1) tc[n-1] |= 0x80;
              tc[n] = tc[n] >> 1;
            }
            if(current_bit == 1) tc[7] |= 0x80;
          }
          total_bits++;
        }
        if (total_bits == end_smpte_position) {
          // we have the 80th bit
          total_bits = 0;
          if (tc_sync) {
            tc_sync = false;
            valid_tc_word = true;
          }
        }
        if (total_bits <= end_data_position) {
          // timecode runs least to most so we need
          // to shift things around
          tc[0] = tc[0] >> 1;
          for(int n=1;n<8;n++) {
            //creates tc[1-8]
            if(tc[n] & 1) tc[n-1] |= 0x80;
            tc[n] = tc[n] >> 1;
          }
          if(current_bit == 1) tc[7] |= 0x80;
        }
        total_bits++;
      }

      if (total_bits == end_smpte_position) {
        // we have the 80th bit
        total_bits = 0;
        if (tc_sync) {
          tc_sync = false;
          valid_tc_word = true;
        }
      }

      if (valid_tc_word) {
        valid_tc_word = false;
        timeCode[10] = (tc[0]&0x0F)+0x30;
        // frames  this converst from binary to decimal giving us the last digit
        timeCode[9] = (tc[1]&0x03)+0x30;
        // 10's of frames this converst from binary to decimal giving us the first digit
        timeCode[8] =  ':';
        timeCode[7] = (tc[2]&0x0F)+0x30; // seconds
        timeCode[6] = (tc[3]&0x07)+0x30; // 10's of seconds
        timeCode[5] =  ':';
        timeCode[4] = (tc[4]&0x0F)+0x30; // minutes
        timeCode[3] = (tc[5]&0x07)+0x30; // 10's of minutes
        timeCode[2] = ':';
        timeCode[1] = (tc[6]&0x0F)+0x30; // hours
        timeCode[0] = (tc[7]&0x03)+0x30; // 10's of hours
        drop_frame_flag = bit_is_set(tc[1], 2);
        //detects whether theree is the drop frame bit.
        write_tc_out = true;
      }
    }

    void setup() {
      lcd.begin (16, 2);
      pinMode(icpPin, INPUT); // ICP pin (digital pin 8 on arduino) as input
      bit_time = 0;
      valid_tc_word = false;
      ones_bit_count = false;
      tc_sync = false;
      write_tc_out = false;
      drop_frame_flag = false;
      total_bits =  0;
      current_bit =  0;
      sync_count =  0;
      lcd.print("FINISHED SETUP");
      delay (1000);
      TCCR1A = B00000000; // clear all
      TCCR1B = B11000010; // ICNC1 noise reduction + ICES1 start on rising edge + CS11 divide by 8
      TCCR1C = B00000000; // clear all
      TIMSK1 = B00100000; // ICIE1 enable the icp
      TCNT1 = 0; // clear timer1
    }

    void loop() {
      if (write_tc_out) {
        write_tc_out = false;
        if (drop_frame_flag)
          lcd.print("TC-[df] ");
        else
          lcd.print("TC-NO DROP FRAME");
        lcd.setCursor(0, 1);
        lcd.print((char*)timeCode);
        lcd.print("\r");
        lcd.setCursor(11, 1);
        lcd.print("......");
        delay (30);
        lcd.clear();
      }
    }
111

  [1]: https://i.sstatic.net/V6CxE.jpg

So if a pin were to be high or low, what variables would you change? And what would you change them to?

Hiya, the values i'd want to change are the one_time_min etc. And I want to change them to the values required to decode NTSC rather than PAL

The one_time_max, one_time_min, zero_time_max and zero_time_min are all defines at the top of the file. This will insert them as constant values at compile time. This makes changing the code to deal with them slightly awkward, but not impossible.
Oddly, the one_time_max value isn't used, but the others are. To allow you to switch between PAL and NTSC, I would do the following (this is marginally lazy, but quick):

change one_time_max to ONE_TIME_MAX_NTSC and ONE_TIME_MAX_PAL so that you have two defined constants for each part. Caps is convention for defines.
create a new global variable, a boolean, that is a flag to decide if PAL or NTSC is to be decoded.
every time that one of the constant is used, use a conditional statement based on the global variable to decided which constants are used.
use the input from a button to decided the value of the global variable.

Thank you! i'll give this a go and see what happens. I don't suppose you could explain how adding the 0x0F+0x30 converts it from presumably a hex value to a decimal?

The &ing seems superfluous in this situation. 0x30 is ASCII for 0, so if you represent 0 as 0x00 and 9 as 0x9, then adding 0x30 converts to ASCII.

I am in the process of implementing exactly the same thing. The simplest way around this problem is simply to do away with the one_time_max and one_time_min variables and simply implement a mid_point value, testing the bit_time against this for one and zero values. By simply testing for a mid_point value, it allows the routine to tune itself for integer/non-integer timecode values from 24fps thorough to 30fps.

I am implementing a similar project, but my timecode reader is built into the clapperboard itself.
https://improduction.ru/tags/imslate-1/
The thing is that the bit length depends on the FPS. I just "listened" to the signal from my Zoom F8 recorder and then started the reference data. While receiving data from the cable, I simply compare them and determine the frequency. That's all.
https://improduction.ru/all/elektronnaya-hlopushka-imslate-1-pro-chtenie-taymkoda/

I see that you have a similar project.  You have nice images.  I have no idea how this attempts to address the question though.

I wrote how I solved this problem in general terms and showed what my display looks like. I determine frequencies and DF / NF in real time. But, I will not show the code


text:
Why does my sketch report too many button presses?
I've been using a button to interact with a sketch (on my Uno), and it's mostly working fine. However, sometimes it seems to be detecting multiple presses when it's only pressed once.
It's a small circuit-mounted momentary button, which is normally open. It's connected from +5V directly to an input pin. I've also added a 10K pull-down resistor on the pin to make sure the input isn't left floating.
Here's a test sketch I've been using, which reports the number of presses to the serial monitor:
    int oldState = LOW;
    int numPresses = 0;

    void setup()
    {
        pinMode(5, INPUT);
        Serial.begin(9600);
    }

    void loop()
    {
        const int newState = digitalRead(5);

        if (newState != oldState) {
            if (newState == HIGH) Serial.println(++numPresses);
            oldState = newState;
        }
    }

Sometimes when I press the button once, the serial monitor shows two presses in a row. It sometimes even reports a press when I release the button.
Is it possible to fix this? Or do I just have a faulty button or pin or something?

So it would seem as if the voltage is going weird when pressing the button... would you mind checking the voltage with a meter to see what happens? It could just be that the button creates a weird contact, and thus contacts when it shouldn't...

The meter holds steady if it's connected between +5V and Ground (although it doesn't usually show any brief spikes).

@hichris123 Multimeters only update the display a few times a second. What we're looking for only lasts a couple hundredths of a second at the longest. You really need an oscilloscope to see it. See my answer for a picture.

@sachleen Yeah, wasn't sure about that. I need an oscilloscope now (I only have a multimeter and some other stuff).

Hehe, maybe you should have rephrased your question title to something like "what are good justifications to afford an oscilloscope?" :-)

Contact Bounce
This is known as contact bounce and happens when the metal contacts in the button or switch bounce against each other when you push it. The microcontroller is fast enough to pick up these bounces and, as far as it's concerned, you're toggling the switch many times in as much as 10 milliseconds of time.
Different switches and buttons will have a different amount of contact bounce, and even one switch will behave differently between two presses.
Here's a button press captured on a scope (image from Maxim):

At 2ms/div we don't see a stable signal until 6ms after initial contact!
Solutions
Add a delay
The absolute simplest solution is to introduce a short delay after you read the button input. This will prevent the code from picking up any bounces and when it resumes, the signal should be stable.
if (digitalRead(A3) == 0) {
    // do something here
    delay(500);
}

In the example above, I delay 500ms after reading the state of the pin. The button is normally high so when I press it down, the state of the pin goes to logic 0. I pick that up in the code and do something and then wait at least 500ms before continuing.
Obviously, this code will just halt for half a second every time you push a button, which may or may not be acceptable in your application. You can decrease the amount of delay depending on the contact bounce time of your switch, too, but I play it safe here.
Ignore button presses too close to each other
Similar to the solution above but instead of adding a hard delay, you use the millis() function to keep track of when the last time the switch was triggered. Every time you see a switch trigger, you compare against the time and, if not enough time has elapsed (say like 500ms in my previous example), you ignore it.
This solves the problem of having to use delay() in your code.
Switch debouncer IC
There are things like the MAX6816 which is an IC that you put in between your switch and microcontroller input. It will denounce the signal for you. At a price of $1.62 @1k you'll probably never use this.
Other
There are many solutions to this problem... I always do it in software, but some others include using a latch or capacitor.
Debounce Code – one post to rule them all

thanks, I'm learning and this was driving me nuts!

The button contacts themselves are probably bouncing in and out of contact, which is causing the circuit to open and close multiple times, even though the button position isn't changing.
It's a common problem with buttons and would be the first thing I would check. In order to fix this, you need to de-bounce the button. There are various ways in which to accomplish this, some of which can be done in the sketch itself.
A good solution is code that measures the duration of each button state and only registers a change in state if the current duration is greater than the desired duration. That option should be used for more complex projects. The code for it will be project specific and likely use sketch defined variables, but an example of what needs to be done can be found here.
If the sketch is very basic or you just want to make sure that bounce is the problem, you can add a short delay after the button state changes. For example:
void loop()
{
    const int newState = digitalRead(5);

    if (newState != oldState) {
        if (newState == HIGH) Serial.println(++numPresses);
        oldState = newState;
        delay(10) //Adjust the delay length to be as short as possible without triggering errors
    }
}

This is your button bouncing which is quite usual behavior; it has nothing to do with button quality.
There are 2 ways to "debounce" a button: by hardware or by software.
Personally, I prefer by hardware; just google for button debouncing circuit and you should find many examples.
If you don't have the necessary components available, you can use software debouncing.
By software, you have an example here on Arduino web site.

Some buttons bounce much more than others, so it does have something to do with button quality.

@sachleen I am not sure I would say so; it essentially depends on the metal used for the contacts in the button. I don't think one could find a non-bouncing button under all situations. Switch bouncing is to be expected, and will bite you in particular if your sketch runs quickly between 2 digitalRead() calls.

Also bouncing will depend on how the button is pushed (e.g. what force is applied to it and how).

Though the phenomenon is called contact-bounce, "looks" electrically like "bouncing" (and may in fact involve some actual "bouncing"), in a mechanical switch, the contacts never approach/depart each other totally squarely; there is unavoidably some degree of sliding, one over the other. The sliding of rough surfaces is what gives rise to the make-break-make... phenomenon, even when if contacts don't actually "bounce". (Think of one sort-of-smooth rock sliding against another). Note that this also means contact break will involve break-make-break..., as well.