text:
Overflow while working with SD library
i am currently working on a Project with an SD card. I want to open a .csv-file on my sd card (later it should be the last file) and then read the ID that is at the start of the .csv-file.
Yesterday it worked like a charm but now i get -1 as output for every read() or peek() i use. I cant seem to work out the problem. It could probably be anything in my code but i hope the error lies in this function
Any help is very appreciated.
This is my function:
unsigned int EKG_recording::get_record_from_SD(File dir)
{
  Serial.println("Its in the function\n");
  //dir.rewindDirectory();
  File entry = dir.openNextFile();

  Serial.println(entry.name());

  if (entry)
  {
    first_digit = entry.read(); //ASCII CODE
    Serial.println("one digit:");
    Serial.println(first_digit);

    Serial.println("peek:");
    Serial.println(entry.peek());

    if (entry.peek() == seperator) { // Check if next Byte ";"
      Serial.println("one digit");
      Serial.println((first_digit - '0'));
      return (first_digit - '0');
    }

    second_digit = entry.read();
    Serial.println("2 digit:");
    Serial.println(second_digit);

    Serial.println("peek:");
    Serial.println(entry.peek());

    if (entry.peek() == seperator) { // Check if next Byte ";"
      all_digits = (first_digit - '0') * 10 + (second_digit - '0') ;
      Serial.println("two digits");
      Serial.println(all_digits);
      return (all_digits);
    }

    third_digit = entry.read();
    Serial.println("3 digit:");
    Serial.println(third_digit);

    Serial.println("peek:");
    Serial.println(entry.peek());

    if (entry.peek() == seperator) { // Check if next Byte ";"
      all_digits = (first_digit - '0') * 100 + (second_digit - '0') * 10 + (third_digit - '0');
      Serial.println("Three digits");
      Serial.println(all_digits);
      return (all_digits);
    }
  }
  else {
    Serial.println("No File found");
  }

  entry.close();

}

I think i get some kind of overflow because all Serial.prints return -1
13:20:09.630 -> Its in the function
13:20:09.630 ->
13:20:09.630 -> /System Volume Information
13:20:09.630 -> one digit:
13:20:09.630 -> -1
13:20:09.630 -> peek:
13:20:09.630 -> -1
13:20:09.630 -> 2 digit:
13:20:09.630 -> -1
13:20:09.630 -> peek:
13:20:09.630 -> -1
13:20:09.630 -> 3 digit:
13:20:09.630 -> -1
13:20:09.630 -> peek:
13:20:09.630 -> -1
13:20:09.630 ->

This are my variables for the function
//Funktion get_record_id
     int first_digit = 0;
     int second_digit = 0;
     int third_digit = 0;
     int all_digits = 0;
    unsigned int seperator = 59;

I call the function like this. I dont create folders or anything on the SD-Card, it just contains .csv-files
File root = SD.open("/");
  EKG_recording_1.get_last_record_from_SD(root);

Here is the CardInfo Example for ESP32
17:14:22.777 -> SD Card Type: SDHC
17:14:22.777 -> SD Card Size: 7624MB
17:14:22.777 -> Listing directory: /
17:14:22.777 ->   DIR : /System Volume Information
17:14:22.777 ->   FILE: /1.CSV  SIZE: 9060
17:14:22.811 ->   FILE: /2.CSV  SIZE: 9060
17:14:22.811 ->   FILE: /3.CSV  SIZE: 9056
17:14:22.811 ->   FILE: /4.CSV  SIZE: 9056
17:14:22.811 -> Creating Dir: /mydir
17:14:22.913 -> Dir created
17:14:22.913 -> Listing directory: /
17:14:22.913 ->   DIR : /System Volume Information
17:14:22.913 ->   DIR : /mydir
17:14:22.913 ->   FILE: /1.CSV  SIZE: 9060
17:14:22.913 ->   FILE: /2.CSV  SIZE: 9060
17:14:22.946 ->   FILE: /3.CSV  SIZE: 9056
17:14:22.946 ->   FILE: /4.CSV  SIZE: 9056
17:14:22.946 -> Removing Dir: /mydir
17:14:22.980 -> Dir removed
17:14:22.980 -> Listing directory: /
17:14:22.980 ->   DIR : /System Volume Information
17:14:22.980 -> Listing directory: /System Volume Information
17:14:22.980 ->   FILE: /System Volume Information/WPSettings.dat  SIZE: 12
17:14:22.980 ->   FILE: /System Volume Information/IndexerVolumeGuid  SIZE: 76
17:14:23.013 ->   FILE: /1.CSV  SIZE: 9060
17:14:23.013 ->   FILE: /2.CSV  SIZE: 9060
17:14:23.046 ->   FILE: /3.CSV  SIZE: 9056
17:14:23.046 ->   FILE: /4.CSV  SIZE: 9056
17:14:23.046 -> Writing file: /hello.txt
17:14:23.046 -> File written
17:14:23.080 -> Appending to file: /hello.txt
17:14:23.113 -> Message appended
17:14:23.113 -> Reading file: /hello.txt
17:14:23.113 -> Read from file: Hello World!
17:14:23.113 -> Deleting file: /foo.txt
17:14:23.113 -> Delete failed
17:14:23.113 -> Renaming file /hello.txt to /foo.txt
17:14:23.146 -> File renamed
17:14:23.146 -> Reading file: /foo.txt
17:14:23.146 -> Read from file: Hello World!
17:14:23.146 -> Failed to open file for reading
17:14:32.208 -> 1048576 bytes written for 9036 ms
17:14:32.208 -> Total space: 7604MB
17:14:32.208 -> Used space: 1MB

/System Volume Information -- Is that really the file you want to open...?

I dont even know what this is. I want to open the main folder so "/". Do you know what /System Volume Information is or how i can open the root folder? I never had that name thats why i put it in there

Ok it seems like there is some invisible folder on my sd card that i cant delete. I already formated the sd card. It still shows up. I think i will just test if the dir.openNextFile() chatches a folder or a file

That file is created by Windows for storing extended attribute information.

Well how can i work around this problem? Always delete System Volume Information at the beginning or what should i do?
while(entry.isDirectory()){     entry = dir.openNextFile();   }
Ok i just used this to test if i get a folder from dir.openNextFile(), now i get correct return values again

SD library doesn't use long file names. run the CardInfo example

I edited it to the Main post

try unsigned int EKG_recording::get_record_from_SD(File& dir)


text:
Flashing a specified digit 4x7 segment display and shift register 74HC595N
I have a project that is simply a relay timer. The code is not complete so you will see 'in progress' sections not related to my question in my code.
However, my question is...
I am creating a timer with 4 x 7 segment display using a rotary encoder to set the time. I have 3 'Modes' that allow me to increment the time by 1 second, 10 seconds and minutes. All this is working correctly however when I switch modes I would like to flash the corresponding digit to give a kind of visual feedback showing what mode you are in (the first digit for seconds, the second for 10 seconds etc..). I can manually ground the corresponding common pin to create that effect manually, however, I am having trouble with the code.
I have tried creating for loops that digitalwrite() to the specific comPin, however, this is just turning the entire display off and on. The section of code that I am looking at is roughly halfway down.
The Bonus Question: I would like the Dp to illuminate between the second and third digits to show "min:sec". I assume this must be to do with my byte table, however, this is all new to me and I am not sure of what direction to go regarding changes.
#include <MD_REncoder.h>

int LightClocksec = 0;
int LightClockmin = 0;

int LightClockAdd = 1;
int Mode = 0;
boolean LightSW = 5;

int EncoderSW = 4;
boolean EncoderSWstate = 0;
MD_REncoder R1 = MD_REncoder(2, 3);

int FocusSW = 13;
boolean FocusSWstate = 0;
boolean FocusSWstatePRE = 0;
int FocusSWCounter = 0;

int MainSW = 14;
boolean MainSWstate = 0;
boolean MainSWstatePRE = 0;

int RelayPIN = 15;
boolean Relaystate = LOW;

unsigned long millispre = 0;

int buttonPushCounter = 0;   // counter for the number of button presses
int lastButtonState = 0;     // previous state of the button

int latchPin = 7;          // Pin connected to ST_CP of 74HC595（Pin12）
int clockPin = 8;          // Pin connected to SH_CP of 74HC595（Pin11）
int dataPin = 6;           // Pin connected to DS of 74HC595（Pin14）
int comPin[] = {12, 11, 10, 9};// Common pin (anode) of 4 digit 7-segment
display

byte num[] = {0xc0, 0xf9, 0xa4, 0xb0, 0x99, 0x92, 0x82, 0xf8, 0x80, 0x90,
0x88, 0x83, 0xc6, 0xa1, 0x86, 0x8e};

void setup() {
  //  Serial.begin(9600);
  R1.begin();
  pinMode (LightSW, OUTPUT);
  pinMode (RelayPIN, OUTPUT);

  pinMode (EncoderSW, INPUT);
  pinMode (FocusSW, INPUT);

  pinMode(latchPin, OUTPUT);
  pinMode(clockPin, OUTPUT);
  pinMode(dataPin, OUTPUT);

for (int i = 0; i < 4; i++) {
  pinMode(comPin[i], OUTPUT);
  }

}

void loop() {

  ///set time, encoder..

  EncoderSWstate = digitalRead(EncoderSW);

  uint8_t z = R1.read();
  if (z) {
    if (EncoderSWstate == 0) {
      if ((Mode == 2) )
      {
        z == DIR_CW ? LightClockmin ++  : LightClockmin --;
      }
      else if (Mode == 1) {
        z == DIR_CW ? LightClocksec = LightClocksec + 10  : LightClocksec = LightClocksec - 10 ;
        if (LightClocksec >= 60) {
          LightClocksec = (LightClocksec - 60);
          LightClockmin ++;
        }
        if ((LightClocksec < 0) && (LightClockmin >= 1 )) {
          LightClocksec = (60 - LightClockAdd) ;
          LightClockmin --;
        }
      }
      else if (Mode == 0) {
        z == DIR_CW ? LightClocksec ++  :  LightClocksec --;
        if (LightClocksec >= 60) {
          LightClocksec = (LightClocksec - 60);
          LightClockmin ++;
        }
        if ((LightClocksec < 0) && (LightClockmin >= 1 )) {
      LightClocksec = (60 - LightClockAdd) ;
      LightClockmin --;
    }
  }
  LightClocksec = constrain(LightClocksec, 0, 59);
  LightClockmin = constrain(LightClockmin, 0, 59);
}

if (EncoderSWstate == 1) {
  z == DIR_CW ? Mode -- : Mode ++ ;
  Mode = constrain(Mode, 0, 3);
  if (Mode == 0) {
    ////////STACK EXCHANGE?//// FLASH first digit on and off 5 times
  }

  if (Mode == 1) {
    ////////STACK EXCHANGE?//// FLASH second digit on and off 5 times
  }
  if (Mode == 2) {
   ////////STACK EXCHANGE?////  FLASH 3rd Digit On and of 5 times
  }
   }
 }

  ////switching

  FocusSWstate = digitalRead(FocusSW);
  MainSWstate = digitalRead(MainSW);

  if (FocusSWstate != FocusSWstatePRE ) {
    if (FocusSWstate == HIGH) {
      FocusSWCounter++;
    } else {}
  }

  FocusSWstatePRE  = FocusSWstate;
  if (FocusSWCounter % 2 == 0) {
    digitalWrite(RelayPIN, LOW);
  } else {
    digitalWrite(RelayPIN, HIGH);
  }

  if (MainSWstate != MainSWstatePRE ) {
    if (MainSWstate == HIGH) {
      digitalWrite(RelayPIN, HIGH);
      delay(((LightClockmin * 60) + (LightClocksec)) * 1000);
      digitalWrite(RelayPIN, LOW);
    }
    else {}
  }
  MainSWstatePRE  = MainSWstatePRE;

  //display

  byte bit[4];
  bit[0] = LightClocksec % 10;
  bit[1] = LightClocksec / 10 % 10;
  bit[2] = LightClockmin % 10;
  bit[3] = LightClockmin / 10 % 10;

  for (int i = 0; i < 4; i++) {
    chooseCommon(i);
    writeData(num[bit[3 - i]]);
    writeData(0xff);
  }
 }

void chooseCommon(byte com) {
  // Close all single 7-segment display
  for (int i = 0; i < 4; i++) {
    digitalWrite(comPin[i], LOW);
  }
  // Open the selected single 7-segment display
  digitalWrite(comPin[com], HIGH);
}

void writeData(int evalue) {
  // Make latchPin output low level
  digitalWrite(latchPin, LOW);
  // Send serial data to 74HC595
  shiftOut(dataPin, clockPin, LSBFIRST, evalue);
  // Make latchPin output high level, then 74HC595 will update the data to parallel output
  digitalWrite(latchPin, HIGH);
}

You kind of already know the answer. To turn on a specific segment you manually connected it to ground. But in your code you are setting the segment you want to HIGH, and al the segments you don’t want to LOW (I.e. ground). Change HIGH to LOW, and LOW to HIGH in your chooseCommon function.

I'm having trouble specifying the specific common, I think that's the trouble.
I have tried the following code, but its just turning the entire display off, and not just comPin[0] as i thought it should. I can't post it all here cause of length so ill stick it in another comment.

if (Mode == 0) {     byte bit[4];     bit[0] = LightClocksec % 10;     bit[1] = LightClocksec / 10 % 10;     bit[2] = LightClockmin % 10;     bit[3] = LightClockmin / 10 % 10;      chooseCommonblink(0);       writeData(num[bit[0]]);       writeData(0xff);    }
and then after my void loop():
void chooseCommonblink(byte com) {   digitalWrite(comPin[com], LOW);   delay(50);   digitalWrite(comPin[com], HIGH);   delay(50);   digitalWrite(comPin[com], LOW);   delay(50);   digitalWrite(comPin[com], HIGH); }

It seems you have a common cathode, but the code is for a common anode. Or do you have some transistors on those pins?

ok, well, I just looked up the code off my display and your right, I have a common cathode I bought as an undefined replacement for an old one that was included in a kit that is now living in another project, that one had a common anode.
Well, the displaying is working as i think it should, lighting up correctly etc. now I'm not sure how that is possible?

When displaying the digits you need to compare the current digit number (i) with the digit number you want to flash. If it's a match then either display the number, or don't display the number. How you make that decision is to examine millis().
Take a look at the BlinkWithoutDelay example in the IDE to see how to make something flash without using delay(), and apply that knowledge to blinking a digit.

I have used 'millis()' / 'BlinkWithoutDelay' in other projects so understand that process. What I am looking at is just creating an interrupt with 5 flashes as the mode changes so normal delays are not an issue for me. The trouble I'm having is "comparing the current digit number" as you say or allocating the correct comPin for a digitalWrite LOW/HIGH sequence.  Sorry, if my terminology is a bit off, i hope you inderstand what im getting at.

This line: writeData(num[bit[3 - i]]); - compare i with your selected digit, and if it matches then either run that line or don't depending on a "blink" variable controlled by millis().

source: Stack Exchange

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

sort: votes


text:
Multiple threshold crossings trigger multiple LEDs - but only one at a time
I'm calculating the acceleration magnitude vector from an accelerometer inside a thick PU mat. When the mat is hit, depending on the value I obtain, only one of two LEDs, later more, shall light up briefly. However, because the low(er) threshold(s) is(are) inevitably always crossed first, stronger hits mean both(all) LEDs light up, not only the single one that corresponds to the highest threshold crossed at the time. I hope the image explains the issue. Somehow, I would need to look ahead if, when a lower threshold is crossed, a higher one may be crossed right after, maybe an even higher one. How must I change/augment the code?

  mAV = sqrt(ax * ax + ay * ay + az * az) - valueShift;

  if (mAV < 0)
  {
    mAV = 0;
  }

  mAVEMA = (alphaEMA * mAV) + ((1 - alphaEMA) * mAVEMA);

  Serial.print("mAVEMA:"); Serial.println(mAVEMA);

  if (mAVEMA >= thresholdC && previousmAVEMA < thresholdC)
  {
    digitalWrite(pinLEDR, HIGH);
    timeLEDROn = timeNow;
  }

  if (mAVEMA >= thresholdB && previousmAVEMA < thresholdB)
  {
    digitalWrite(pinLEDY, HIGH);
    timeLEDYOn = timeNow;
  }

  previousmAVEMA = mAVEMA;

  if (digitalRead(pinLEDY) == HIGH && timeNow - timeLEDYOn >= timeLEDOn)
  {
    digitalWrite(pinLEDY, LOW);
  }

  if (digitalRead(pinLEDR) == HIGH && timeNow - timeLEDROn >= timeLEDOn)
  {
    digitalWrite(pinLEDR, LOW);
  }

Edit: Getting closer to the desired behaviour https://wokwi.com/projects/406459026144282625
const int pinAccel = A0; // simulate acceleration magnitude vector
const int pinsLED[] = {11, 12, 13}; // yellow, orange, red
const int threshold0 = 300;
const int threshold1 = 600;
const int threshold2 = 900;
const unsigned long timeSearch = 200;
const unsigned long timeLEDsOn = 500;

int mAVEMA = 0;
int active = -1;
unsigned long timersLED[] = {0, 0, 0};

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

  for (byte i = 0; i < 3; i++)
  {
    pinMode(pinsLED[i], OUTPUT);
  }
}

void loop()
{
  unsigned long timeNow = millis();

  mAVEMA = analogRead(pinAccel);
  int threshold = checkThresholds(mAVEMA);

  // only on rising signal
  if (threshold == 0)
  {
    unsigned long timerStart = millis();
    active = 0;
    timersLED[active] = millis();

    while (millis() - timerStart < timeSearch) // timeSearch user adjustable?
    {
      mAVEMA = analogRead(pinAccel);
      threshold = checkThresholds(mAVEMA);

      if (threshold == 1)
      {
        active = 1;
        timersLED[active] = millis();
      }

      if (threshold == 2) // reset to 0 once one of the three LEDs was lit
      {
        active = 2;
        timersLED[active] = millis();
      }
    }
    digitalWrite(pinsLED[active], HIGH);
  }

  if (timeNow - timersLED[active] >= timeLEDsOn)
    {
    digitalWrite(pinsLED[active], LOW);
    }

  delay(10); // Only for serial monitor/plotter
}

int checkThresholds(int accel) // later floats for real accelerometer!
{
  if (mAVEMA >= threshold2) return 2;
  if (mAVEMA >= threshold1) return 1;
  if (mAVEMA >= threshold0) return 0;
  return -1;
}

insert a layer of separation between the signal detection and the lighting of the LEDs ... when signal is detected, set a flag variable,  nothing else ... light the LEDs in response to the value of the flag variables, not in response to the signal

@jsotola Separated, see edit, but to no avail. I feel that I need to take the time of when the lowest threshold is crossed by the rising signal, and then wait to see if a higher threshold is crossed, and then wait to see if yet another higher threshold is crossed - and then set the corresponding LED pin to HIGH. But how to wait and for how long?

you're just blindly turning on the LEDs ... think about how the LEDs should behave

Well, I did, as the explanatory graphic shows; only when the signal is rising: thresholdA -> LEDA, thresholdB -> only LEDB, thresholdC -> only LEDC, and so forth. The problem is that when, for example, thresholdC is crossed, thresholdA and thresholdB are inevitably crossed beforehand.

why are you lighting pinLEDY when crossedC is true? ... you have no logic that prevents that ... you already know the state of all of the flag variables when it is time to light the LEDs

Are these leds only for a visual indication of the impact on this mat or are you later going to attempt to extract the led on periods into a calculation ?
Assuming the simple case and looking at your sample, I'd probably wait until a rising edge crossed the lowest threshold and start a 30ms timer. Keep measuring the maximum value while the timer is running then, on expiry of the timer, light the appropriate led for X ms. The start of the led indication will slightly lag the peak by a few ms.

@6v6gt Only for a visual indication of jab, left hook and right cross, a fun exercise project, by no means scientific. I updated the Edit above with something that works for one, the lowest, threshold. Now it's about the waiting time, the timer, as you say. Also I need to look at Edgar Bonet's implementation below.

I think chrisl's solution (let the LED change as you cross higher
thresholds) is the simplest and probably the most effective for your
problem. If you really want only one LED to light for each punch, then
you will have add a delay. I would implement this using a finite state
machine as follows:
The system can be in one of three states:

IDLE: the acceleration is below the first threshold, and all LEDs are
off

WAITING: a threshold has just been crossed, and the Arduino is waiting
some time for a higher threshold to be also crossed

LIT: one LED is on, and stays on for a fixed time

When in the WAITING state, if a higher threshold is indeed crossed, the
timer is reset in order to wait for the next threshold. If the timer
expires, an LED is lit and we go to the LIT state.
The state diagram:

For programming this, I would use this helper function:
/*
 * The punch "level" is:
 *   (0, 1 or 2) if the acceleration reaches the threshold (A, B or C)
 *   -1 otherwise
 */
int get_level(float accel)
{
    if (accel >= threshold_C) return 2;
    if (accel >= threshold_B) return 1;
    if (accel >= threshold_A) return 0;
    return -1;
}

And here is the code for the state machine:
enum { IDLE, WAITING, LIT } state;
int punch_level = -1;
uint32_t timer_start;

void loop() {
    float accel = get_acceleration();
    int level = get_level(accel);
    int32_t now = millis();
    switch (state) {
        case IDLE:
            if (level >= 0) {  // a threshold has been crossed
                punch_level = level;
                state = WAITING;
                timer_start = now;
            }
            break;
        case WAITING:
            if (level > punch_level) {  // crossed a higher threshold
                punch_level = level;
                timer_start = now;
            }
            if (now - timer_start >= wait_timeout) {
                digitalWrite(led_pins[punch_level], HIGH);
                state = LIT;
                timer_start = now;
            }
            break;
        case LIT:
            if (now - timer_start >= light_timeout) {
                digitalWrite(led_pins[punch_level], LOW);
                state = IDLE;
            }
            break;
    }
}

Thanks, I began with a state machine, and failed miserably. I will study your suggestion.

Thanks, again; I put your suggestion in WOKWI https://wokwi.com/projects/406583203546521601 to try it out and understand the logic, but it is not working. Do you mind having another look?

With your helper function idea, I got closer to the desired system behaviour, see edit in original question. Still needs testing for rising edge only.

@Systembolaget digitalWrite(led_pins[level], HIGH); I believe that instead of level what as meant here is punch_level since that retains the highest value of level seen in the session. And it is the same when you are switching off the led. Very elegant solution by the way.

@6v6gt Indeed, you are right. Still, LEDs illuminate when the signal is falling. I have that issue also in my attempt in the Edit. Nothing must respond on a falling signal. I must additionally implement that "oldvalue newvalue thing" for a rising signal I suppose.

@6v6gt: Good catch, thanks! Fixed.

@Systembolaget: From my tests, your wokwi simulation works perfectly well. No lights on falling edges. With one caveat: the punch has to last less than light_timeout (300 ms), which doesn't seem unreasonable, but is hard to achieve with the mouse and the simulated pot.

As a kluge, add a delay(3000) after switching the led off. Better would be to add a new state say LOCKOUT.   Edit. Post crossed with Edgar.

The punches I observed came in under 300 milliseconds, and only a trained person can throw a 3-punch combination in one second. It works well now, the graphic helped me to understand what must/must not happen and when. Thanks for your solution! I still want to get my own approach right now ; )

As you are sampling an analog signal, you will cross the lower threshold first. That cannot be changed. But it might be enough to only light the currently relevant LED, turning all others off, like the following form:
if(mAVEMA >= thresholdC){
  digitalWrite(pin_led_c, HIGH);
  digitalWrite(pin_led_b, LOW);
} else if (mAVEMA >= thresholdB) {
  digitalWrite(pin_led_c, LOW);
  digitalWrite(pin_led_b, HIGH);
}

Or, if you want to generalize for more thresholds you can also turn off all LEDs, then check for the thresholds and turn the corresponding LED on:
// on global scope
int pin_led[] = {4,5,6}; //defining all LED pins in order
int N_LEDs = sizeof(pin_led)/sizeof(pin_led[0]) // getting number of LEDs
int threshold[] = {100, 200, 500}; //defining all thresholds in order

// in your measurement function or in loop()
for(int i=0;i<N_LEDs;i++) digitalWrite(pin_led[i], LOW); //turning all LEDs off
for(int i=N_LEDs-1;i>0;i--){ //looping backwards through thresholds
  if(mAVEMA >= threshold[i]){ //checking from highest to lowest threshold
    digitalWrite(pin_led[i], HIGH);
    break; // breaking, since threshold was met
  }
}

Note, that this will light up the LED for the lower threshold briefly in the time, that the signal spends between both thresholds. When the higher threshold is reached, the LED for the lower one is turned off again.
If you don't want that, you need to change how you handle your measurements. As you cannot look into the future, you need to change your simple threshold measurements to a peak detection algorithm. How you implement it depends on your requirements, though it will always mean, that the LEDs turn only on shortly after the peak (otherwise you cannot know, if it is a peak). For example you can check, if the value sinks below its current maximum value (in a defined time frame) for a specific minimum time, so checking the maximum in 500ms and checking, if the value sank at least 100 points in 100ms after the maximum was reached.

Thanks, so it's like: timestamp when lowest thresholdA is crossed -> wait for possibly higher threshold crossings until signal peak was detected -> only then switch on the LED for the highest threshold crossed.
A trained boxer can throw a jab, left hook and right cross in one second, and impact time is up to 200 milliseconds on a slow punch, so that should be my "wait and see" threshold sampling window, right?

Edited original question with a partial solution, I think. But now comes the part to wait for possibly higher thresholds, before the signal peak is reached. The Edit code should work in WOKWI.

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


text:
PMS5003 Serial Output Data to SD Issues
I'm trying to save the output of an air quality sensor to a SD card, but I'm having a few issues.
The sensor I'm using is a Plantower PMS5003 which puts out its data via serial. I've heavily tweaked the example sketch from Adafruit (here) as I'd like to use the Low Power library to sleep the unit, take a sample and note the time, write it to SD, then return to sleep.
I am getting the timestamp written no issue, but the data is coming out repeated as below:
22:13:10 - 34,55,61
22:13:18 - 34,55,61
22:13:27 - 34,55,61
22:13:36 - 34,55,61
22:13:44 - 34,55,61
22:13:53 - 34,55,61
22:14:1 - 34,55,61
22:14:10 - 34,55,61
22:14:18 - 34,55,61
22:14:27 - 34,55,61
22:14:35 - 34,55,61
22:14:44 - 34,55,61

The 8s timer appears to be working fine, but the repetition of data has me confused. I've tried adding delays and the like in case it was a lack of data but when I run that example sketch it comes screaming in over serial.
I also ditched using the software serial as I couldn't get it to stop messing with the low power library, it wouldn't ever sleep.
That and any general advice on the sketch is appreciated, it seems like its not the best way to accomplish this.
#include "LowPower.h"
#include <SdFat.h>
#include "RTClib.h"
#include <Wire.h>

SdFat SD;
RTC_DS3231 rtc;

File test;
String tString = "";
String sString = "";

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

  pinMode(10, OUTPUT);

  if (!rtc.begin()) while (1);

  if (!SD.begin(10)) while (1);
}

struct pms5003data {
  uint16_t framelen;
  uint16_t pm10_standard, pm25_standard, pm100_standard;
  uint16_t pm10_env, pm25_env, pm100_env;
  uint16_t particles_03um, particles_05um, particles_10um, particles_25um, particles_50um, particles_100um;
  uint16_t unused;
  uint16_t checksum;
};

struct pms5003data data;

void loop() {
  //LowPower.idle(SLEEP_8S, ADC_OFF, TIMER2_OFF, TIMER1_OFF, TIMER0_OFF, SPI_OFF, USART0_OFF, TWI_OFF);
  LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF);

  DateTime now = rtc.now();
  test = SD.open("test.txt", FILE_WRITE);

  tString = String(now.hour()) + ":" + String(now.minute()) + ":" + String(now.second()) + " - ";

  readPMSdata(&Serial);
  sString = String(data.pm10_standard) + "," + String(data.pm25_standard) + "," + String(data.pm100_standard);

if (test) {
  test.print(tString);
  test.println(sString);
  test.close();

  delay(250);
}
}

boolean readPMSdata(Stream *s) {
  if (! s->available()) {
    return false;
  }

  // Read a byte at a time until we get to the special '0x42' start-byte
  if (s->peek() != 0x42) {
    s->read();
    return false;
  }

  // Now read all 32 bytes
  if (s->available() < 32) {
    return false;
  }

  uint8_t buffer[32];
  uint16_t sum = 0;
  s->readBytes(buffer, 32);

  // get checksum ready
  for (uint8_t i = 0; i < 30; i++) {
    sum += buffer[i];
  }

  //debugging
  for (uint8_t i = 2; i < 32; i++) {
    Serial.print("0x"); Serial.print(buffer[i], HEX); Serial.print(", ");
  }
  Serial.println();

  // The data comes in endian'd, this solves it so it works on all platforms
  uint16_t buffer_u16[15];
  for (uint8_t i = 0; i < 15; i++) {
    buffer_u16[i] = buffer[2 + i * 2 + 1];
    buffer_u16[i] += (buffer[2 + i * 2] << 8);
  }

  // put it into a nice struct :)
  memcpy((void *)&data, (void *)buffer_u16, 30);

  if (sum != data.checksum) {
    Serial.println("Checksum failure");
    return false;
  }
  // success!
  return true;
}

add Serial output to the question. are you sure that the 3 values you log are changing?

Yeah they can change quite wildly in the basic example sketch if I introduce smoke to the sensor.

You don't use the return value to check if the data was valid. If the function readPMSdata returns false, write an error message instead of the wrong data. The normal way is to store every received byte in a buffer instead of waiting for 32 bytes. For 9600 baud with an arduino uno, you can try the AltSoftSerial. Which arduino board do you use?

See I had wondered about buffer, and I recall a much different method offered for serial data on the Arduino forum itself in one of the long tutorials.
Using a regular 328 arduino at the moment, likely stick with the 328 if I move this away from the arduino. Do have quite a few alternates around however.

AltSoftSerial was a god send as well, its at least allowing the LowPower library to function as desired during this debug period

There is a mismatch in the code.
The Arduino loop function assumes that readPMSdata needs to be called just once for valid data but the function readPMSdata itself assumes that it will be called over and over again until a enough bytes are received and are valid.
The solution is to let the Arduino loop call readPMSdata over and over again, until it has valid data. It returns true when it has valid data, so that can be used in a if statement.
This might cause troubles with the rest of the code in the loop. The delay(250); may no longer be used and I don't know the best place to go into sleep mode. Therefor I removed the powerdown.
void loop() {
  if( readPMSdata(&Serial))        // call it many times to collect data
  {
    // there is valid data from the sensor
    DateTime now = rtc.now();
    test = SD.open("test.txt", FILE_WRITE);

    tString = String(now.hour()) + ":" + String(now.minute()) + ":" + String(now.second()) + " - ";

    sString = String(data.pm10_standard) + "," + String(data.pm25_standard) + "," + String(data.pm100_standard);

    if (test) {
      test.print(tString);
      test.println(sString);
      test.close();
  }
}

This I had not considered at all! I do love Adafruit for what they do, but they leave quite a bit unexplained in the long run. But the moment I read the post my mind started ticking on more appropriate ways to go about this.
Thank you!

So I'm having a bit of trouble figuring this out, how would you recommend looping readPMSdata until I get the data?

@BWulf, I have added it to my answer. Reading serial input and going to sleep don't go well together.


text:
Atmega328p programming with Arduino libraries
I'm trying to use the serial communication to work between a naked AVR Atmega328p and a computer (OS X and Linux Ubuntu).
I can program the atmega (using a pololu programmer), I make it blink a LED on a breadboard, it works fine.
I am using the Arduino libraries to facilitate the task. And they seem to work fine (using delay, digitalRead, digitalWrite, etc).
I use a USB-to-TTL CH340 chip bought on internet. The CH340 works fine, it is recognised both on Ubuntu and OS X, and the loopback test works (Put a jumper between the TX and RX line, launch screen, type something and it comes back in the terminal), so I assume the CH340 is properly recognise and works.
Then, I plug the CH340 on my board. The 5V on the + column of the breadboard, the GND to the - column. The circuit works, my LED blinks as requested. The loop function looks like this:
void setup() {
  Serial.begin(9600);
  pinMode(9, OUTPUT);
}

void loop() {
  digitalWrite(9, HIGH);   // sets the LED on
  delay(30);                     // waits for a second
  digitalWrite(9, LOW);    // sets the LED off
  delay(70);                     // waits for a second
  Serial.println("loop end");
}

As you can see, at the send of the loop I send a string on the serial line. Now, I see the blue LED blinking on the USB-to-TTL converter, so it is definitely receiving data. But when I try to connect like so:
screen /dev/cu.wchusbserialfd110 9600

on OS X, or
screen /dev/ttyUSB0 9600

on Ubuntu, nothing is displayed. I just get a black terminal.
Is the Arduino Serial works with Atmega328 ? I suppose so, as it is the same microcontroller than on the Arduino. Any idea of what I am doing wrong?
Update:
More details to answer Christ Stratton question:
My low fuse is 62: 01100010. So, according to the specifications, the internal clock is used and set at 1MHz.
I programmed the Atmega using my own test bed, a Pololu programmer (as described in the book Practical AVR Microcontrollers: Games, Gadgets, and Home Automation with the Microcontroller Used in Arduino) and avrdude (through the use of platformio).
This is the command line used by platformio to flash the ROM:
/Users/[user]/.platformio/packages/tool-avrdude/avrdude -v -p atmega328p -C /Users/[user]/.platformio/packages/tool-avrdude/avrdude.conf -c avrispv2 -B 10 -e -b 115200 -P "/dev/cu.usbmodem00149121" -U flash:w:.pioenvs/pololu/firmware.hex

According to avrdude documentation, -B 10 means bitclock is set to 10us (microseconds) so a clock at speed 100Khz.
Now if I set this -B option to 1 (1Mhz), I can't program the Atmega anymore. Avrdude just timeout:
avrdude stk500v2_ReceiveMessage(): timeout

I think it is necessary to consider the possibility that the Arduino's bootloader is setting up the UART in some way that the Arduino Serial library assumes, and does not do itself. I believe this is plausible as IIRC the Arduino bootloader will always be run before any uploaded (Arduino) program is started. Can you put the Arduino bootloader onto your ATmega328, and then try to upload to it using your USB-UART? You might need to fiddle with the reset to your ATmega to get it into the right state as autoboot might not work (unless you can wire that up correctly too)

Definitely a question for the Arduino StackExchange. Or even Ask Ubuntu..

@gbulmer your theory is incorrect.  There is absolutely no dependency whatsoever between the bootloader and main program, and it is well known that Arduino code does not in any way require a bootloader to be present.

What is the clock source and frequency of your circuit?  What was the clock source and frequency of the Arduino board configuration you used to build?  If there is a mismatch all the serial baud rates will be off.  If they are off by a power of two, you may be able to temporarily work around the issue by setting your computer to a baud rate that differs by the same factor, but it would be better to make the board configuration match the board.

@ChrisStratton, I tried to answer your question. I think I understand what you mean. The Arduino libraries are using some constants to deal with time dependent functionalities and those constant varies according to the board you want to program. If you compile you code with a ucontroller with 8MHz as target and run it on a 1Mhz, your 9600 baud rates will not be achieved. My guess is that either these constants are derived from the -B parameter or from another part of the avrdude configuration.

Bingo. The clock speed specified was the problem, but not through the -B parameter but by the board_f_cpu configuration option of the platformio.ini file. @ChrisStratton, if you post an answer summing up the solution, I'll accept it.

@ChrisStratton - I haven't read some of those sources for years, and clearly I'm misremembering, so thanks for the information. " it is well known that ... " a relative of "AssUme"?

The clock rate of your board must match the clock rate defined in the board file you used to compile your sketch.  If it does not, the baud rate will differ by the same factor.
If the actual baud rate so achieved is a valid one, you can temporarily achieve communication by setting the computer to that baud rate, but all delays and other clock-rate related functions will be off.
You should use or create a board file entry that matches your board, or use a standard clock source / clock divier setting for which there already is an entry.

Indeed, just needed to update the platformio.ini file used by platformio to configure avrdude.

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

authors: ﻣﺳـﮐووﻧهہ اﻟﻋراﻗﻱ


text:
Multiple 3-wire SPI sensor interfacing with Arduino
I want to connect 4 MAX6675 thermocouple to Arduino.
MAX 6675 description.
It comes with its own Arduino library. library link.
I tested the example code for one sensor and it works perfectly. Now I want to connect all the four sensors to Arduino using minimum GPIO pins possible.
I connected - (for 2 sensors only for initial testing):
D7 -> clk (slave 1) ->clk (slave 2)
D3 -> so (slave 1) ->so (slave 2)
D4 -> cs (slave 1)
D5 -> cs (slave 2)

My code (I modified the original example code a bit):
// this example is public domain. enjoy!
// www.ladyada.net/learn/sensors/thermocouple

#include "max6675.h"

int thermoCLK = 7;
int thermoDO = 3;
int thermoCS = 4;
int thermoCS2 = 5;
MAX6675 thermocouple(thermoCLK, thermoCS, thermoDO);
MAX6675 thermocouple2(thermoCLK, thermoCS2, thermoDO);

void setup() {
  Serial.begin(9600);
  Serial.println("MAX6675 test");
  // wait for MAX chip to stabilize
  delay(500);
}

void loop() {
  // basic readout test, just print the current temp
  Serial.print("C = ");
  Serial.println(thermocouple.readCelsius());
  Serial.print("F = ");
  Serial.println(thermocouple.readFahrenheit());
  Serial.print("C 2= ");
  Serial.println(thermocouple2.readCelsius());
  Serial.print("F 2= ");
  Serial.println(thermocouple2.readFahrenheit());
  delay(1000);
}

I am able to read only one sensor information correctly. The other output is nan. Am I wiring the circuit wrong or is my code incorrect or both?

I'd not use that library. Instead I'd one that uses SPI properly. Then you use just N+2 pins. Or since it's so simple to use anyway, just use SPI directly.

The above program will not run as it is as there is a syntax error. You have readCelsius in the beginning and readCelcius later on, all references should be readCelsius. Best regards, Phil.

Why would you not use pin 19 for SCK and pin 18 for MISO to keep the digital pins free? Could you please comment on what each line does in that code, just trying to learn and understand as I want to use 4 thermocouple and then write to 6 relay outputs.

First off ditch that library. It's completely pointless and actually makes things harder.
Secondly connect your sensors to the SPI pins, selecting a new CS pin for each sensor.

Arduino SCK (pin 13) to all the SCK pins.
Arduino MISO (pin 12) to all the SO pins.
Individual GPIO pins to individual CS pins (use pin 10 for one of them).

Then just use a simple function to read the data using the SPI library (adapted from the library you link to). For instance with CS on 10 an 9:
#include <SPI.h>

double readCelsius(uint8_t cs) {
    uint16_t v;

    digitalWrite(cs, LOW);
    v = SPI.transfer(0x00);
    v <<= 8;
    v |= SPI.transfer(0x00);
    digitalWrite(cs, HIGH);

    if (v & 0x4) {
        // uh oh, no thermocouple attached!
        return NAN;
    }

    v >>= 3;

    return v*0.25;
}

void setup() {
    SPI.begin();
    pinMode(10, OUTPUT);
    pinMode(9, OUTPUT);
    digitalWrite(10, HIGH);
    digitalWrite(9, HIGH);

    Serial.begin(115200);
}

void loop() {
    Serial.print(readCelsius(10));
    Serial.print(" ");
    Serial.println(readCelsius(9));
    delay(1000);
}

Shouldn't the above code also refer to the SCK and MISO pins?

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


text:
Reading data from multiple sensors from Arduino with ESP8266
I am trying to do a project where I need to get data from multiple sensors simultaneously. I am planning to use a Arduino to get the readings from the sensors. I am thinking to control the Arduino using ESP8266 as I would finally like to have internet capabilities for my project. I have worked with Arduino before but this is my first time with ESP8266 and I don't know much about. What I would like to know is if its feasible? I read that I need to use SoftwareSerial library to achieve this. Am I correct? I have tried to google for similar examples but most of the results direct to using a single pin on the Arduino controlled by ESP8266 and the Blynk app. Apart from that I could not find much information. I would be very much grateful if you could point out some similar projects or examples. Thanks a lot for your time in advance.

You want to use the esp8266 as the main MCU or only as network adapter? I recommend the second option with Mega. Mega has 4 Serials so don't use SoftwareSerial. I you put AT firmware 1.7 in the esp8266, you can use my WiFiEspAT library

Hi Juraj. I intend to use Mega as the main MCU and esp8266 as the network adapter. I will look into the WiFiEspAT library as you suggested. Thanks for the advice.

What are those sensors? Why don't you just use the esp without the arduino?

i always do it backwards, if for no other reason than OTA is faster for dev cycles and the ESP is WAY faster/stronger than the mega, making it the better "brain"

Sim, I need to use multiple load cells and a solenoid lock. So I am planning to use mega as it gives me more I/O pins.


text:
Nano 33 IoT rescue from the dead: No USB. No upload mode
First of all: my board used to work fine.
Now my Nano 33 IoT turns ON (green light) when connected to USB on Mac but:

doesn't enter in upload mode after pressing twice on board button.
doesn't shows up in any serial port: nor /dev/cu.usbmodem14*01, neither /dev/tty.usbmodem14*01

For reasons too long to explain, I want to connect via ANY pins to the SAMD21 and force the burning of a new bootloader.
Is that possible in any way? Any idea is welcome!
Tx

Use the SWD interface and a programmer to burn the bootloader to SAMD.

source of the picture https://medium.com/@manuel.bl/arduino-in-circuit-debugging-with-platformio-9f699da57ddc
I had luck with Adafruit DAP library using an Arduino M0 to burn a bootloader to MKR Zero.


text:
How can I give power to Arduino Uno using a 12V 7.5 Ah Lead-Acid battery?
I am trying to give power to my Arduino Board using a 12V 7.3 Ah Lead-Acid Battery but I am unable to do it.
I connected the battery to Arduino Uno (via DC Pin) and it worked for a couple of minutes but then, it automatically stopped working. I checked the voltage of the battery using a Multimeter from the same DC Pin which was connected with battery and board. The voltage was 12.62 volts.
Then I thought my board might have been fried. So, I checked the board by connecting it with a 12V 2 Amp DC adapter and I found that my board was not fried and it was working fine with the Adaptor. The Adaptor was giving 12.48 volts voltage. Then, I again checked the board using battery but still it didn't work. I tried charging the battery via a charger but it still didn't work. I tried these steps multiple times but the results were always same.
I checked with my 12V DC Fan & some other devices also and it works perfectly, but it doesn't work with my Arduino Board.
This indicates that my battery is in a good condition but not working with Arduino Board only. While Arduino is also in a good condition, working with 12V DC Adaptors but not with the Battery.
Please Help!

measure the voltage while the Arduino is connected

your question is not about the Arduino ... your question is about how to determine if a battery is in good condition .... voting to close

@jsotola  I updated my question after further tests. Now please help.

a fan is not a voltmeter ... as i asked before, what is the battery voltage when the arduino is connected to the battery? ... also, what is the power adapter voltage when the arduino is connected to the power adapter?

I have re-opened the question as it mentions Arduino 5 times and thus is hardly not about Arduinos.

@NickGammon  Thank You So Much for opening my question again and Supporting me.     People like you are so much needed in stack exchange communities. ❤

The input voltage on the DC pin is specified as 7 to 12V. Your battery may well be supplying more than that, causing the voltage regulator to overheat and shut down.

The voltage was 12.62 volts.

That is out of spec for the Arduino Uno. When you operate out of specified voltages anything can happen, and that anything may not be very good.
You could get a buck converter to lower the voltage.
Certainly a Uno should be able to run for a long time on a 7 Ah battery (provided you are supplying voltages in range for it, preferably using a buck converter or similar to make sure that a fully-charged battery does not supply too high a voltage).

I was thinking the same - I had this exact problem about a year ago with a solar powered setup. Droped the input voltage to 10V and no problemo!

Thank You So Much for your answer. I've read the Wikipedia article of the Buck Converter and I believe it will work in my case also, as you have already explained me. I have ordered a buck converter online. I'll update you as soon as it arrives and I use it in my project. Thanks Again. ❤

@Bevan Thanks for mentioning about your case. It strengthened my will to modify my current settings as told by Nick  and not leave it. Otherwise I was thinking of changing the battery  or the board

@Bevan One more help will be appreciated from your side. People have downvoted my post considering it as an off-topic post. It would be very great if you upvote it because it has resulted the decrease in my community reputation .

@Nick Gammon   sorry for the delayed update. My package with the buck converter just arrived today. I have installed it and it is working like butter. Thank You


text:
Blank Preferences on Arduino IDE 2.0.1
I just install this new IDE on my pc.
Yesterday, I changed my sketch folder location on preferences.
And when i need to change it again, the preferences shown nothing. Ive restart my pc and its not working.
How to solve this? Should I reinstall this app?

I just reinstall the app. But the preferences still blank.

Run the IDE from a command-line.  If any relevant error or warning messages show up, edit them into the question.

I checked the Arduino IDE issue list and did not find anything about a blank preferences dialog. Seems like the best way forward would be to open an issue there. Until then, it may be that deleting the arduino preferences folders/files somewhere in your user home suffices (probably C:\Users\Meiko.arduino or some subfolder in C:\Users\Meiko\AppData in your case, I'm not on windows). -- Actually, don't delete, move it away so you can include it in a bug report later.

try to provide more info into this thread on arduino forum. it is a discussion with a member of Arduino Team. https://forum.arduino.cc/t/blank-file-settings-menu-in-arduino-ide-2-0-1/1048087


text:
No SPIFFS data upload in Arduino IDE 2.0.0-rc3 (ESP32 & TTGO) - Ubuntu
I tried adding esp32fs.jar to /home/myname/Arduino/tools/ESP32FS/tool (and a few other places as it looked likely that the jar file wasn't loading).  I've definitely got the correct board selected, and can upload Sketches.  I can also run the demo that writes to SPIFFS.
But the Tools menu doesn't have an option for ESP32 Sketch data upload.
Is SPIFFS data upload not available so far in V2?

FS upload plugins for ESP are not available in IDE 2 yet (2022-01-07).
IDE 2.0 doesn't run on Java so it can't use the java plugins of the IDE 1. You have to use IDE 1 for FS upload and exception decoder until new plugins are written for IDE 2.
It is tracked here: https://github.com/arduino/arduino-ide/issues/58

I've created a utility that provides a web-based ESP32 interface for

OTA
File system formatting
FS directory listing
File uploading
File editing
File deletion

It can be found at https://github.com/palmerr23/ESP32-OTA-and-File-Manager

ESP32-OTA-and-File-Manager does not yet support FFAT, a good start, but 10 months later still to be done? You should point that out in the above.

Thanks for the comment Timothy, I've changed the FFAT status to "Not implemented" as the utility isn't as necessary as before now that Arduino 2.X has file upload capability. If you want to do the work, please feel free to create a pull request.


text:
ARDUINO UNO WIFI R3 (Dev Edition) Send simple http get request
I need send http request to my own server from arduino uno.
First of all I connected the board through web client configurator.
I tried different codes, the last one is:
    /*
    File: RestClient.ino
    This example makes an HTTP request after 10 seconds and shows the result both in
    serial monitor and in the wifi console of the Arduino Uno WiFi.
Note: works only with Arduino Uno WiFi Developer Edition.

http://www.arduino.org/learning/tutorials/boards-tutorials/restserver-and-restclient
*/

#include <Wire.h>
#include <UnoWiFiDevEd.h>

void setup() {

  const char* connector = "rest";
  const char* server = "<MY IP>";
  const char* method = "GET";
  const char* resource = "/";

  Serial.begin(9600);
  Serial.println("prima");
  Ciao.begin();
  Serial.println("dopo");

  pinMode(2, INPUT);

  //delay(1000);
  doRequest(connector, server, resource, method);
}

void loop() {

}

void doRequest(const char* conn, const char* server, const char* command, const char* method){
  Serial.println("Im doing the request");
  CiaoData data = Ciao.write(conn, server, command, method);
  if (!data.isEmpty()){
    Ciao.println( "State: " + String (data.get(1)) );
    Ciao.println( "Response: " + String (data.get(2)) );
    Serial.println( "State: " + String (data.get(1)) );
    Serial.println( "Response: " + String (data.get(2)) );
  }
  else{
    Ciao.println ("Write Error");
    Serial.println ("Write Error");
  }
}

But I get "Write Error" and the server does not recive any request

does your server run on port 80 and is it accessible over the Firewall? try to access it from some other device in the network.

I made a mistake. I put PubIP:PORT.
After your comment I exposed the server on PORT 80 and works.
So The request works only with port 80.
Thank you

If you find out that the UnoWiFiDevEd library is very limited, you can use WiFiLink firmware and library with my UnoWiFiDevEdSerial1 library


text:
Sense person connected to TENS unit
So let's say I use a store-bought TENS unit for liability. I want to make a challenge where you need to hold on to the TENS unit for 10 seconds before it activates a solenoid. How can I have an Arduino detect if someone is touching some metal posts connected to the unit? Would I need to measure the current for the tens unit or something? Any ideas/suggestions? Thanks!
Edit- Not sure if this should be in Arduino or Electrical Engineering, feel free to move it.

@jstola one of those things you connect to your body with sticky pads that shocks you and contracts your muscles. They are supposed to help with muscle pain and such. So basically it shocks you safely.

I think the main problem here is that you want to measure in the presence of high voltage from the TENS. Not having experience with TENS circuits, I would suppose that their contact pins are connected to the high voltage source through resistors to limit the current. (Or some equivalent current-limiting scheme.)  If so, the voltage between the contacts should drop when there is a person connected. You should be able to detect that drop with the Arduino.  The "obvious" approach would be to use voltage dividers to reduce the no-load voltage to less than 5V so the Arduino ADCs can handle it. You'd need high-value resistors in the dividers so they don't load the TENS... maybe 1 Megohm or more for each divider.  One problem with this simplistic approach is that the TENS is putting out its stimulus using brief pulses, which may be too quick to catch with the ADCs.  To get around that, you'd feed the output of each divider through a diode to an R-C filter.  (Note that you need the diode anyway, since the TENS output is probably AC and the Arduino ADCS only want DC.)  This may take a fair amount of experimentation to get the values right, which you should do without the Arduino... just a DVM or scope that you can start at a high-voltage range until you sure you have everything worked out to 0-5V.


text:
char to String conversion in Arduino program
I have started learning about Arduino and am well versed in Java and Python. In an Arduino program, I need a character input via Serial to be stored in a String variable. From my previous programming experience, I knew that a code like the one below would give an error as char can't be converted into String like this.
void loop() {
  if(Serial.available()) {
     String s=(char)Serial.read();
  }
}

As expected, the above code gives an error on compiling. But when I first defined s and then assigned its value in a separate step in void loop(), I got no error.
void loop() {
  if(Serial.available()) {
     String s;
     s=(char)Serial.read();
  }
}

The above code yields no error despite the fact that it is almost similar to the first code. What I suspect is that it has something to do with String being a class. Can one tell what is going on?

this isn't an arduino specific error what you're trying to do is declare and initialize the variable in one statement which is causing the problem. As you've figured it out already. Declaring the variable first
String s;

and initializing it another statement does the job for you
s=blabla

Hope this helps. PS, try posting the error that you get during build process next time :)
EDIT:
 I think this needs more explanation. Basically why you cant declare and initialize at the same time in this case is because Serial.read is a synchronous request. Declaring an object requires acquiring the space for it, running any constructors and whatsoever, and doing while Serial.read() is an IO blocking operation. You could declare and initialize a String class variable given it was a string constant but not with anything like get_input or Serial.read
EDIT 2:
Further here's what I've found for you.
http://www.cplusplus.com/reference/string/string/string/
Apparently the  String class has a copy constructor which means when declaring the variable you initialize at the same time it uses the copy constructor, and which requires ADDRESS to a valid string(know that you can use a constant because C++ deals with all strings as the address to their first char). In your case the constructor raised an error because you pointed it to an undefined(Serial.read() ).
String mystring=Serial.read(); //error, uses copy constructor

However this would work
String mystring="hey juliet!" ; //uses the copy contructor which takes address to a char

Doing the same thing in two different lines works for the same reasons, it uses a different constructor
String mystring; //uses empty string constructor - okay so far
mystring=Serial.read(); // uses the overloaded = operator  --okay

You misunderstand Serial.read(): it does not return a String or sth. like a char array, but an integer, representing only the last byte in the input buffer that hasn't been read.
What you probably want to do is to interpret those incoming bytes as chars and accumulate those in a String.
E.g. like this:
String s="";
while(Serial.available()) {
  // as long as there are bytes in the buffer
  s+=(char)Serial.read(); // interpret int as char and append character to s
}

As using String can easily lead to crashes you should avoid dynamic memory allocation by using a fixed-size char arrays:
#define MAX_LEN 64
char s[MAX_LEN];
uint8_t i;
while (serial.available() && i<MAX_LEN) {
  s[i]=(char) Serial.read();
  i++;
}

Note: once you are that far you still have to handle, when you want the data to be ready to process (e.g. detecting a \n and setting a flag appropriately).

I don't misunderstand Serial.read(). I know it returns an integer and that's why I have put (char) in front of it. Nor, in my program, do I want a character sequence to be stored in a String s, just a single character and that's why Serial.read(). I was just testing and figured out something unknown and want to know a reason for that only.

This will fix the problem:
void loop() {
  if(Serial.available()) {
     String s=(char*)Serial.read();
  }
}
This is because in C: Strings are defined as an array of characters.
You cannot assign a primitive to an array...
I guess the casting into pointer can be implicit as in your second example..

I don't have much experience with Arduino's String type, however, most people (including myself) don't advise to use it. Because the Arduino only has 1 KB of SRAM and the String type has its own hidden memory allocation, you might run out of memory without you know it, resulting in crashing/frozen programs without a clue what is happening.
Instead use character arrays (like char str[10]) where you know exactly what is reserved.
However, to answer your question, what I expect since String is a class, there is a (copy) constructor in that class that takes a char and converts it into a String.


text:
Arduino Mega keep states after reprogramming
Based on:
https://forum.arduino.cc/index.php?topic=440978.0
And some previous experience with Arduinos. What I would like to accomplish here is that I have a 8 channel relay board with the relays in different states. The Arduino is connected to a RaspberryPI via USB.
The first problem is well known the automatic reset of the Arduino which can be taken care of with a resistor or desoldering a pin on the Mega board so you can reconnect your Arduino as many time as you wish (while running on an external +5V power source) to the Raspberry and it will never reset.
However I also remember that doing this to the boards will also make them impossible to program because they cannot reset at the end when the sketch is uploaded.
I have think of a workaround:
1, Create a programming command on the arduino which is when it's received from the RPI it will connect that cut off pin with a relay which will make resetting possible again
2, Save all relay states to the EEPROM
3, After reset the Arduino always checks this programming flag in it's EEPROM and if it's present it either does not touch the relays or set them to the same position ON/OFF depending on the value it read back from the EEPROM
The last guy claims that: When the Arduino is in reset, all pins act like they aren't connected to anything. If you have an output which must be in a specific state during that period, you must add an external resistor to pull it up or down as required.
Is there any other solution for this problem? Like using a newer Arduino board which can keep pin states over reprogramming?

You have basically 2 distinct problems here. The problem to somewhat automatically enable/disable the reset from USB and the problem to keep the relays at their set states over reprogramming.

Enable/disable reset: The easiest way is to use a jumper, that you disconnect everytime you want to program the board. If you want to do it remotely, you already described a valid way, though I think, that you don't need a relay for that. A transistor or MOSFET should be sufficient for it.
Keep the relay states:

Like using a newer Arduino board which can keep pin states over reprogramming?

I don't think, that something like that exists. It does not make sense for general purpose microcontrollers to do that; they all start from a clean state. So you need to save the state of the relays outside of the Arduino. What type of device you want to use for that is up to you. Majenko mentioned flipflops, which gives you the most basic functionality for this. You could also use devices, which are interfaces serially, like shift registers or even port expanders. Using flipflops will be the easiest way, since the programming does not change much. There are many examples how to use each of these devices with an Arduino on the web.

I had to solve a problem similar to this for an ESP32 based system. The solution I came up with was to use external D-type latches (flipflops) to store the state independently of the Arduino.
The Arduino has to actively load a new relay state into a latch in order for the relay to change state, and that state is retained regardless of what the Arduino does.
The outputs of the latches can also be connected to other input pins so the Arduino can find the current state of the relays at boot time.

simulate this circuit – Schematic created using CircuitLab
The Arduino keeps track of what the outputs should be (reading the current state at boot) and then changes a state when needed. It then loads all the states onto the output pins and pulses the LOAD pin (CLK on the chip) high to load those states into the latches.
I used the 74HC374 chip for this since it contains 8 latches tied to a single CLK pin.

I use for this purpose (model railroading switching turnouts/signals with relays and coils) a simple and pin saving solution. An I2C bus shield/module with 16 I/O ports (and its daisy chainable - up to 64 modules theoretically, 16 practically due to address encoding pins)The 16-channel PCA9685/PCF8574 I/O extender module cost around 4-5 euro and requires beside GND/VCC only two data pins (SDA & SCL) to control the module. The I2C header has extra 10K pullup resistors and onboard of the module is a 25 MHz typical internal oscillator.
So after reseting, I first read the EEPROM/SPIFFS/SD-values and based on that stored set I work on. The Module(s) has(ve) a seperate power source which is not affected by the reset of the Arduino controlling them. The operating range of 2.3V to 5.5V allows the module to be powered from a range of power supplies and also used with 3.3V devices.The green terminal block in the picture is for use with servos - the extra power supply attaches to the I2C header (but common ground with Arduino).  Of course you have to use a lib (or like me write the functions you need) but once your into it its easy to use and also usable for other scenarios (LEDs, PWM generator, servos).

The PCA9685 is a 'free running' PWM controller. Tell it what to do,
  and it will keep doing that until you tell it to do something else. If
  you wanted to set the relays to a specific state and keep them
  there, you could disconnect the Arduino until you wanted the relays to
  do something else.


text:
'TCCR1B' was not declared in this scope
I'm trying to use a MS5540C (digital pressure sensor)
and the sample code has this line:
 TCCR1B = (TCCR1B & 0xF8) | 1; //generates the MCLK signal

I'm a bit of a noob to the IoT but its not beyond me to check the SPI.h and see that there is indeed no declaration.
I'm using an Arduino UNO WiFi Rev 2.
(Seems like its pins are quit different from an UNO)
I have noted in the comments that Im using pins 32,33,34 instead of 11,12,13
I'm not 100% sure what to ask … other than
Is there a replacement call/function/method that should replace that line? ..or am I missing something else totally. As it stands now...when the program runs its results are inconsistent. I'm just commenting out the faulty line to get it to compile.
Complete sketch
source: Future Electronics
/*
  MS5540C Miniature Barometer Module
  This program will read your MS5440C or compatible pressure sensor every 5 seconds and show you the calibration words, the calibration factors,
  the raw values and the compensated values of temperature and pressure.
  Once you read out the calibration factors you can define them in the header of any sketch you write for the sensor.

  Uno Pins:
  MS5540 sensor attached to pins 10 - 13:
  MOSI: pin 11
  MISO: pin 12
  SCK: pin 13
  MCLK: pin 9 (or use external clock generator on 32kHz)
  CS is not in use, but might be pin 10

  ==[ addendum start]=============================
  Uno WiFi Rev2 Pins:
  MOSI: pin 32
  MISO: pin 33
  SCK: pin 34
  MCLK: pin 9 (or use external clock generator on 32kHz)
  ==[ addendum end ]=============================

  created 29 February 2012
  by MiGeRA
*/

/*
  Calibration of my sensor example ...

  Calibration word 1 = 46958
  Calibration word 2 = 65369
  Calibration word 3 = 39392
  Calibration word 4 = 45914
  c1 = 23479
  c2 = 2074
  c3 = 717
  c4 = 615
  c5 = 1021
  c6 = 25
*/

#include <SPI.h>

const int clock = 9;

void setup() {
  Serial.begin(9600);
  SPI.begin(); //see SPI library details on arduino.cc for details
  SPI.setBitOrder(MSBFIRST);
  SPI.setClockDivider(SPI_CLOCK_DIV32); //divide 16 MHz to communicate on 500 kHz

  pinMode(clock, OUTPUT);
  delay(100);
}

void loop()
{
  Serial.println("=====================================================================");
  TCCR1B = (TCCR1B & 0xF8) | 1; //generates the MCLK signal

  analogWrite (clock, 128) ;
  resetsensor(); //resets the sensor - caution: afterwards mode = SPI_MODE0!

  //Calibration word 1
  unsigned int result1 = 0;
  unsigned int inbyte1 = 0;
  SPI.transfer(0x1D); //send first byte of command to get calibration word 1
  SPI.transfer(0x50); //send second byte of command to get calibration word 1
  SPI.setDataMode(SPI_MODE1); //change mode in order to listen
  result1 = SPI.transfer(0x00); //send dummy byte to read first byte of word
  result1 = result1 << 8; //shift returned byte
  inbyte1 = SPI.transfer(0x00); //send dummy byte to read second byte of word
  result1 = result1 | inbyte1; //combine first and second byte of word
  Serial.print("Calibration word 1 = ");
  Serial.print(result1, HEX);
  Serial.print(" ");
  Serial.println(result1);

  resetsensor(); //resets the sensor

  //Calibration word 2; see comments on calibration word 1
  unsigned int result2 = 0;
  byte inbyte2 = 0;
  SPI.transfer(0x1D);
  SPI.transfer(0x60);
  SPI.setDataMode(SPI_MODE1);
  result2 = SPI.transfer(0x00);
  result2 = result2 << 8;
  inbyte2 = SPI.transfer(0x00);
  result2 = result2 | inbyte2;
  Serial.print("Calibration word 2 = ");
  Serial.print(result2, HEX);
  Serial.print(" ");
  Serial.println(result2);

  resetsensor(); //resets the sensor

  //Calibration word 3; see comments on calibration word 1
  unsigned int result3 = 0;
  byte inbyte3 = 0;
  SPI.transfer(0x1D);
  SPI.transfer(0x90);
  SPI.setDataMode(SPI_MODE1);
  result3 = SPI.transfer(0x00);
  result3 = result3 << 8;
  inbyte3 = SPI.transfer(0x00);
  result3 = result3 | inbyte3;
  Serial.print("Calibration word 3 = ");
  Serial.print(result3, HEX);
  Serial.print(" ");
  Serial.println(result3);

  resetsensor(); //resets the sensor

  //Calibration word 4; see comments on calibration word 1
  unsigned int result4 = 0;
  byte inbyte4 = 0;
  SPI.transfer(0x1D);
  SPI.transfer(0xA0);
  SPI.setDataMode(SPI_MODE1);
  result4 = SPI.transfer(0x00);
  result4 = result4 << 8;
  inbyte4 = SPI.transfer(0x00);
  result4 = result4 | inbyte4;
  Serial.print("Calibration word 4 = ");
  Serial.print(result4, HEX);
  Serial.print(" ");
  Serial.println(result4);

  //now we do some bitshifting to extract the calibration factors
  //out of the calibration words;
  long c1 = (result1 >> 1) & 0x7FFF;
  long c2 = ((result3 & 0x003F) << 6) | (result4 & 0x003F);
  long c3 = (result4 >> 6) & 0x03FF;
  long c4 = (result3 >> 6) & 0x03FF;
  long c5 = ((result1 & 0x0001) << 10) | ((result2 >> 6) & 0x03FF);
  long c6 = result2 & 0x003F;

  Serial.print("c1 = ");
  Serial.println(c1);
  Serial.print("c2 = ");
  Serial.println(c2);
  Serial.print("c3 = ");
  Serial.println(c3);
  Serial.print("c4 = ");
  Serial.println(c4);
  Serial.print("c5 = ");
  Serial.println(c5);
  Serial.print("c6 = ");
  Serial.println(c6);

  resetsensor(); //resets the sensor

  //Pressure:
  unsigned int presMSB = 0; //first byte of value
  unsigned int presLSB = 0; //last byte of value
  unsigned int D1 = 0;
  SPI.transfer(0x0F); //send first byte of command to get pressure value
  SPI.transfer(0x40); //send second byte of command to get pressure value
  delay(35); //wait for conversion end
  SPI.setDataMode(SPI_MODE1); //change mode in order to listen
  presMSB = SPI.transfer(0x00); //send dummy byte to read first byte of value
  presMSB = presMSB << 8; //shift first byte
  presLSB = SPI.transfer(0x00); //send dummy byte to read second byte of value
  D1 = presMSB | presLSB; //combine first and second byte of value
  Serial.print("D1 - Pressure raw = ");
  Serial.println(D1);

  resetsensor(); //resets the sensor

  //Temperature:
  unsigned int tempMSB = 0; //first byte of value
  unsigned int tempLSB = 0; //last byte of value
  unsigned int D2 = 0;
  SPI.transfer(0x0F); //send first byte of command to get temperature value
  SPI.transfer(0x20); //send second byte of command to get temperature value
  delay(35); //wait for conversion end
  SPI.setDataMode(SPI_MODE1); //change mode in order to listen
  tempMSB = SPI.transfer(0x00); //send dummy byte to read first byte of value
  tempMSB = tempMSB << 8; //shift first byte
  tempLSB = SPI.transfer(0x00); //send dummy byte to read second byte of value
  D2 = tempMSB | tempLSB; //combine first and second byte of value
  Serial.print("D2 - Temperature raw = ");
  Serial.println(D2); //voila!

  //calculation of the real values by means of the calibration factors and the maths
  //in the datasheet. const MUST be long
  const long UT1 = (c5 << 3) + 20224;
  const long dT = D2 - UT1;
  const long TEMP = 200 + ((dT * (c6 + 50)) >> 10);
  const long OFF  = (c2 * 4) + (((c4 - 512) * dT) >> 12);
  const long SENS = c1 + ((c3 * dT) >> 10) + 24576;
  const long X = (SENS * (D1 - 7168) >> 14) - OFF;
  long PCOMP = ((X * 10) >> 5) + 2500;
  float TEMPREAL = TEMP / 10;
  float PCOMPHG = PCOMP * 750.06 / 10000; // mbar*10 -> mmHg === ((mbar/10)/1000)*750/06

  /*
    Serial.print("UT1 = ");
    Serial.println(UT1);
    Serial.print("dT = ");
    Serial.println(dT);
    Serial.print("TEMP = ");
    Serial.println(TEMP);
    Serial.print("OFFP = ");
    Serial.println(OFF);
    Serial.print("SENS = ");
    Serial.println(SENS);
    Serial.print("X = ");
    Serial.println(X);
  */

  Serial.print("Real Temperature in C = ");
  Serial.println(TEMPREAL);

  Serial.print("Compensated pressure in mbar = ");
  Serial.println(PCOMP);
  Serial.print("Compensated pressure in mmHg = ");
  Serial.println(PCOMPHG);

  //2-nd order compensation only for T < 20°C or T > 45°C

  long T2 = 0;
  float P2 = 0;

  if (TEMP < 200)
  {
    T2 = (11 * (c6 + 24) * (200 - TEMP) * (200 - TEMP) ) >> 20;
    P2 = (3 * T2 * (PCOMP - 3500) ) >> 14;
  }
  else if (TEMP > 450)
  {
    T2 = (3 * (c6 + 24) * (450 - TEMP) * (450 - TEMP) ) >> 20;
    P2 = (T2 * (PCOMP - 10000) ) >> 13;
  }

  if ((TEMP < 200) || (TEMP > 450))
  {
    const float TEMP2 = TEMP - T2;
    const float PCOMP2 = PCOMP - P2;

    float TEMPREAL2 = TEMP2 / 10;
    float PCOMPHG2 = PCOMP2 * 750.06 / 10000; // mbar*10 -> mmHg === ((mbar/10)/1000)*750/06

    Serial.print("2-nd Real Temperature in C = ");
    Serial.println(TEMPREAL2);

    Serial.print("2-nd Compensated pressure in mbar = ");
    Serial.println(PCOMP2);
    Serial.print("2-nd Compensated pressure in mmHg = ");
    Serial.println(PCOMPHG2);
  }

  delay(5000);
}

void resetsensor() //this function keeps the sketch a little shorter
{
  SPI.setDataMode(SPI_MODE0);
  SPI.transfer(0x15);
  SPI.transfer(0x55);
  SPI.transfer(0x40);
}

Haave you written this code yourself, or did you copy parts of it somewhere? If the least, plase link to that source

@chrisl I added the source above. If you copy the text..take note of a char that is the 'f" and the 'l' combined!...ie in "float"...just retype it.

While writing this answer, I found out about the register emulation of the Arduino Uno Wifi. The Uno Wifi is a different chip, than the Uno, thus you have different registers. But the Uno Wifi was thought as a drop in replacement, so register emulation maps the old register names to the new registers, so that you can basically simply reuse the old code for the Uno. In my Arduino IDE (v1.8.9) I had a buildin Uno Wifi board, which seems to have the register emulation enabled without configuration option (I could compile your sketch even for the Uno Wifi). Through the board manager I installed the "Arduino megaAVR Boards" core, that contains the Arduino Uno Wifi rev2. If you choose this board in the board selection, you get the option to select the register emulation. For old code you need the emulation for ATmega328. With that, your old code should compile.
This makes the rest of my answer unnecessary, but since I already spend some time writing it,  I will leave it in the answer for information and for the case, that you don't want to use the register emulation.

You get the error, because the sketch, that you copied is made for the Arduino Uno, not the Arduino Uno Wifi. While the first uses an ATmega328P chip, the last is build with an ATmega4809 (you can find this information here at the Arduino.cc store). These are different chips, thus you cannot simply reuse code that is made for the Uno on the Uno Wifi.
TCCR1B is the control register B of Timer 1. This name is specific to the ATmega328P chip. The ATmega4809 has even more timers than the 328P, but they seem to get configured via different registers. Refer to the datasheets on the product site of the ATmega4809. The timer hardware and it's registers are described in the more general megaAVR 0 series family datasheet. At the first glance it seems, that not only the register description is different from the 328P, but also the positions of the different configurations. This means, that every code, that uses direct register manipulations for the timer, must be rewritten for the 4809.
Fortunately, I see only 1 line here, that does this: The line, that generated the compiler error. (The SPI library very likely already has fitting definitions inside for the 4809). You have the line
TCCR1B = (TCCR1B & 0xF8) | 1;

That clears the 3 least significant bits (leaving the rest as it was) and setting the least significant bit to 1. According to chapter 16.11.2 of the 328P's datasheet (description of the TCCR1B register), these 3 bits are the clock selection. A bit code of 001 (only least significant bit set) means timer on, but with no prescaling.
To be honest, I'm not sure, if this line really does something, since directly after that, analogWrite() is called and I thought this function would overwrite the timer settings. But other posts (like this one) suggest, that it at least does not overwrite the clock selection.
I don't know, which timer get's used for outputting PWM to that pin, but for now, I will assume the first timer of type B. If you look into the families datasheet (as linked above) the clock source of the second timer (TCB) is configured with the register TCB0.CTRLA (see chapter 20.5.1). Bits 1 and 2 are configuring the prescaler (binary 00 for no prescaler), bit 0 enables the timer. So you can again write binary 001 to this register, leaving the rest untouched. So I suggest, you use this line instead of the old one
TCB0.CTRLA = (TCB0.CTRLA & 0xF8) | 1;

This should do the same with the second timer, that was done in the original sketch. If the first timer is used for this, you would have to change TCB0 to TCA0.SINGLE (I really don't know, why this SINGLE is needed) and change 0xF8 to 0xF0, since TCA has 3 bits for selecting the clock source.

I might be a little over my head. I do have the right board in boardmanager. I had also tried changing the emulation. I still get the error! My initial thoughts were the preprocessor was boogering up the code. The calibration words keep changing. I can see now Im going to have to get a grip on registers,clocks..etc..etc.

I think the emulation doesn't cover timers

@Juraj But the old code compiles for me only with register emulation. Doesn't that mean, that it also does the emulation for the timer registers?


text:
"Simple" code...but what have I done wrong?
This code  compiles without problem, but doesn't work at all... The switch does not set the LED low and the while loop doesn't work, plus the serial print doesn't print....
Until I put the while loop in pressing either button would change the LED state. I wanted to make the sequence "button one, LED change, THEN button two"
I'm certain to have missed something...
const int buttonPin1 = 2;     // the number of the pushbutton 1 pin 2
const int buttonPin2 = 7;     // the number of the pushbutton 2 pin 7
const int ledPin = 13;      // the number of the LED pin

// variables will change:
int buttonState1 = 0;         // variable for reading the pushbutton status
int buttonState2 = 0;
int i = 0;

void setup() {
// initialize the LED pin as an output:
  pinMode(ledPin, OUTPUT);
// initialize the pushbutton pin 1 as an input:
  pinMode(buttonPin1, INPUT);
// initialize the pushbutton pin 2 as an input:
  pinMode(buttonPin2, INPUT);
  Serial.begin(9600);
}

void loop() {

  digitalWrite(ledPin, HIGH);

// read the state of the pushbutton value:
  buttonState1 = digitalRead(buttonPin1);

// check whether a  pushbutton is pressed.
// if it is, the buttonState is HIGH:

  if (buttonState1 == HIGH) {
// turn LED off:   //
    digitalWrite(ledPin, LOW);
    while (1) {
      (buttonState1 == LOW);
      if (buttonState1 == LOW) {
        Serial.println("1");
      }
      {
        break;
      }
    }

    delay[1000];

    digitalWrite(ledPin, HIGH);

// read the state of the pushbutton 2 value:
    buttonState2 = digitalRead(buttonPin2);
    if (buttonState2 == HIGH) {
// turn LED off:
      while (1) {
        if (buttonState2 == LOW) {
          break;
        }
      }
      digitalWrite(ledPin, LOW);

      delay(10000);
      digitalWrite(ledPin, HIGH);

    }
  }
}

Your code is only reading the real state of buttonPin1 once, and copies the value as it is at that moment to the variable buttonState1, which will no longer change or reflect the real button status after that (the value of buttonState1 will not automagically change when you push or release button 1). If you want to continue to check the current button status, you have to continuously read the I/O port, by using digitalRead() statements where appropriate. The same goes for buttonPin2.

I guess as the function "name" is basically pointer, it really is possible to write delay[1000]; :D Luckily it wasn't called, so it doesn't do anything :D

@KIIV, I didn’t spot that one, good catch!

I think there’s a misunderstanding of how variables work.
Your code is only reading the real state of buttonPin1 once (before the first if () statement) and copies the value read from the I/O port as it is at that moment to the variable buttonState1, by executing buttonState1 = digitalRead(buttonPin1);.
After you’ve copied the value read from the buttonPin1 port to the buttonState1 variable, this variable will no longer change or reflect the actual button status. I.e. the value of the variable buttonState1 will not automagically change when you push or release button 1. buttonState1 is a normal program variable and not coupled to the I/O port.
If you want to continue to check the current button status, you have to continuously read the I/O port, by using digitalRead() statements where appropriate.
The same goes for buttonPin2 and buttonState2.


text:
Arduino keeps crashing
I've got an Arduino with a WS2812 hooked up to it, powered by the USB on my computer and I am trying to run the following code:
#include <FastLED.h>

#define NUM_LEDS 144
#define DATA_PIN 6
#define LED_TYPE WS2812B
#define COLOR_ORDER GRB

CRGB leds[NUM_LEDS];

void setup() {
  FastLED.addLeds<LED_TYPE, DATA_PIN, COLOR_ORDER>(leds, NUM_LEDS);
  FastLED.show();
}

void loop() {
  for(int dot = 0; dot < NUM_LEDS; dot++) {
    fill_solid(leds, NUM_LEDS, CRGB::Red);
    leds[dot] = CRGB::Black;
    leds[dot] = CRGB::Blue;
    FastLED.show();
    leds[dot] = CRGB::Red;
    delay(30);
  }
}

void setAll() {

  FastLED.show();
}

What this does is sets all the LEDs to red, then goes through each one turning it off, then to blue and then back to red.
For some reason, it gets X number of LEDs along and then crashes.  By crashes I mean the Arduino disconnects itself from the computer, but the Arduino stays on with the LED strip still powered up.
Any ideas?  This is a genuine Uno and I can run any of the FastLED or NeoPixel examples for hours on end without an issue

Have you checked the memory footprint?

I'm not 100% sure how I go about this, but when I upload the code, it says its taking up X bytes which if I recall was about 25%.  Also, I can throw any of the complex FastLED examples onto it and run them without any problems at all

Have you checked the power requirements? Circuit?

The LEDs require 5v and are powered off the Arduinos 5v pin. It's a fairy simple setup. Grd to grd pin, data to pin 6 and live to 5v

X number of LEDs time 60 mA > USB Amax.

This is a duplicate of Arduino keeps crashing in Stack Overflow. It already has an answer there (and the OP said in chat that the problem was the power: http://chat.stackoverflow.com/transcript/message/34924703#34924703 ). I'm closing this as a duplicate.

Please do not cross-post the same question on different Stack Exchange sites. See Is cross-posting a question on multiple Stack Exchange sites permitted if the question is on-topic for each site?.

I'm voting to close this question as off-topic because it has been cross-posted to Stack Overflow. Also it is a power issue, not an Arduino issue.

I'm going to add to this.  This might be a power issue, but it is also an Arduino resolution.  Within FastLED there is a power setting which can be used to control the power of the LEDs.  A USB3 port gives off a maximum of 900mAh, so setting the following code configures the commands sent to the LEDs to scale as to not use more than the power parameter given FastLED.setMaxPowerInVoltsAndMilliamps(5,900);

See Powering NeoPixels.

Each individual NeoPixel draws up to 60 milliamps at maximum brightness white (red + green + blue).

OK, so you have 144 LEDs.
#define NUM_LEDS 144

That means you need to allow for 8.64 amps to power them!
144 * 0.060 = 8.64

(This is a worst-case scenario, but you should probably allow for 2 amps at least).
As st2000 points out, the USB interface will provide 500 mA (0.5 amps). So you are possibly 8 amps short. You need to power the NeoPixels independently, not through the Arduino.
By powering them through the Arduino they are draining the current from the USB port so much that the over-current protection kicks in.

See my comment above. Your answer is theoretically correct, bit given that I can light the entire strip white and 100% brightness and run any FastLED without issue, it would disprove your theory on power consumption

I measured my 24-pixel strip using your sketch and it took 388 mA. Extrapolating to 144 pixels you get 144/24 * 388 which is 2.328 amps. You just can't get that from your USB supply! I note that you acknowledge here that "OK well power was definately the issue" so perhaps you can upvote the replies here that said so, and accept one of them.

It is inferred from your question that the Arduino is getting powered through the USB port.  As you say the Arduino appears "gone" from the computer when you light up too many LEDs.
All USB ports are only obliged to supply 500mA with out the USB Device (the Arduino) negotiating for more power from the USB Host.  If the load goes beyond 500mA, the USB Host (the computer) can limit the power my reducing the voltage.  At some point the Atmel processor on the Arduino will stop working.
There are many tutorial on how to use LED strips on the web.  Most will indicate power from a larger than normal power supply is necessary.  Also, that the LED strip power should be connected directly to an appropriately chosen power supply.
The following image from this web page illustrates this:

(Note: In this picture PIN 6 was chosen to communicate with the LED strip.  Your specific application (program or sketch) may use a different pin. Also, realize that the power supply in the picture is wired to only power the LED strip. The Arduino still needs to be powered.)

You are correct for only fort the example above. I can quite happily make the entire strip white at 100% brightness or run any of the FastLED or Neopixel examples without an issue.

I'm trying this with my 5V PSU now, however I can't even get the LEDs to power on (even with just lighting 1 LED)  The LED 5V goes to my PSU 5V+, GRD & Data to my arduino

What you say sound correct.  If you are using 2 power supplies make sure their grounds are connected.  I will add a link to a LED strip how to web page to my answer to help out.


text:
Yet another display 16x2 not working with arduino
I found hundreds of questions about display not working with arduino.
However, no matter how trivial this looks like I am having the same problem I cannot understand by reading the other posts.
I have an Arduino micro connected to a display from the adafruit kit
RGB LCD SHIELD KIT W/ 16X2 CHARACTER DISPLAY
I haven't been able to understand whether positive or negative, but I think from the picture is RGB positive.
I have connected everything as shown in the diagram in this page:
LCD "Hello World!"

Obviously changing the pins as I have
RS at 8
E at 7
d4 = 12
d5 = 11
d6 = 10
d7 = 9;

The potentiometer changes the contrast, if I saturate it I can see the black boxes.
In the code put this as
const int rs = 8, en = 7, d4 = 12, d5 = 11, d6 = 10, d7 = 9;
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);

I checked with the multimeter whether the soldering is good and it carries the signal at the end of the wires.
and the rest as the example in the link,
This is my mess (please ignore the other arduino and the thermocople which is not connected, the other orange wire goes to GND of the Arduino).

Any ideas that might help?

If you also have an Arduino Uno, I would try exactly the example on your link, to see if at least you haven't a bad display.

Agreed.  Whether or not you use Nano or Uno, wire it up precisely according to the instructions with no changes.  Test it that way first.  Then you can make changes as you like.

disconnect the E line, power up the system and adjust the contrast so you see 1 black bar on the first line;
reconnect the E line and see if your code is working.
go from there.


text:
Only print when the button is pressed and not being pressed anymore
I have an Arduino and a microswitch that I want to use to know when the switch is initially being pressed (get "OnsetTime" on Serial) and when the switch is not being pressed anymore (get "OffsetTime" on Serial).
Imagine a bird sitting on the switch. I want to get an output "OnsetTime" when the bird first sits on the switch and an output "OffsetTime" when the bird flies away from the switch.
Right now, I have an output that constantly prints out "OnsetTime" when the switch is pressed.
I would appreciate it if anybody can help me figure out how can I implement the below code to get the outputs only when the switch is initially pressed and not being pressed anymore.
void setup() {
  pinMode(7, INPUT);
  Serial.begin(9600);
}

void loop() {
  if (digitalRead(7) == HIGH) {
    Serial.println("OnsetTime");
    }
}
    //Serial.println("GetOffsetTime");

If you want to be simple, you can use this library. The code will be
#include <ezButton.h>

ezButton button(7);  // create Button object that attach to pin 7;

void setup() {
  Serial.begin(9600);
  button.setDebounceTime(100); // set debounce time to 100 milliseconds
}

void loop() {
  button.loop(); // MUST call the loop() function first

  if(button.isPressed())
    Serial.println("OnsetTime");

  if(button.isReleased())
    Serial.println("GetOffsetTime");
}

If you want to understand in depth, You can see the code and instruction in this tutorial

Hi. This gives me the error: 'class Button' has no member named 'setDebounceTime'

did you install ezButton library ? if not, follow this instruction to install libraray

Yes, I did. This is an unusual case so I'm a bit confused. Did you try it and does it work?

Yes, I tried, it works. I think, you may install multiple Button libraries. Please check it. Or please run example code from library.
If still happened, which Arduino are you  using?

Do you mean I'd want to delete other Button libraries if I have any? I am using Arduino Uno.

I've tried deleting other Button libraries and now the code works. Thank you!

You can save the value of the switch read to compare it on the next loop. This way you're able to detect changes.
int lastValue;

void setup() {
  pinMode(7, INPUT);
  lastValue= digitalRead(7);

  Serial.begin(9600);
}

void loop() {
  int currentValue = digitalRead(7);
  if (lastValue != currentValue) {
    lastValue = currentValue;

    if (currentValue == HIGH) {
      Serial.println("OnsetTime");
    } else {
      Serial.println("OffsetTime");
    }
  }
}

Please be aware that switches bounce. If you see multiple messages at each mechanical change, insert a delay(...).


text:
digitalRead keeps giving 1
I am new to arduino programming and I have bought arduino UNO a few days ago.
I am trying to read the value of pin 4 using digitalRead with pinMode INPUT_PULLUP but it keeps giving me 1 even when the pin 4 is not connected to anything.
Here is the code:
void setup() {
  pinMode(2,OUTPUT);
  pinMode(4,INPUT_PULLUP);
  Serial.begin(9600);
  digitalWrite(2,HIGH);
}

void loop() {
  Serial.print(digitalRead(4));
  Serial.print('\n');
  delay(150);
}

Pin 2 is connected to one side of the button and Pin 4 is connected to other side of the button.
According to condition, when the button should be off , the value should be 0 and when the button  should be on , the value should be 1 , but the value is 1 even when I press the button is off or on.
On the other way , if I replace INPUT_PULLUP with INPUT then the value is floating.
Why the value with INPUT_PULLUP is 1?

“when the button should be off , the value should be 0”: what led you to this assumption?

You have set Pin 2 to HIGH, which is 5V. You have set Pin 4 to INPUT_PULLUP, which means if no signal is driving it, it will be HIGH.
You have connected a button between Pins 2 and 4. So, if you don't press the button, the input is pulled HIGH. And if you do press the button, Pin 2 is driving it HIGH.

@J.Doe: The standard way to wire a push button is to connect it between a digital input and ground. If you set the digital input to INPUT_PULLUP mode, the pin will read LOW when the button is pressed and HIGH when it's not.

There are to simple options how to connect a simple button. You mixed them.
Better option is connect the button between pin with INPUT_PULLUP and ground. The pin is HIGH when the button is open and LOW when the button grounds the pin. This option is better because if you disconnect the button, the pin is still pulled up to HIGH and not floating.
If you connect the button with a pull-down circuit, then the pin is HIGH when the button is pressed and LOW when the button is open, but when you disconnect the circuit, the pin floats and the sketch reads chaos.

This looks as it is operating as wired and programmed.  When the button is open, the INPUT_PULLUP is pulling pin 4 to HIGH, and when the button is closed & shorted to pin 2, the digitalWrite(2,HIGH) would also pull the pin 4 to HIGH.
Maybe you want digitalWrite(2,LOW) so that connecting pin 4 to pin 2 through the button would pull pin 4 low.

But then there is no point in using pin 2 instead of GND.

I don't know why Doe did that, but he wasn't doing it correctly.  I sometimes provide power or ground through the output pins so I can plug a device directly into a header, or so I can switch the device on or off, but it kind of a sloppy, cheap hack.

"digitalWrite" was misspelled as "digitalWtite" here. Not sure why it was rolled back.

@Pikamander2 Tiny, trivial edits are discouraged and you added &nbsp at the end. https://arduino.stackexchange.com/help/privileges/edit


text:
How to modify a created byte?
I have created a byte for 16x2 LCD. It is basically a custom character which I will have to change later.

byte char[8]{
 B10000,
 B01000,
 B00100,
 B00010,
 B00001,
 B11000,
 B11100
};

I want to edit the third number from fourth row. So, the fourth row will become B00110 from B00010. Is this possible? Are there any alternatives for this?

Well first of all you are trying to name the variable char? which is already a keyword for the variable type of char.   But you can access it by the index of the array. Also not sure if you intended to make the array 8 bytes in length, and then only use 7, but thats what you had done in your example
//define it all at once
// byte byteArray[8] = {B10000,B01000,B00100,B00010,B00001,B11000,B11100};
//or by index
byte byteArray[8];
byteArray[0]=B10000;
byteArray[1]=B01000;
byteArray[2]=B00100;
byteArray[3]=B00010;
byteArray[4]=B00001;
byteArray[5]=B11000;
byteArray[6]=B11100;

//if you need to change one in the code elsewhere
byteArray[3]=B00110;
//or
byteArray[3]=6;
}

In the second last line, why did you set the byteArray[3] equal to 6? Why not 3 because we want to change the third element?

B00110 = B110 = 1 (first 1) * 2^2 + 1 (second 1) * 2^1 + 0 (last 0) * 2^0 = 1 * 4 + 1 * 2 + 0 * 1 = 6

@MichelKeijzers Well, i didn't get it. What is the purpose of it? Is there simpler way? I just don't want to involve other elements.

E.g. in the normal (10 or decimal system) number 76 = 7 * 10^1 + 6 * 10^0 = 7 * 10 + 6 * 1 = 70 + 6 = 76. In the binary (2 system) number 110 = 1 * 2^2 + 1 * 2^1 + 0 * 2^0 = 1 * 4 + 1 * 2 + 1 * 0 = 4 + 2 + 0 = 6.

Was just showing that it could be set using decimal rather then binary  x=B00110(Binary), x=6(Dec),x=0x06(Hex) Are all equal. It doesn't really pertain to your question, so I should have just left it out to not be confusing.

You can use the following array initialization:
In the setup I shows how to set a bit. For this, the bit operator or (|) is used. To reset a bit, you can use &. You can set/reset multiple bits this way.
Also you can use 1 << 2 which means 1 (most right bit) shifted left two places (thus B100).
Btw, it is common practice to initialize all values.
byte lcd[8] =
{
  B10000,
  B01000,
  B00100,
  B00010,
  B00001,
  B11000,
  B11100,
  B00000  // Also initialize last element
};

void setup()
{
   lcd[3] |= B100; // Set 4th row (element 3), 3th bit (from the right)
   lcd[3] |= 1 << 2; // Alternative
}

void loop()
{
}

Explanation about the or arithmetics: OR means: if at least one bit is 1, the result is 1, otherwise 0.
Truth table:
A | B | A or B
--+---+-------
0 | 0 |   0
0 | 1 |   1
1 | 0 |   1
1 | 1 |   1

For your example it means:
Original value of lcd[3]: B00010
Or mask (in setup):       B00100
                          ------ OR
Result                    B00110

Why have we done this? lcd[3] |= B100; .Where did the other elements go?

lcd[3] will only change the 3th element, the other elements will remain equal. With the or (|) you can set a bit, all 0-values in an or 'mask' will remain unchanged.

Can I do directly like lcd[3][3] = B1; where first 3 is the 4th row and second is the 3rd element?

No you cannot use lcd[3][3] because lcd[3] is one element  (a byte) and not an array.