# Question
Title: Detecting when a timer interrupt does not run
I am dealing with code thatt i received that relies heavily on timer interrupts. i am using arduino Mega (Funduino)

More specifically, when a signal arrives in a pin, an interrupt is run that starts a timer. A different interrupt is run from inside the 1st interrupt, when the timer overflows.

The interrupts measure time between the incoming signal pulses, to figure out the resistance of a sensor, that is being produced from a supporting analog circuit.

The problem is when the sensor doesn't work. For example, the resistance is open circuited. Then the analog circuit does not produce and signal, and no interrupt is triggered.

My code is stuck on the loop() function. It cannot progress because it requires a flag to be set up ,from when the interrupt finishes execution (the interrupt sets that flag at the end).

What i would like to do, is to detect when the resistance is open circuited and move on. This means i have to figure out how to detect when the interrupt is not run.

Perhaps i would set a timer to that flag that the interrupt sets? And if some time passes without the flag being set, this means that the interrupt did not run.

But using another timer (my interrupt already uses two timers) maybe would complicate things further. Any ideas?

Maybe i could also check if the pin that receives the signal does not receive anything for some time... Maybe this would be a better option. If it is, what's the best way to do so, considering the fact i already use two different timers?

This is the code:

```
/***** CONSTANTS *****/
const int BAUD_RATE = 9600;

const int INTERRUPT_PIN = 3;

const int S0_PIN = 4;
const int S1_PIN = 5;
const int S2_PIN = 6;
const int OE_BAR_PIN = 22;

const int NUM_OF_SENSORS = 8;

/***** ANALOG CIRCUIT CONSTANTS *****/
const double CAPACITOR_VALUE = 400; //pF
const double GAIN_VALUE = 3.5222672065;
const double R_BIAS_VALUE = 98.7; //kΩ

/***** GLOBAL VARIABLES *****/
int number_of_samples = 10;

int pulse_counter = 0;
byte measurement_counter = 0;

unsigned long overflows = 0;
unsigned long ticks = 0;
double period = 0;

boolean interrupts_enabled = false;
boolean measurement_finished = false;

int sensor_coord;

boolean full_mode = false;

void setup() {
  attachInterrupt(digitalPinToInterrupt(INTERRUPT_PIN), count_time_of_k_pulses, RISING);

  pinMode(OE_BAR_PIN, OUTPUT);
  pinMode(S0_PIN, OUTPUT);
  pinMode(S1_PIN, OUTPUT);
  pinMode(S2_PIN, OUTPUT);

  TIMER1_init();

  Serial.begin(BAUD_RATE);
  while (! Serial);
}

void loop() {
  if (Serial.available()) {
    /***** DEFINE MEASUREMENT MODE *****/
    String input = Serial.readString();
    if (input[0] == 'r' && interrupts_enabled == false) {
      if (input[1] == 'f') {
        full_mode = true;
        sensor_coord = 0;
      } else
        sensor_coord = input[2] - '0';

      select_sensor();

      /***** SET VARIABLES FOR DUMMY MEASUREMENT *****/
      number_of_samples = 10;

      pulse_counter = 0;
      measurement_counter = 0;

      TIMER1_clear();

      interrupts_enabled = true;
    }
  }

//THIS IS WHERe I BELIEVE THE CHECK SHOULD OCCUR, OF WHETHER THE INTERRUPT DID NOT RUN. OR WHETHER THE PIN 3 IS RECEIVING A ZERO SIGNAL FOR SOME TIME

  if (measurement_finished) {
    measurement_counter++;

    ticks = (overflows * 65536) + TCNT1;
    period = (ticks * 0.0625) / (number_of_samples - 1);

    if (measurement_counter == 1) {
      /***** SET VARIABLES FOR MEASUREMENT *****/
      number_of_samples = 500;

      pulse_counter = 0;

      TIMER1_clear();

      interrupts_enabled = true;
    }
    else {
      TIMER1_print_results();

      if (full_mode) {
        sensor_coord++;

        select_sensor();

        /***** SET VARIABLES FOR DUMMY MEASUREMENT *****/
        number_of_samples = 10;

        pulse_counter = 0;
        measurement_counter = 0;

        TIMER1_clear();

        interrupts_enabled = true;

        if (sensor_coord == NUM_OF_SENSORS) {
          full_mode = false;
          interrupts_enabled = false;
        }
      }
    }
    measurement_finished = false;
  }
}

/***** INTERRUPT ROUTINES *****/

void count_time_of_k_pulses() {
  if (interrupts_enabled) {
    pulse_counter++;

    if (pulse_counter == 1)
      TIMER1_start();

    if (pulse_counter == number_of_samples) {
      TIMER1_stop();

      measurement_finished = true;
      interrupts_enabled = false;
    }
  }
}

ISR (TIMER1_OVF_vect) {
  overflows++;
}

/***** FUNCTION FOR SENSOR SELECTION *****/

void select_sensor() {
  digitalWrite(OE_BAR_PIN, LOW);
  digitalWrite(S2_PIN, ((sensor_coord & 4) == 4) ? HIGH : LOW );
  digitalWrite(S1_PIN, ((sensor_coord & 2) == 2) ? HIGH : LOW );
  digitalWrite(S0_PIN, ((sensor_coord & 1) == 1) ? HIGH : LOW );
}

/***** TIMER1 FUNCTIONS *****/

void TIMER1_init() {
  TCCR1A  = 0;
  TCCR1B  = 0;
  TIMSK1  = 0;
  TCCR1B |= (0 << CS12) | (0 << CS11) | (1 << CS10);
}

void TIMER1_start() {
  TIMSK1 |= (1 << TOIE1);
}

void TIMER1_stop() {
  TIMSK1 = 0;
}

void TIMER1_clear() {
  TCNT1     = 0;
  overflows = 0;
}

void TIMER1_print_results() {
  Serial.println("----------------------------------------");
  Serial.print("SENSOR COORDINATE         = ");
  Serial.println(sensor_coord);

  Serial.print("NUMBER OF PULSES MEASURED = ");
  Serial.println(pulse_counter);

  Serial.print("TIMER1 VALUE              = ");
  Serial.println(TCNT1);

  Serial.print("TIMER1 OVERFLOWS          = ");
  Serial.println(overflows);

  Serial.print("TICKS                     = ");
  Serial.println(ticks);

  Serial.print("MEASURED PERIOD           = ");
  Serial.print(period);
  Serial.println(" US");

  Serial.print("MEASURED RESISTANCE       = ");

  double resistanse = ((period * GAIN_VALUE * 1000) / (4 * CAPACITOR_VALUE)) - R_BIAS_VALUE; //kΩ
  Serial.print(resistanse);

  Serial.println(" kΩ");

  Serial.println("----------------------------------------");
}

```

EDIT: This is the updated code, with help from chrisl. Only the lines or blocks of code with '!!!!!!!!!!!' are new, so there is not much new code.

```
/***** CONSTANTS *****/
const int BAUD_RATE = 9600;

const int INTERRUPT_PIN = 3;

const int S0_PIN = 4;
const int S1_PIN = 5;
const int S2_PIN = 6;
const int OE_BAR_PIN = 22;

const int NUM_OF_SENSORS = 8;

/***** ANALOG CIRCUIT CONSTANTS *****/
const double CAPACITOR_VALUE = 400; //pF
const double GAIN_VALUE = 3.5222672065;
const double R_BIAS_VALUE = 98.7; //kΩ

/***** GLOBAL VARIABLES *****/
int number_of_samples = 10;

byte measurement_counter = 0;

unsigned long overflows = 0;
unsigned long ticks = 0;
double period = 0;

//variables for determining if a resistance cannot be measured !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
unsigned long timestamp = 0;
unsigned long measurement_timeout = 5000;  //5 secods is the timeout time
boolean sensor_corruption[7]; //each element of the array is the sensor info. If false, resistance is working. If it's true, resistance is open.
boolean ISR_unavailable = false; //this flag is raised, when the ISR dose not run, because no signal comes from the circuit, because resistance is open circuit
boolean setup_finished = false;

//variables that get changed inside the ISR - thus are declared volatile!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
volatile int pulse_counter = 0;
volatile boolean interrupts_enabled = false;
volatile boolean measurement_finished = false;

int sensor_coord;

boolean full_mode = false;

void setup() {
  attachInterrupt(digitalPinToInterrupt(INTERRUPT_PIN), count_time_of_k_pulses, RISING);

  pinMode(OE_BAR_PIN, OUTPUT);
  pinMode(S0_PIN, OUTPUT);
  pinMode(S1_PIN, OUTPUT);
  pinMode(S2_PIN, OUTPUT);

  TIMER1_init();

  Serial.begin(BAUD_RATE);
  while (! Serial);

  //Initializing all array elements to false!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  for (int i=0; i<=7; i++)
  {
    sensor_corruption[i] = false; // false means it's working ok. true means it's corrupted
  }

  setup_finished = true; //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

}

void loop()
{
  if (Serial.available())
  {
    /***** DEFINE MEASUREMENT MODE *****/
    String input = Serial.readString();
    if (input[0] == 'r' && interrupts_enabled == false)
    {
      if (input[1] == 'f')
      {
        full_mode = true;
        sensor_coord = 0;
      } else
        sensor_coord = input[2] - '0';

      select_sensor();

      /***** SET VARIABLES FOR DUMMY MEASUREMENT *****/
      number_of_samples = 10;

      pulse_counter = 0;
      measurement_counter = 0;

      TIMER1_clear();

      interrupts_enabled = true;
    }
  }

// TIMEOUT CODE HERE. TO DETERMINE IF A RESISTANCE IS OPEN CIRCUITED!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  if(setup_finished && millis() - timestamp > measurement_timeout)
  {
    sensor_corruption[sensor_coord] = true; //label the resistance (indicated by sensor_coord) as true in the boolean array. this means it's open circuited (no signal from circuit)
    measurement_finished = true;
    interrupts_enabled = false;
    ISR_unavailable = true;
  }

  if (measurement_finished)
  {
    //This does not get executed when the resistance is open circuited
    if (!ISR_unavailable) //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! this if statement is the only thing i added here
    {
      measurement_counter++;

      ticks = (overflows * 65536) + TCNT1;
      period = (ticks * 0.0625) / (number_of_samples - 1);

      if (measurement_counter == 1)
      {
         /***** SET VARIABLES FOR MEASUREMENT *****/
        number_of_samples = 500;

        pulse_counter = 0;

        TIMER1_clear();

        interrupts_enabled = true;
       }
    }
    else
    {
      TIMER1_print_results();

      if (full_mode)
      {
        sensor_coord++;

        select_sensor();

        /***** SET VARIABLES FOR DUMMY MEASUREMENT *****/
        number_of_samples = 10;

        pulse_counter = 0;
        measurement_counter = 0;

        TIMER1_clear();

        interrupts_enabled = true;

        if (sensor_coord == NUM_OF_SENSORS)
        {
          full_mode = false;
          interrupts_enabled = false;
        }
      }
    }
    measurement_finished = false;
    ISR_unavailable = false; //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    timestamp = millis();  //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  }
}

/***** INTERRUPT ROUTINES *****/

void count_time_of_k_pulses() {
  if (interrupts_enabled) {
    pulse_counter++;

    if (pulse_counter == 1)
      TIMER1_start();

    if (pulse_counter == number_of_samples) {
      TIMER1_stop();

      measurement_finished = true;
      interrupts_enabled = false;
    }
  }
}

ISR (TIMER1_OVF_vect) {
  overflows++;
}

/***** FUNCTION FOR SENSOR SELECTION *****/

void select_sensor() {
  digitalWrite(OE_BAR_PIN, LOW);
  digitalWrite(S2_PIN, ((sensor_coord & 4) == 4) ? HIGH : LOW );
  digitalWrite(S1_PIN, ((sensor_coord & 2) == 2) ? HIGH : LOW );
  digitalWrite(S0_PIN, ((sensor_coord & 1) == 1) ? HIGH : LOW );
}

/***** TIMER1 FUNCTIONS *****/

void TIMER1_init() {
  TCCR1A  = 0;
  TCCR1B  = 0;
  TIMSK1  = 0;
  TCCR1B |= (0 << CS12) | (0 << CS11) | (1 << CS10);
}

void TIMER1_start() {
  TIMSK1 |= (1 << TOIE1);
}

void TIMER1_stop() {
  TIMSK1 = 0;
}

void TIMER1_clear() {
  TCNT1     = 0;
  overflows = 0;
}

void TIMER1_print_results() {
  Serial.println("----------------------------------------");
  Serial.print("SENSOR COORDINATE         = ");
  Serial.println(sensor_coord);

  //Added the if-else statement, to cover the possibility of open circuited resistance !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  if (sensor_corruption[sensor_coord])
  {
  Serial.println("This resistance is open circuited!!!");
  }
  else
  {
  Serial.print("NUMBER OF PULSES MEASURED = ");
  Serial.println(pulse_counter);

  Serial.print("TIMER1 VALUE              = ");
  Serial.println(TCNT1);

  Serial.print("TIMER1 OVERFLOWS          = ");
  Serial.println(overflows);

  Serial.print("TICKS                     = ");
  Serial.println(ticks);

  Serial.print("MEASURED PERIOD           = ");
  Serial.print(period);
  Serial.println(" US");

  Serial.print("MEASURED RESISTANCE       = ");

  double resistanse = ((period * GAIN_VALUE * 1000) / (4 * CAPACITOR_VALUE)) - R_BIAS_VALUE; //kΩ
  Serial.print(resistanse);

  Serial.println(" kΩ");
  }

  Serial.println("----------------------------------------");
}

```

And this is the output i get:

```
----------------------------------------
SENSOR COORDINATE         = 0
This resistance is open circuited!!!
----------------------------------------
----------------------------------------
SENSOR COORDINATE         = 1
This resistance is open circuited!!!
----------------------------------------
----------------------------------------
SENSOR COORDINATE         = 2
This resistance is open circuited!!!
----------------------------------------
----------------------------------------
SENSOR COORDINATE         = 3
This resistance is open circuited!!!
----------------------------------------
----------------------------------------
SENSOR COORDINATE         = 4
This resistance is open circuited!!!
----------------------------------------
----------------------------------------
SENSOR COORDINATE         = 5
This resistance is open circuited!!!
----------------------------------------
----------------------------------------
SENSOR COORDINATE         = 6
This resistance is open circuited!!!
----------------------------------------
----------------------------------------
SENSOR COORDINATE         = 7
This resistance is open circuited!!!
----------------------------------------
----------------------------------------
SENSOR COORDINATE         = 8
This resistance is open circuited!!!
----------------------------------------
----------------------------------------
SENSOR COORDINATE         = 8
This resistance is open circuited!!!
----------------------------------------
----------------------------------------
SENSOR COORDINATE         = 8
This resistance is open circuited!!!
----------------------------------------
----------------------------------------
SENSOR COORDINATE         = 8
This resistance is open circuited!!!
----------------------------------------
----------------------------------------
SENSOR COORDINATE         = 8
This resistance is open circuited!!!
----------------------------------------

```

As you can see, all the resistances are falsely labeled as open circuited. Not only that but for some reason, it measures resistance 8 which does not exist, multiple times. Actually then it loops forever on resistance 8 (Normal operation stops at resistance 7 )

# Answer
I tried to understand your program and found quite a few issues, which I am listing below. This is more a general review than a specific answer. I hope it nevertheless helps you fix the code.

The major issue is the logic of `loop()` being quite convoluted and hard to follow. My guess is that the issue you face is a direct consequence of this single problem. I won't propose a fix because I can't really understand what this logic is supposed to accomplish. I think this problem is rooted in that logic having too much “state”, i.e. too many global variables that influence its behavior.

You may be able to make the logic of the function a lot clearer if you consolidate various state-defining variables into a single `enum` variable named `state`, and write the logic as in a regular finite state machine. This should make it a lot easier to understand, which in turn should make the bugs evaporate like magic.

Now, some specific details in the code.

I can't understand the purpose of `measurement_counter`. It is used only in the test `if (measurement_counter == 1)`. A boolean named `first_measurement` may be more appropriate here. Better yet if you can merge it into the unique `state` variable.

The variable `setup_finished` has no purpose at all. It is used only in `loop()` to test whether `setup()` is done. However, `loop()` only starts running after `setup()` is complete, so the test is pointless.

The handling of `OE_BAR_PIN` looks wrong: the pin goes `LOW` in `setup()` and never goes `HIGH` again. It would seem saner to initialize it `HIGH`, keep it `HIGH` when toggling the sensor-select pins, and only turn it `LOW` once a sensor has been properly selected. Thus:

```
void setup() {
  ...
  digitalWrite(OE_BAR_PIN, HIGH);
  pinMode(OE_BAR_PIN, OUTPUT);
  ...
}

void select_sensor() {
  digitalWrite(OE_BAR_PIN, HIGH);
  digitalWrite(S2_PIN, ((sensor_coord & 4) == 4) ? HIGH : LOW );
  digitalWrite(S1_PIN, ((sensor_coord & 2) == 2) ? HIGH : LOW );
  digitalWrite(S0_PIN, ((sensor_coord & 1) == 1) ? HIGH : LOW );
  digitalWrite(OE_BAR_PIN, LOW);
}

```

Note that `setup()` turns the pin `HIGH` *before* setting it as `OUTPUT`: this prevents an unwanted short `LOW` pulse.

The handling of Timer 1 is also flaky: it runs continuously. `TIMER1_start()` and `TIMER1_stop()` start and stop the overflow counting, not the timer itself. This means the measured tick count can be off by as much as ±65,535 ticks. It would be more sensible to really start and stop the timer as needed:

```
void TIMER1_init() {
  TCCR1A  = 0;
  TCCR1B  = 0;
  TIMSK1 |= (1 << TOIE1);
}

void TIMER1_start() {
  TCCR1B |= (0 << CS12) | (0 << CS11) | (1 << CS10);
}

void TIMER1_stop() {
  TCCR1B  = 0;
}

```

You probably want to call `TIMER1_stop()` when you detect a timeout.
> 1 votes

# Answer
In your code you are using the `measurement_finished` variable as a flag, that a new measurement was finished inside the ISRs, so that it can be handled inside the `loop()` function. This is very useful. As I understood, an open circuit means, that no measurement can happen, since no pulses are created. So you need to check, how much time passed since the last measurement.

Also the Arduino core sets up Timer0 for general timekeeping purposes. For example the `delay()` function uses it, and also functions like `micros()` and `millis()`, which will return the number of micro/milli-seconds elapsed since startup. So, if you are using these functions, you are actually using a hardware timer, but you don't have to set it up yourself. It is already done by the Arduino core.

So I suggest a principle similar to the `BlinkWithoutDelay` example from the Arduino IDE. First you define a global timestamp variable and a timeout value (here 1s aka 1000ms):

```
unsigned long timestamp=0;
unsigned long measurement_timeout=1000;

```

Then inside your `loop()` function (in fact you can do this exactly, where you placed the corresponding comment for the check), you check for the difference between the current time and the timestamp:

```
if(millis() - timestamp > measurement_timeout){

```

This will trigger, when the timestamp was last updated 1s ago. Inside this measurement, you do, what ever you need to do, if a measurement timeout happens (like printing an appropriate message to Serial). And now, we want to start a new timeout by updating the `timestamp` variable to the current time, as given by `millis()`. We could do this inside the corresponding ISR, but that would give us a problem. The ISR could fire right in between of the calculation of our if statement. This cannot happen for single byte variables (as for an 8 bit controller the current 8 bit action will be completed in one step), but `unsigned long` has 4 bytes. We would need to disable interrupts, when accessing it, to keep it from getting corrupted.

So we can simply set the timestamp inside the

```
if (measurement_finished) {

```

statement in the loop function. There we simply do

```
timestamp = millis();

```

to update the timestamp. As long, as the if statement is evaluated often enough (at least 1 time during the timeout range), it will work.

So, what happens in the changed code? When you start the code, it might think, that a zero measurement was done (if your `setup()` function needs longer than the timeout), but as soon, as the first measurement arrives, the `if (measurement_finished)` statement will execute and update the timestamp. Now the `millis()` if statement is disabled for the timeout duration, each new finished measurement will reset this timeout. It is like a dead man's switch. The timeout will trigger, when there is no one (or no code) to reset the timeout again.

---

BTW: As you are using interrupt routines, you should declare all variables, that get changed in an ISR as volatile like this:

```
volatile int pulse_counter = 0;

```

If you are not doing this, the compiler might optimize the variable to use a cached value, instead of the real value. Also think about, what I wrote above about variables changed by ISRs in the middle of a calculation. You have to be careful to not run in difficult to debug situations, if you don't protect your variables in the main code against change from an ISR.
> 1 votes

---
Tags: arduino-mega, interrupt, timers
---


title: Arduino encrypted Radio communication

text:
# Question
Title: Arduino encrypted Radio communication
Is there any way or library to communicate two Arduino devices with encrypted connection using modules NRF24L01 or "433Mhz RF" ? Similar encryption like CCMP in Wi-Fi network.

# Answer
Communicating and Encryption are to completely separate things. How you communicate (with what device) has no relevance to encryption. True, there are devices that can themselves encrypt data, but they tend to be higher-end or geared towards a specific purpose (such as WiFi).

What you send is just data. What that data consists of is entirely up to you. If you want your communications encrypted then send encrypted data before sending it and decrypt it after receiving it.

Of course, you have to then consider such things as sharing of keys, etc.

There are numerous ways of encrypting data, but one of the easiest to implement on Arduino is AES, for which there is a library here.
> 0 votes

---
Tags: arduino-mega, wireless, rf
---


# Question
Title: Bootloader difference between Atmel328p(through hole) and Atmel328p au(smd)
It’s been bugging me lot that Can’t we burn the same bootloader for both 328p and 328p au?

I got confused when I see this linksmd 328p au bootloader burn.

Will there be any impact on performance or any other impact if I use same bootloader for both?

# Answer
> 1 votes
The bootloader doesn't care about how many pins the device has. All it cares about is the UART pins, and they are the same.

Internally the two chips are the same, it's just the packaging that is different. They take the same silicon chip and mount it on a different lead frame and encapsulate it in epoxy. Which is why the only pin differences are a couple of extra power and ground pins, and two dedicated ADC pins that they don't connect in the DIP package. Even the pins are in the same order around the chip if you examine the pinouts in the datasheet.

Whether you use the DIP (Uno) or the SMD (Nano) bootloader it makes no difference (the two bootloaders are the same anyway). There can be no "perform better" anyway, since that isn't a valid concept. Either it is compatible, in which case it will work, or it's not, in which case it won't.

The only real thing of concern is to ensure that your fuses are set correctly for your chosen clock source, and that the bootloader you install is compiled to run at the speed of your chosen clock source. That has nothing at all to do with which chip it is you are using, but how you have designed your circuit.

# Answer
> 0 votes
Two different bootloaders are used for ATmega328p. One is used in Uno, it is based on Optiboot 4. Second is used in Arduio Nano and is based on Atmel bootloader. Arduino replaced the old Nano bootloader with the Uno Optiboot bootloader in 2018, but Nano clones and old Nanos still in use have the old bootloader. In current AVR boards package version there is a bootloader selection in Tools menu.

With the burn of bootloader fuses are written to set the bootloader area size.

The old Nano bootloader is 2 kB large. The Optiboot bootloader is 0.5 kB large (small). But Arduino didn't change for Nano the size of the flash memory reserved for bootloader so 1.5 kB of flash memory is lost because of inaccurate fuse setting.

The old Nano bootloader didn't reset the watchdog flag. If your sketch setup the watchdog for some short time, after the reset the watchdog did reset the MCU while still in bootloader ending in endless reset loop.

The tutorial in your question would flash the Nano bootloader, because the author of the tutorial has Nano as target board while burning the bootloader. In 2017 it would be the Old bootloader.

So the Uno bootloader is recommended for ATmega328p with Uno fuse settings for bootloader size. After uploading the "Arduino as ISP" sketch and before activating "Burn bootloader" change the board selection to Uno.

Notes:

* For ATmege328p with different frequency then 16 MHz the bootloader must by build with the required frequency.
* there are newer versions of Optiboot (7 is current) with additional options. Some of the options result in larger bootloader.

---
Tags: arduino-uno, arduino-nano, atmega328, bootloader, arduino-uno-smd
---


# Question
Title: Cancelling state of code before going to interrupt
Currently, I have two loops in my Arduino code.

Certain cases take me from loop 1 to loop 2

I also have an ISR

When my ISR condition is met the code is executed and part of the ISR code is supposed to go to loop 1. Which it does but...

Then I close the ISR accordingly, but the service routine goes back to loop 2.

Any ideas why?

I've been surfing the web for the past couple hours and haven't caught a wave..

Thanks all.

```
//Physical variables
int eStop = 3;         // the number of the input pin
int eStopLED = 9;       // the number of the output pin

int dispenseButton = 6;         // the number of the input pin
int dispenseLED = 8;       // the number of the output pin

// have 789 for colors and 3456 for input only 3 ND 6 NEEDS TO BE USED

int eStopZone = HIGH;      // the current eStopZone of the output pin
int eStopScan;           // the current eStopScan from the input pin
int eStopPrior = LOW;    // the eStopPrior eStopScan from the input pin

int dispenseZone = HIGH;      // the current eStopZone of the output pin
int dispenseScan;           // the current eStopScan from the input pin
int dispensePrior = LOW;    // the eStopPrior eStopScan from the input pin

//Other Variables
volatile int vControl = 0;
int eVar;
int i; //Normal counting integer

// will quickly become a bigger number than can be stored in an int.
long time = 0;         // the last time the output pin was toggled
long debounce = 200;   // the debounce time, increase if the output flickers

void control(void);
void emergency(void);
//another coid for char ring

void setup()
{
  pinMode(eStop, INPUT);
  pinMode(eStopLED, OUTPUT);

  pinMode(dispenseButton, INPUT);
  pinMode(dispenseLED, OUTPUT);
  eVar = 0;
  Serial.begin(9600);  //Start Serial
  attachInterrupt(digitalPinToInterrupt(eStop), emergency, CHANGE);
}

void loop()
{
  eStopScan = digitalRead(eStop);
  dispenseScan = digitalRead(dispenseButton);
  //Serial.println(eStopScan);
  /*if (eStopScan == HIGH && eStopPrior == LOW && millis() - time > debounce) { //eStop control conditions
    switch (eVar) {
      case 0:
        vControl = 0;
        control();
        break;

      case 1:
        vControl = 1;
        control();
        break;
    }
    time = millis();
    }
  */

  if (dispenseScan == HIGH && dispensePrior == LOW && millis() - time > debounce) { //dispense control conditions
    Serial.println("in this loop");
    switch (eVar) {
      case 0:
        vControl = 2;
        control();
        break;

      case 1:
        vControl = 3;
        control();
        break;
    }
    time = millis();
  }

  eStopPrior = eStopScan;
  dispensePrior = dispenseScan;
}

void control () {

  switch (vControl) {
    case 0: //estop case put in another variable for showing last estop state
      eStopZone = HIGH;
      dispenseZone = LOW;
      digitalWrite(dispenseLED, dispenseZone);
      digitalWrite(eStopLED, eStopZone);
      eStopScan = LOW;
      dispenseScan = LOW;
      Serial.println("Case 0");
      //eVar = 1;
      break;

    case 1:
      for (int i = 0; i <= 2; i++) {
        eStopZone = LOW;
        digitalWrite(eStopLED, eStopZone);
        delay(345);
        eStopZone = HIGH;
        digitalWrite(eStopLED, eStopZone);
        delay(345);
        Serial.println("Case 1");
        //Serial.println(i);
      }
      break;

    case 2:
      dispenseZone = HIGH;
      eStopZone = HIGH;
      digitalWrite(eStopLED, eStopZone);
      digitalWrite(dispenseLED, dispenseZone);
      Serial.println("here 1");
      delay(1000);
      Serial.println("here?");
      eStopZone = LOW;
      digitalWrite(eStopLED, eStopZone);
      Serial.println("Case 2");
      break;

    case 3:
      dispenseZone = HIGH;
      eStopZone = LOW;
      digitalWrite(eStopLED, eStopZone);
      digitalWrite(dispenseLED, dispenseZone);
      eVar = 0;
      Serial.println("Case 3");
      // make led go green
      break;
  }
  time = millis();
  loop();
}

void emergency () {
  Serial.println("interrupt");
  vControl = 0;
  control();
}

```

Com window from debugging

```
in this loop
here 1
here?
Case 2
in this loop
here 1
here?
Case 2
in this loop
here 1
interrupt
interrupt
interrupt
here?
Case 2

```

# Answer
> 1 votes
Your explanation of what you expect to happen is not very clear but I'll take a stab at your question.

First thing - Interrupt Service Routines (ISR) need to be *short* (execution time, not necessarily code length). Do the minimum necessary to save whatever status or data caused the interrupt and exit. Let the background (your main sketch) handle any further processing resulting from the interrupt.

That means the ISR has to leave some indication - a boolean flag, f/ex - that it did something, and your background has to check that frequently, act on it when it changes, and reset it for the next interrupt.

It looks like your ISR is calling into your background code, which effectively becomes part of the ISR, runs at interrupt level, prevents further interrupts while it is doing so, and (possibly) returns to your background code at a place or in a state that is no longer relevant by then.

Think about organizing your code so that the background does whatever ongoing, routine tasks you need it to be doing, but checking frequently for whether an interrupt has occurred yet. When one has, do whatever needs to done to handle it, reset the "interrupt has occurred" flag, and return to your background task(s).

# Answer
> 1 votes
I cannot see what actually goes wrong, but you're calling way too much stuff in your ISR. You're changing non-volatile variables with the `control()` call in your ISR, leading to undefined behaviour: You don't know *when* the ISR is being called, especially not whether it is called before or after the non-volatile variables have been transferred from memory to the registers or back in the routine started from `loop()`. Also: Never output anything from an ISR nor from code you call from that ISR. Serial communication is slooow (compared to what the processor could be doing in that time frame).

I'd say: The only thing your ISR should do is to add 1 to a volatile variable, then end. In your `loop()`, check whether that volatile variable is greater than 0, then reset the volatile variable back to 0 and run what you've got in your current ISR. To react to the interrupt in a timely manner, this also means that you should not use `delay()` anywhere in your code. This would put your code back into defined behaviour, at least.

---
Tags: arduino-uno, interrupt
---


title: Multiple Time-Sensitive Tasks

text:
# Question
Title: Multiple Time-Sensitive Tasks
I'm using an Arduino Leonardo and need to perform two time-sensitive tasks like this:

```
// Task 1 - Gets executed once a second (1Hz)
// Execution of task needs approx 70ms
   task1(); //Sending a message via Serial

// Task 2 - Gets executed 50 times a second (50Hz)
// Execution of task need a few micros
   task2(); //digitalWrite

```

As you can see, the problem is, that task one needs very long for execution and therefore task2 is executed too late to send a 50Hz signal. I'm not sure how, but I think there must be a way to give task 1 higher priority to interrupt task 2?

Thanks in advance! :)

**Just for completion**, here is my (not so clean) code:

```
#include <SoftwareSerial.h>
SoftwareSerial mySerial(7, 6); //232_TX,232_

int triggerFreq = 10;
unsigned long timestamp_pps;
unsigned long timestamp;
unsigned long triggerStartTime;
const unsigned long dt_pps = 1000000; //micros
const unsigned long dt_trig = 1000000/triggerFreq; //micros
unsigned long ts_pps_high;
unsigned long ts_pps_low;
unsigned long ts_msg_high;
unsigned long ts_msg_low;

unsigned long i_pps = 0;
unsigned long i_trig = 0;

int hh = 04;
int mm = 51;
int ss = 00;
unsigned int pos = 2307;
bool msg;
bool trigMsgSent;

void setup() {
  // put your setup code here, to run once:
  pinMode(11, OUTPUT); // PPS
  pinMode(12, OUTPUT); // Indicator of msg_sent
  pinMode(13, OUTPUT); // FPS
  Serial.begin(9600);
  mySerial.begin(9600);
  triggerStartTime = micros();
}

void loop() {
  // ================== Part for the GPS Simulation ==================
  timestamp_pps = micros()-triggerStartTime;
  if (timestamp_pps>= dt_pps*i_pps+350000)
  {
    pos += 1;
    digitalWrite(12,HIGH);
    i_pps +=1;
    if (ss == 59)
    {
      ss=0;
      if (mm==59)
      {
        mm=0;
        hh+=1;
      }
      else mm+=1;
    }
    else ss+=1;

    ts_msg_high = micros();
    mySerial.print("$GPRMC,");
    if (hh<10) mySerial.print(F("0"));
    mySerial.print(hh);
    if (mm<10) mySerial.print(F("0"));
    mySerial.print(mm);
    if (ss<10) mySerial.print(F("0"));
    mySerial.print(ss);
    mySerial.print(".000,A,3015.");
    mySerial.print(pos);
    mySerial.println(",N,09749.2872,W,0.67,161.46,030913,,,A*7C");

    // Print Debug Messages
    digitalWrite(12,LOW);
    ts_msg_low=micros();
    Serial.print("PPS at: ");
    Serial.print(ts_pps_high);
    Serial.print("\t PPS low after: ");
    Serial.print(ts_pps_low-ts_pps_high);
    Serial.print("\t MSG high after: ");
    Serial.print(ts_msg_high-ts_pps_high);
    Serial.print("\t MSG low after: ");
    Serial.print(ts_msg_low-ts_pps_high);
    Serial.print("$GPRMC,");
    if (hh<10) Serial.print(F("0"));
    Serial.print(hh);
    if (mm<10) Serial.print(F("0"));
    Serial.print(mm);
    if (ss<10) Serial.print(F("0"));
    Serial.print(ss);
    Serial.print(".000,A,3015.");
    Serial.print(pos);
    Serial.println(",N,09749.2872,W,0.67,161.46,030913,,,A*7C");
  }
  else if (timestamp_pps>=dt_pps*i_pps+100000)
  {
    digitalWrite(11,LOW);
    if (msg==true)
    {
      msg = false;
      ts_pps_low = micros();
    }

  }
  else if (timestamp_pps>=dt_pps*i_pps)
  {
    digitalWrite(11,HIGH);
    if (msg==false)
    {
      msg = true;
      ts_pps_high = micros();
    }
  }
  // ================== Part for the FPS Trigger ==================
  timestamp = micros()-triggerStartTime;
  if (timestamp>= dt_trig*i_trig+2000)
  {
    digitalWrite(13,LOW);
    i_trig +=1;
    trigMsgSent = false;
  }
  else if (timestamp >=dt_trig*i_trig)
  {
    digitalWrite(13,HIGH);
    if (trigMsgSent == false)
    {
      Serial.print("FPS at: ");
      Serial.println(micros());
      trigMsgSent = true;
    }
  }

}

```

---

**Update:** So i implemented it with an interrupt according to this example. I just programmed the interrupt for the 50Hz signal, because that one must be accurate. The code is at the end. However, I'm still experiencing the 50Hz signal to be late when the serial is sent. It's now in the dimensions of half a millisecond, but that's not negligible in my project (Sensor fusion computer vision). The output of my post-processing-tool shows:

```
Trigger Nr. 25 is 646.912us late!
Trigger Nr. 28 is 434.176us late!
Trigger Nr. 75 is 653.056us late!
Trigger Nr. 78 is 429.056us late!
Trigger Nr. 125 is 646.912us late!
Trigger Nr. 128 is 434.944us late!
Trigger Nr. 175 is 646.912us late!
Trigger Nr. 178 is 439.04us late!
Trigger Nr. 225 is 646.912us late!
Trigger Nr. 228 is 440.064us late!
Trigger Nr. 275 is 647.168us late!
Trigger Nr. 278 is 434.944us late!
Trigger Nr. 325 is 611.84us late!
Trigger Nr. 328 is 462.08us late!
Trigger Nr. 375 is 612.864us late!
Trigger Nr. 378 is 475.136us late!
Trigger Nr. 425 is 619.008us late!
Trigger Nr. 428 is 473.856us late!
Trigger Nr. 475 is 613.888us late!
Trigger Nr. 478 is 467.968us late!
Trigger Nr. 525 is 612.864us late!
Trigger Nr. 528 is 474.88us late!
Trigger Nr. 575 is 613.12us late!

```

Does anyone know how I could improve my code?

Code:

```
//GPS DEFINITIONS
#include <SoftwareSerial.h>
SoftwareSerial mySerial(7, 6); //232_TX,232_

int triggerFreq = 50;
unsigned long timestamp_pps;
//unsigned long timestamp;
unsigned long triggerStartTime;
const unsigned long dt_pps = 1000000; //micros
//const unsigned long dt_trig = 1000000/triggerFreq; //micros
unsigned long ts_pps_high;
unsigned long ts_pps_low;
unsigned long ts_msg_high;
unsigned long ts_msg_low;

unsigned long i_pps = 0;
//unsigned long i_trig = 0;

int hh = 04;
int mm = 51;
int ss = 00;
unsigned int pos = 2307;
bool msg;
bool trigMsgSent;

void setup() {

  cli();//stop interrupts
  //set timer1 interrupt at 1Hz
  TCCR1A = 0;// set entire TCCR1A register to 0
  TCCR1B = 0;// same for TCCR1B
  TCNT1  = 0;//initialize counter value to 0
  // set compare match register for 1hz increments
  //OCR1A = 15624;// = (16*10^6) / (1*1024) - 1 (must be <65536)
  OCR1A = 19999; // = (16*10^6) / (100 * 8) -1 (must be <65536)
  // turn on CTC mode
  TCCR1B |= (1 << WGM12);
  // Set CS11 bit for 8 prescaler
  TCCR1B |= (1 << CS11);
  // enable timer compare interrupt
  TIMSK1 |= (1 << OCIE1A);
  sei();//allow interrupts

  // GPS SETUP
  pinMode(11, OUTPUT); // PPS
  pinMode(12, OUTPUT); // Indicator of msg_sent
  pinMode(13, OUTPUT); // FPS
  Serial.begin(9600);
  mySerial.begin(9600);
  triggerStartTime = micros();

}

ISR(TIMER1_COMPA_vect){  //change the 0 to 1 for timer1 and 2 for timer2
   //interrupt commands here
   digitalWrite(13,!digitalRead(13));
}

void loop() {
  // ================== Part for the GPS Simulation ==================
  timestamp_pps = micros()-triggerStartTime;
  if (timestamp_pps>= dt_pps*i_pps+350000)
  {
    pos += 1;
    digitalWrite(12,HIGH);
    i_pps +=1;
    if (ss == 59)
    {
      ss=0;
      if (mm==59)
      {
        mm=0;
        hh+=1;
      }
      else mm+=1;
    }
    else ss+=1;

    ts_msg_high = micros();
    mySerial.print("$GPRMC,");
    if (hh<10) mySerial.print(F("0"));
    mySerial.print(hh);
    if (mm<10) mySerial.print(F("0"));
    mySerial.print(mm);
    if (ss<10) mySerial.print(F("0"));
    mySerial.print(ss);
    mySerial.print(".000,A,3015.");
    mySerial.print(pos);
    mySerial.println(",N,09749.2872,W,0.67,161.46,030913,,,A*7C");

    // Print Debug Messages
    digitalWrite(12,LOW);
    ts_msg_low=micros();
    Serial.print("PPS at: ");
    Serial.print(ts_pps_high);
    Serial.print("\t PPS low after: ");
    Serial.print(ts_pps_low-ts_pps_high);
    Serial.print("\t MSG high after: ");
    Serial.print(ts_msg_high-ts_pps_high);
    Serial.print("\t MSG low after: ");
    Serial.print(ts_msg_low-ts_pps_high);
    Serial.print("$GPRMC,");
    if (hh<10) Serial.print(F("0"));
    Serial.print(hh);
    if (mm<10) Serial.print(F("0"));
    Serial.print(mm);
    if (ss<10) Serial.print(F("0"));
    Serial.print(ss);
    Serial.print(".000,A,3015.");
    Serial.print(pos);
    Serial.println(",N,09749.2872,W,0.67,161.46,030913,,,A*7C");
  }
  else if (timestamp_pps>=dt_pps*i_pps+100000)
  {
    digitalWrite(11,LOW);
    if (msg==true)
    {
      msg = false;
      ts_pps_low = micros();
    }

  }
  else if (timestamp_pps>=dt_pps*i_pps)
  {
    digitalWrite(11,HIGH);
    if (msg==false)
    {
      msg = true;
      ts_pps_high = micros();
    }
  }

}

```

# Answer
Here lies your ≈ ½ ms problem:

> `#include <SoftwareSerial.h>`

SoftwareSerial is very time sensitive. It generates the serial stream by bit-banging, *with interrupts disabled*. For each byte sent, interrupts are disabled just before sending the start bit, and re-enabled just after the stop bit has been written. At 9600 bps, interrupts are thus disabled for a little more than 9 bit times on each byte, i.e. 936 µs.

Do not use SoftwareSerial if you need short interrupt latency. Use a hardware serial port instead. This can be problematic on the Uno, where you would loose the ability to send debugging info, but it is fine on the Leonardo.

Alternatively, if the *only* thing your ISR has to do is toggle a pin, you can instead configure the timer to generate that as PWM. This way the CPU is not involved at all in the pin toggling, and you get cycle-accurate signal timing irrespective of interrupt latency.

---

**Edit**: Answering your comment.

About the hardware serial ports: on the Uno you just have `Serial`, so you are out of luck if you want one port for outputting NMEA sentences and another one for debugging information. However, on the Leonardo, `Serial` is a virtual serial port emulated over USB. The real hardware serial port is called `Serial1`, and you should use it in preference to a `SoftwareSerial` instance.

About “more than just toggle the pin”: You may still be able to use PWM if whatever other stuff task2 has to perform is less time-critical than toggling the pin. In this case, you use PWM to toggle the pin on the `TIMER1_COMPA` event, and `ISR(TIMER1_COMPA_vect)` to do the other stuff. Then, each time the timer hits `TIMER1_COMPA`, it will immediately toggle the pin and, *at the same time*, rise an interrupt request. The CPU may take some time to service the request, but this delay could be acceptable if only the toggling needs extra-accurate timing.
> 2 votes

# Answer
Two possible solutions:

1. Split the serial string in small pieces so it's (comfortably) less than 50 ms and send the string in 'pieces' … you could even send it until e.g. 45 ms has been reached and continue in the next round. Use the Blink Without Delay mechanism to switch between the tasks.
2. More robust solution: Make Task 2 an interrupt... This is probably much easier, since you can keep sending the serial string and the MCU takes care of automatically starting the interrupt each 50 ms. Make sure the interrupt code is very short. When it is finished, it will automatically resume with the normal code (sending serial data). I have not checked this library, but it seems very simple to use: https://playground.arduino.cc/Code/Timer/ .
> 3 votes

---
Tags: arduino-uno, programming, arduino-leonardo
---


# Question
Title: How should I connect 5 buttons to arduino so that I can use the least number of inputs all the buttons are connected to ground
The problem here is that I want to connect 5 input buttons to an Arduino but I do not want to utilize 5 input pins of Arduino, is there any matrix like connection using which I can reduce the number of inputs used. The conditions here are:

* All the buttons will be connected to ground and initialized using:

`pinMode(PIN_NUMBER, INPUT_PULLUP)`
* Only digital input is required and not analogue

# Answer
> 2 votes
> Only digital input is required and not analogue

I'd consider arranging the switches to produce different voltages depending on which button was pressed and feed the resulting analogue signal level into one of these (the MOD input): -

It doesn't need to run at 1 MHz of course; RSET can be chosen to make it free run at (say) 1 kHz. The resulting duty cycle (set by the switches) can be read under software control via a digital input line.

# Answer
> 5 votes
If all switches have one input grounded, you cannot use matrixing.

In any case, the best you could do would be a 2 * 3 matrix, which uses 5 signals, the same as individual switching (though you may be able to share the strobes with other signals e.g. display strobes)

If you are allowed to use an analog input you can pull the input high with one resistor, and allow each switch to pull it low with a different resistance. Then each switch results in a different analog voltage and you can decipher an ADC reading into a switch input. That way, only one input is required.

# Answer
> 2 votes
If you do not want to use analog input but not opposed to adding one more component then you can get by with 3 digital pins, two connected to shift register (e.g. SN74HC164) and one reading common return from all buttons. Binary counter can also be used, but with rather high latency.

If you are OK with complicating things even more, you can use external logic for initializing the register, in which case two pins would be sufficient - one for clock output and another for feedback input.

Here is a simple circuit that can be extended to scan any number of buttons by chaining registers or choosing chips with more bits.

Unlike the answers stretching "digital input" function (as implied by OP) to include PWM and Serial communication, this method uses simplest digital I/O: one pin cyclically selects the button, another reads whether it is pressed or not.

The same 2-pin principle (selector output + feedback input) can be used in many different combinations. For example, you can have one side of each switch connected to the ground, as you mentioned in your question. The other sides are fed back to Arduino via analog MUX (e.g. 74HC4051). The MUX address is selected by binary counter (e.g. 74HC193) and the counter is reset by its own QD pin when it reaches 0x08.

# Answer
> 2 votes
If you have only one digital pin available, you might consider the 1-wire bus. For example, the DS2408 provides 8 open-drain GPIO pins.

---

If you can use an analog input pin, then Brian's answer is correct.

Some simple adjustments of the resistor values create equal-size voltage steps for the A/D converter as shown below.

For the 4-switch case, this gives 5V for no switch pressed, and 0-3.75V in approximately equal steps for a switch press. This approach works well up to 16 switches and beyond.

The general approach for calculating the resistor values is as follows:

1. Select the pullup resistor value; say, 10K ohms.
2. Decide how many switches are required: N = 16.
3. The top switch generates 0 volts by shorting the A/D input to ground.
4. The next switch down will generate Vcc / N volts:

R = 10k × 1/(N-1) = 666.7 Ω
5. Select the nearest standard 5% value: 680 ohms
6. Repeat for switches i = 2 through N - 1:

* The next switch down will generate Vcc × i / N volts, but you must subtract out the values of the resistors above it. This helps avoid cumulative errors.

    R = 10K × i/(N - i) - 680 Ω - ...
    * Select the nearest standard 5% value.

For the specific example of 16 switches, you should end up with the following resistor values: 680, 750, 910, 1000, 1200, 1500, 1800, 2200, 2700, 3900, 5600, 7500, 13K, 27K and 82K. Even with 5% resistors, all of the resulting voltages are within 0.25% of full scale of their nominal values.

---
Tags: input, button
---


title: How to send data from PC to arduino?

text:
# Question
Title: How to send data from PC to arduino?
How can I read data in Arduino IDE from a text file, if I have a text file which has the angle of arm at the different time intervals? If I want to read a text file from PC, can anyone please show the demonstration code as well? I am attaching a code where I am writing a position to servo1 whose values I want to give via text file.

```
#include <Servo.h>

Servo myservo1 ;
int pos1 = 0;

void setup() {
  myservo1.attach(4);   //inner
}

void loop() {
   myservo1.write(pos1); // pos1 I will give different angles via text file
}

```

If I am not using SD card module, how can I do this with PC only? Someone please help.

# Answer
I assume you want to store multiple values in the text file, and then have the Arduino IDE (not the Arduino itself) read the file and insert the data into your sketch. If this is really what your question is about, a quick and dirty solution would be as follows:

1. Format the text file as a list of comma-separated numbers, either in one or several lines. For example:

```
1, 12, 23, 34, 45, 56, 67,
78, 89, 100

```
2. Include this file in your sketch as the body of an array initializer:

```
#include <Servo.h>

const int positions[] = {
#include "full_path_of_the_file_holding_the_positions"
};
#define positions_length (sizeof positions / sizeof positions[0])

Servo myservo1;

void setup() {
    myservo1.attach(4);
}

void loop() {
    for (int i = 0; i < positions_length; i++) {
        myservo1.write(positions[i]);
        delay(200);
    }
}

```
> 0 votes

---
Tags: arduino-ide
---


title: Pressure Switch 4-20mA

text:
# Question
Title: Pressure Switch 4-20mA
Im working on a project trying to read the pressure value from an Allen Bradley Pressure Transmitter 836P-D2NFGB20PA-D4 Ser.A

However the pin configuration that comes on the description along with the schematics its way different that the one i used before

And the circuit im using is like this one, on the top its the circuit from the pressure documentation, and the bot one it the one im wiring on my Arduino Uno.

However on arduino im reading a constant value of 230 that does not increase nor decrease when i apply pressure to mi sensor even when the lcd on my sensor displays the correct psi value.

```
#include <LiquidCrystal.h> //libreria
int V0 = 3;
int RS= 4;
int E = 5;

int D4 = 6;
int D5 = 7;
int D6 = 8;
int D7 = 9;
LiquidCrystal lcd(RS, E, D4, D5, D6, D7); //Indicar los pins de la interfaz

//Variables globales
int SensorPin= 0; //Variable del pin de entrada del sensor
int indice; //posicion del array de textos
int presion; //variable para almacenar el valor obtenido del sensor(0 a 1023)
int outputValue = 0;
int state = 0;
int prv_state = -1;

#define ARRAYTXT 4 //Numero de textos a escribir

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

Serial.begin(9600);
analogWrite(V0, 50);

//lcd.begin(16, 2);
//lcd.clear();
//lcd.begin(Cols, Rows);
}

void loop() {

 //Configuramos un comando de textos
  String textos[ARRAYTXT] = {"Baja presion", "Presion normal", "Alta presion", "Apagar Maquina"};

  presion = analogRead(SensorPin); //obtenemos datos del sensor
    outputValue = map(presion, 175, 1023, 0, 367);

//Indicamos los textos que se definieron en el comando texto al principio("Baja presion" = 0)
  if(outputValue < 50){
    indice = 0;
  } else{
    if(outputValue >=50 && outputValue < 100){
      indice = 1;
    }else{
      if(outputValue >=100 && outputValue < 200){
        indice = 2;
      }else{
        if(outputValue >=200 && outputValue < 350){
          indice= 3;
        }
      }
    }
  }
  //lcd.clear(); // se borran pantallas
  //lcd.setCursor(0, 0); //Escribimos en la fila de abajo
  Serial.print("PRESION: "); // escribimos mensaje en el lcd
  Serial.print(outputValue,DEC);
  Serial.println(" PSI");
  //lcd.setCursor(0, 1); //Escribimos en la fila de abajo
  Serial.println(textos[indice]); // Indicamos que imprima los indices
  //Serial.print("Psi ");
  //Serial.println(outputValue);
  delay(200); //Tiempo para repetir el mensaje(1 segundo)
  //lcd.clear();
}

```

# Answer
Your drawing is different from the drawing in the wiring diagram of that sensor: the resistor has to be connected right like the "4-20mA"-block in the drawing, (-) goes to ground. Measure the voltage directly at pin 2. When reading the sensor's analog signal you can probably leave pin 4 floating.
> 1 votes

# Answer
I think this is the connection you want. Leave out the OUT connection completely and use a 250 ohm resistor (the datasheet says \< 0.5 kiloohm).
> 1 votes

---
Tags: arduino-uno, sensors, pressure
---


# Question
Title: Hardware serial not working, SoftwareSerial is
On my Uno-equivalent Arduino, a SoftwareSerial connection (on RX, TX = 8, 9) is working\*, while a hardware serial connection to the same device, set up in the same way (but on pins RX, TX = 0, 1) is not working. Why is the hardware serial setup not working?

\*By working I mean receiving a byte from the external device

**Edit:** as a simple example:

```
void setup() {
  Serial.begin(38000);
  pinMode(7, OUTPUT);
}

void draw() {
  if (Serial.available() > 0) {
    Serial.read();
    tone(7, 440, 1000);
  }
}

```

The above, using `Serial`, doesn't work, whereas

```
#include <SoftwareSerial.h>

SoftwareSerial serial(8, 9);

void setup() {
  serial.begin(38000);
  pinMode(7, OUTPUT);
}

void draw() {
  if (serial.available() > 0) {
    serial.read();
    tone(7, 440, 1000);
  }
}

```

does work.

---

I don't know if this helps, but connecting RX/TX through an LED to ground gave me the following, using Serial on (0, 1) and SoftwareSerial on (8, 9):

**Serial**
RX: bright
TX: bright
**SoftwareSerial**
RX: dim (but still lit)
TX: bright

Is the fact that RX is dim using SoftwareSerial significant?

# Answer
> 1 votes
There may be several reasons

1. Be sure uC pin connect pin header
2. In setup part, you write Serial.begin(xxxx);
3. After serial begin, don't change this pins IO features(Input, output)

Please check that after if not solve, please share code

# Answer
> 1 votes
I would check if the arduino you are using supports your selected baudrate.

38000 is not a standard rate and it could be, that the hardware is not able to work at it with the needed precision. The software serial (and most USB serial dongles) could use any baudrate, but not the limited hardware within most arduinos.

---
Tags: serial
---


# Question
Title: Serial Monitor is printing out weird values and skipping strings
I am currently working on a project with some friends. In short, we want to create a setup where when a button is pressed a thermal printer prints out a random sentence.

I am currently trying to get my code to work and to debug it with the Serial Monitor, but it prints out weird stuff.

The baud rate is the same for the monitor and the Serial.begin().

```
int checkSum[] = {-1, -1};

String stringPool[] =
                      {
                        "Satz 1", "Satz 2",
                        "Satz 3", "Satz 4",
                        "Satz 5", "Satz 6",
                        "Satz 7", "Satz 8",
                        "Satz 9", "Satz 10",
                        "Satz 11", "Satz 12",
                        "Satz 13", "Satz 14",
                        "Satz 15", "Satz 16",
                        "Satz 17", "Satz 18",
                        "Satz 19", "Satz 20",
                        "Satz 21", "Satz 22"
                      };

String chooseRandom ()
{
  bool isMaybeThreeTimes;
  int randomInt;

  do
  {
      randomInt = random( 0, sizeof( stringPool ) -1 );

      // first and further random number chosen
      if( checkSum[0] == -1 ) { checkSum[0] = randomInt; }
      else
      {
        checkSum[1] = checkSum[0];
        checkSum[0] = randomInt;
      }

      if( randomInt == checkSum[0] && randomInt == checkSum[1] )
      {
        isMaybeThreeTimes = true;
      }
      else
      {
        isMaybeThreeTimes = false;
      }

      Serial.print("Current random value: " + randomInt);
      delay(1000);
      Serial.print("Last random value: " + checkSum[0]);
      delay(1000);
      Serial.print("Last last random value: " + checkSum[1]);
      delay(1000);
      Serial.print("Three times in row?: " + isMaybeThreeTimes);
      delay(1000);

   } while ( isMaybeThreeTimes );

  return stringPool[randomInt];
}

void buttonPressed()
{
  String stringToPrint = chooseRandom();
  // Send the string to the adafruit printer.
  Serial.println(stringToPrint);
}

void setup()
{
    Serial.begin(19200);
    delay(2000);
    Serial.println("Setup finished");
    randomSeed(analogRead(0));

}

void loop()
{
    buttonPressed();
}

```

Any ideas why this is happening? I switched the baud rates changed delays and changed the places on where and how often and in which frequeny the method buttonPressed() is called.

Here a picture of the output:

# Answer
> 2 votes
```
int checkSum[] = {-1, -1};

const String stringPool[] = {
                        "Satz 1", "Satz 2", "Satz 3", "Satz 4",
                        "Satz 5", "Satz 6", "Satz 7", "Satz 8",
                        "Satz 9", "Satz 10", "Satz 11", "Satz 12"
                      };

const String& chooseRandom () {
  bool isMaybeThreeTimes;
  int randomInt;

  do {
      randomInt = random( 0, sizeof(stringPool) / sizeof(stringPool[0]));
      isMaybeThreeTimes = (randomInt == checkSum[0] && randomInt == checkSum[1] );

      Serial.print("Current random value: "); Serial.println(randomInt);
      delay(1000);
      Serial.print("Last random value: "); Serial.println(checkSum[0]);
      delay(1000);
      Serial.print("Last last random value: "); Serial.println(checkSum[1]);
      delay(1000);
      Serial.print("Three times in row?: ");
      Serial.println(isMaybeThreeTimes?"Yes":"No");
      delay(1000);
      checkSum[1] = checkSum[0]; // for next run
      checkSum[0] = randomInt;
  } while (isMaybeThreeTimes);
  return stringPool[randomInt];
}

void buttonPressed()
{  // has nothing to do with button presses, just a test
  const String& stringToPrint = chooseRandom();  // waits 3 seconds
  // Send the string to the adafruit printer.
  Serial.println(stringToPrint);
}

void setup() {
    Serial.begin(19200);
    delay(2000);
    Serial.println("Setup finished");
    randomSeed(analogRead(0));
}

void loop() {
    buttonPressed();
}

```

Some fixes, not tested. Edit: some more fixes, tested.

---
Tags: arduino-uno, serial, print
---


# Question
Title: Error compiling code for Arduino/Genuino Uno. "multiple definition of `__vector_7"
```
#include <PulseSensorPlayground.h>

int pulsePin = A0;                 // Pulse Sensor purple wire connected to analog pin A0
int Redled = 7;  // The pin for the Red LED which notifies you if you're heart rate is increasing.
int Greenled = 8; // The pin for the Green LED which notifies you if you're heart rate is stable.
int buzzer = 9; // The pin for the piezo which plays music when you're heart rate is increasing.
int music[] = {261, 277, 294, 311, 330, 349, 370, 392, 415, 440};//The frequency the piezo will play.

// the follow variables are long's because the time, measured in miliseconds,
// will quickly become a bigger number than can be stored in an int.
long time = 0;         // the last time the output pin was toggled
long debounce = 200;   // the debounce time, increase if the output flickers
//push button part stop

// Volatile Variables, used in the interrupt service routine!
volatile int BPM;                   // int that holds raw Analog in 0. updated every 2mS
volatile int Signal;                // holds the incoming raw data
volatile int IBI = 600;             // int that holds the time interval between beats! Must be seeded!
volatile boolean Pulse = false;     // "True" when User's live heartbeat is detected. "False" when not a "live beat".
volatile boolean QS = false;        // becomes true when Arduoino finds a beat.

static boolean serialVisual = true;   // Set to 'false' by Default.  Re-set to 'true' to see Arduino Serial Monitor ASCII Visual Pulse

volatile int rate[10];                      // array to hold last ten IBI values
volatile unsigned long sampleCounter = 0;          // used to determine pulse timing
volatile unsigned long lastBeatTime = 0;           // used to find IBI
volatile int P = 512;                      // used to find peak in pulse wave, seeded
volatile int T = 512;                     // used to find trough in pulse wave, seeded
volatile int thresh = 525;                // used to find instant moment of heart beat, seeded
volatile int amp = 100;                   // used to hold amplitude of pulse waveform, seeded
volatile boolean firstBeat = true;        // used to seed rate array so we startup with reasonable BPM
volatile boolean secondBeat = false;      // used to seed rate array so we startup with reasonable BPM

void setup()
{

 pinMode(Redled, OUTPUT); //This defines the pin to be an output
 pinMode(Greenled, OUTPUT);//This defines that the Green Led will be an output.
 pinMode(buzzer,OUTPUT);//This defines that the piezo pin will be an output.

  Serial.begin(115200);
  interruptSetup();                // sets up to read Pulse Sensor signal every 2mS
                                    //   analogReference(EXTERNAL);

}

//  Continuous and does not stop
void loop()
{

   serialOutput();

  if (QS == true) // A Heartbeat Was Found
    {
      // BPM and IBI have been Determined
      // Quantified Self "QS" true when arduino finds a heartbeat
      serialOutputWhenBeatHappens(); // A Beat Happened, Output that to serial.
      QS = false; // reset the Quantified Self flag for next time
    }
   if (BPM > 50){ //If the heart rate is more than 55 BPM(Beats Per Minute) then...

    digitalWrite(Redled, HIGH);//The Red Led will turn on
    digitalWrite(Greenled, LOW);//Green Led will turn off

   }
   else if(BPM < 50)//If the heart rate is below 55 BPM then...
   {
   digitalWrite(Redled, LOW);//The Red Led will stay off
   digitalWrite(Greenled, HIGH);//The Green Led will stay on
   tone(3, 500, 1000);

   }
  delay(20); //  take a breakx

  }

void interruptSetup()
{
  // Initializes Timer2 to throw an interrupt every 2mS.
  TCCR2A = 0x02;     // DISABLE PWM ON DIGITAL PINS 3 AND 11, AND GO INTO CTC MODE
  TCCR2B = 0x06;     // DON'T FORCE COMPARE, 256 PRESCALER
  OCR2A = 0X7C;      // SET THE TOP OF THE COUNT TO 124 FOR 500Hz SAMPLE RATE
  TIMSK2 = 0x02;     // ENABLE INTERRUPT ON MATCH BETWEEN TIMER2 AND OCR2A
  sei();             // MAKE SURE GLOBAL INTERRUPTS ARE ENABLED
}

void serialOutput()
{   // Decide How To Output Serial.
 if (serialVisual == true)
  {
     arduinoSerialMonitorVisual('-', Signal);   // goes to function that makes Serial Monitor Visualizer
  }
 else
  {
      sendDataToSerial('S', Signal);     // goes to sendDataToSerial function
   }
}

void serialOutputWhenBeatHappens()
{
 if (serialVisual == true) //  Code to Make the Serial Monitor Visualizer Work
   {
     Serial.print(" Heart-Beat Found ");  //ASCII Art Madness
     Serial.print("BPM: ");
     Serial.println(BPM);

     delay(300);

   }
 else
   {
     sendDataToSerial('B',BPM);   // send heart rate with a 'B' prefix
     sendDataToSerial('Q',IBI);   // send time between beats with a 'Q' prefix
   }
}

void arduinoSerialMonitorVisual(char symbol, int data )
{
  const int sensorMin = 0;      // sensor minimum, discovered through experiment
  const int sensorMax = 100;    // sensor maximum, discovered through experiment
  int sensorReading = data; // map the sensor range to a range of 12 options:
  int range = map(sensorReading, sensorMin, sensorMax, 0, 11);
  // do something different depending on the
  // range value:
}

void sendDataToSerial(char symbol, int data )
{
   Serial.print(symbol);
   Serial.println(data);
}

ISR(TIMER2_COMPA_vect) //triggered when Timer2 counts to 124
{
  cli();                                      // disable interrupts while we do this
  Signal = analogRead(pulsePin);              // read the Pulse Sensor
  sampleCounter += 2;                         // keep track of the time in mS with this variable
  int N = sampleCounter - lastBeatTime;       // monitor the time since the last beat to avoid noise
                                              //  find the peak and trough of the pulse wave
  if(Signal < thresh && N > (IBI/5)*3) // avoid dichrotic noise by waiting 3/5 of last IBI
    {
      if (Signal < T) // T is the trough
      {
        T = Signal; // keep track of lowest point in pulse wave
      }
    }

  if(Signal > thresh && Signal > P)
    {          // thresh condition helps avoid noise
      P = Signal;                             // P is the peak
    }                                        // keep track of highest point in pulse wave

  //  NOW IT'S TIME TO LOOK FOR THE HEART BEAT
  // signal surges up in value every time there is a pulse
  if (N > 250)
  {                                   // avoid high frequency noise
    if ( (Signal > thresh) && (Pulse == false) && (N > (IBI/5)*3) )
      {
        Pulse = true;                               // set the Pulse flag when we think there is a pulse

        IBI = sampleCounter - lastBeatTime;         // measure time between beats in mS
        lastBeatTime = sampleCounter;               // keep track of time for next pulse

        if(secondBeat)
        {                        // if this is the second beat, if secondBeat == TRUE
          secondBeat = false;                  // clear secondBeat flag
          for(int i=0; i<=9; i++) // seed the running total to get a realisitic BPM at startup
          {
            rate[i] = IBI;
          }
        }

        if(firstBeat) // if it's the first time we found a beat, if firstBeat == TRUE
        {
          firstBeat = false;                   // clear firstBeat flag
          secondBeat = true;                   // set the second beat flag
          sei();                               // enable interrupts again
          return;                              // IBI value is unreliable so discard it
        }
      // keep a running total of the last 10 IBI values
      word runningTotal = 0;                  // clear the runningTotal variable

      for(int i=0; i<=8; i++)
        {                // shift data in the rate array
          rate[i] = rate[i+1];                  // and drop the oldest IBI value
          runningTotal += rate[i];              // add up the 9 oldest IBI values
        }

      rate[9] = IBI;                          // add the latest IBI to the rate array
      runningTotal += rate[9];                // add the latest IBI to runningTotal
      runningTotal /= 10;                     // average the last 10 IBI values
      BPM = 60000/runningTotal;               // how many beats can fit into a minute? that's BPM!
      QS = true;                              // set Quantified Self flag
      // QS FLAG IS NOT CLEARED INSIDE THIS ISR
    }
  }

  if (Signal < thresh && Pulse == true)
    {   // when the values are going down, the beat is over
      Pulse = false;                         // reset the Pulse flag so we can do it again
      amp = P - T;                           // get amplitude of the pulse wave
      thresh = amp/2 + T;                    // set thresh at 50% of the amplitude
      P = thresh;                            // reset these for next time
      T = thresh;
    }

  if (N > 2500)
    {                           // if 2.5 seconds go by without a beat
      thresh = 512;                          // set thresh default
      P = 512;                               // set P default
      T = 512;                               // set T default
      lastBeatTime = sampleCounter;          // bring the lastBeatTime up to date
      firstBeat = true;                      // set these to avoid noise
      secondBeat = false;                    // when we get the heartbeat back
    }

  sei();                                   // enable interrupts when youre done!
}// end isr

```

This is the error code I get

```
Arduino: 1.8.10 (Windows 10), Board: "Arduino Uno"

Tone.cpp.o (symbol from plugin): In function `timer0_pin_port':

(.text+0x0): multiple definition of `__vector_7'

sketch\Heart_Beat_Sensor_Code.ino.cpp.o (symbol from plugin):(.text+0x0): first defined here

collect2.exe: error: ld returned 1 exit status

Multiple libraries were found for "PulseSensorPlayground.h"
 Used: C:\Users\amaan\Documents\Arduino\libraries\PulseSensor_Playground
exit status 1
Error compiling for board Arduino Uno.

This report would have more information with
"Show verbose output during compilation"
option enabled in File -> Preferences.

```

# Answer
Both the `tone()` command and the `PulseSensor_Playground` library use Timer 0's interrupt. That means there are two implementations of the ISR for that interrupt. However you can only have one implementation of a function or ISR, so it conflicts.

You will have to modify the `PulseSensor_Playground` library to use a different timer. There may be a way in the code already (some libraries implement such a thing) - if not then you'll have to rewrite the library to use another timer.
> 1 votes

---
Tags: sensors
---


# Question
Title: STM32 "Blue Pill" Serial.print freezes Serial Monitor
I am having difficulties when printing any type of variable using the Serial.print(ln) command.

The Serial Monitor becomes inactive after printing for approximately 7 - 15 times.

I currently have the STM32 Blue Pill Board, running Mac OS Mojave and Arduino IDE v 1.8.9

```
void setup() {
  Serial.begin(9600);
  pinMode(PC13, OUTPUT);

}

void loop() {
  float raw = analogRead(PA0);
  float voltage = (raw * 3.3) / 4096;
  Serial.println(voltage);
  delay(500);
}

```

# Answer
Have you made sure to modify the board before using it?

This page mentions at least one resistor that you have to replace for the USB to "work".

> The USB standard requires a 1.5 kΩ pullup resistor on D+, but this board is known to have a wrong value (R10 on the board). It ships with either a 10 kΩ resistor or a 4.7 kΩ resistor, but it should be replaced with a 1.5 kΩ resistor, or put an appropriate resistor value (e.g 1.8 kΩ) in between PA12 and 3.3V.
>
> It is also true that some PCs are tolerant of incorrect value so, before you change the resistance, you can try if it works in your case.

I have had issues with bluepill boards myself in the past, but never had an issue like yours after fixing the resistor. (before that, I couldn't even flash the bootloader)

Try printing other things with the board, and see if there's any pattern to it cutting out. e.g. a string over and over again, or the same float over and over again.

Try different baudrates, or even SoftwareSerial to another board.
> 1 votes

# Answer
Printing a float should work (at least with an Arduino), but to test if it cannot handle it correctly, I suggest you convert the float to a string (e.g., with the `C` function `ftoa`, and print the characters one by one or as a string.

Since this C function is not available on Arduino, use the function implementation of this article, credits to Martin Waller:

```
char *ftoa(char *buffer, double d, int precision) {

    long wholePart = (long) d;

    // Deposit the whole part of the number.

    itoa(wholePart,buffer,10);

    // Now work on the faction if we need one.

    if (precision > 0) {

        // We do, so locate the end of the string and insert
        // a decimal point.

        char *endOfString = buffer;
        while (*endOfString != '\0') endOfString++;
        *endOfString++ = '.';

        // Now work on the fraction, be sure to turn any negative
        // values positive.

        if (d < 0) {
            d *= -1;
            wholePart *= -1;
        }

        double fraction = d - wholePart;
        while (precision > 0) {

            // Multipleby ten and pull out the digit.

            fraction *= 10;
            wholePart = (long) fraction;
            *endOfString++ = '0' + wholePart;

            // Update the fraction and move on to the
            // next digit.

            fraction -= wholePart;
            precision--;
        }

        // Terminate the string.

        *endOfString = '\0';
    }

   return buffer;
}

```
> 0 votes

---
Tags: arduino-ide
---


# Question
Title: Motor does not rotate smoothly ( Even in High speed )
I am bhanuka and i am new to Stepper motors and to this library.

I am trying to control 4 NEMA 17 motors ( Different speeds in same time ) using 4 (four) DM320t stepper driver. Actually i want to move the robot ( Robot has omni wheels) to coordinates according to the Gcode. It seem like code is ok, but when i enter a G-code, motors start to rotate to correct direction but they don't give smooth rotation ( I can hear clicking sound , motor seems jumping from step to step and motor get hot too much ).

I think the problem for this case is motor miss some steps. here i have attach the code. Can someone help me to overcome this problem. Thank you.

```
#include <AccelStepper.h>
#include <math.h>

int Gval;
int Xval, Yval, Zval;
int Fval;
int Ival, Jval;
String Gvalstr, Xvalstr, Yvalstr, Zvalstr, Fvalstr, Ivalstr, Jvalstr;
char Key;
String code; // parameters of G code Translator, It will execute the code
String ab; // Para of G code translator, For come to Gcode function

AccelStepper w1(1, 2, 3); // pin 3 = step, pin 6 = direction
AccelStepper w2(1, 49, 51); // pin 4 = step, pin 7 = direction
AccelStepper w3(1, 5, 6); // pin 3 = step, pin 6 = direction
AccelStepper w4(1, 8, 9); // pin 4 = step, pin 7 = direction

int w1_enb = 4;
int w2_enb = 53;
int w3_enb = 7;
int w4_enb = 10;
char x ; // x cordinate
char y ; // x cordinate
char command; // case vari.
char com;

String inString = "";

void setup() {
  digitalWrite(w1_enb, HIGH);
  digitalWrite(w2_enb, HIGH);
  digitalWrite(w3_enb, HIGH);
  digitalWrite(w4_enb, HIGH);

  Serial.begin(9600);
  Serial.println("G code");

}

void loop() {
  Gvalstr = "";
  Xvalstr = "";
  Yvalstr = "";
  Zvalstr = "";
  Fvalstr = "";
  Ivalstr = "";
  Jvalstr = "";

  String code;
  if (Serial.available() > 0 ) {
    ab = Serial.readString();
    Gcode();
  }
  else {}

}

void Gcode () {
  code = ab;
  Serial.println("code is " + ab);
  //Serial.println(code);
  //String code = "G01 X1 Y1 F200 T01 M03 S500";
  int len = code.length();
  for (int i = 0; i < len; i++) {

    if (code[i] == 'G')Key = 'G';
    else if (code[i] == 'X')Key = 'X';
    else if (code[i] == 'Y')Key = 'Y';
    else if (code[i] == 'Z')Key = 'Z';
    else if (code[i] == 'F')Key = 'F';
    else if (code[i] == 'i')Key = 'i';
    else if (code[i] == 'j')Key = 'j';
    else if (isdigit(code[i]) || code[i] == '-') {
      if (Key == 'G') {
        Gvalstr += code[i];
      }
      else if (Key == 'X') {
        Xvalstr += code[i];
      }
      else if (Key == 'Y') {
        Yvalstr += code[i];
      }
      else if (Key == 'Z') {
        Zvalstr += code[i];
      }
      else if (Key == 'F') {
        Fvalstr += code[i];
      }
      else if (Key == 'i') {
        Ivalstr += code[i];
      }
      else if (Key == 'j') {
        Jvalstr += code[i];
      }

    }
    else
    {
      Key = '-1';
    }

  }

  Gval = Gvalstr.toInt();
  Xval = Xvalstr.toInt();
  Yval = Yvalstr.toInt();
  Fval = Fvalstr.toInt();

  Serial.println( Gval);
  Serial.println (Xval);
  Serial.println (Yval);
  Serial.println (Fval);

  switch (Gval) {

    case 0:
      motor_setup(Xval, Yval);
      //Serial.println("**********");
      break;
    case 1:
      motor_setup(Xval, Yval);
      //Serial.println("**-------");
      break;

    case 2:
      motor_setup(Xval, Yval);
      break;

    case 3:
      motor_setup(Xval, Yval);
      break;

    case 90:
      motor_setup(Xval, Yval);
      break;

    case 91:
      motor_setup(Xval, Yval);
      break;

    case 92:
      motor_setup(Xval, Yval);
      break;

  }
}

void motor_setup (int Xval , int Yval) {

  double Xprojection;
  double Yprojection;

  if (Yval == 0 ) {

    if (Xval > 0) {
      Xprojection = '1';
    }

    else if (Xval == 0) {
      Xprojection = 0;

    }

    else {

      Xprojection = -1;
    }
    Serial.println("Xprojection in if ");
    Serial.println(Xprojection);

    Yprojection = 0;

  }
  else {
    float alpha = Yval / Xval;
    Serial.println("CALCULATING");
    Serial.println(alpha);

    double atanval = atan(alpha);
    Xprojection = cos(atanval);
    Yprojection = sin(atanval);

    Serial.println("X_projection : ");
    Serial.println(Xprojection);

    Serial.println("Y_projection : ");
    Serial.println(Yprojection);
  }

  float W1, W2, W3, W4;  // Radial Velocity required to move to Position

  W1 = float ( -0.35 * Xprojection + 0.35 * Yprojection) ;
  W2 = float (-0.35 * Xprojection - 0.35 * Yprojection );
  W3 = float ( 0.35 * Xprojection - 0.35 * Yprojection );
  W4 = float (0.35 * Xprojection + 0.35 * Yprojection );

  Serial.println ("Velocity components ");
  Serial.println (W1);
  Serial.println (W2);
  Serial.println (W3);
  Serial.println (W4);
  Serial.println('\n');

  long c = 20;    // these values for testing
  long d = 20;
  long e = 20;
  long f = 20;

  w1.setMaxSpeed(2);
  w1.setAcceleration(12);
  w1.moveTo( Xval );

  w2.setMaxSpeed(2);
  w2.setAcceleration(12);
  w2.moveTo( Yval);

  w3.setMaxSpeed(2);
  w3.setAcceleration(12);
  w3.moveTo( -Xval);

  w4.setMaxSpeed(2);
  w4.setAcceleration(12);
  w4.moveTo( -Yval );

  while (w1.distanceToGo() != 0 || w2.distanceToGo() != 0 || w3.distanceToGo() != 0 || w4.distanceToGo() != 0) {
    w1.run();
    w2.run();
    w3.run();
    w4.run();

  }

  Serial.println("Executed");
  Serial.println("Next GCODE");
  Serial.flush();

}

```

# Answer
> 0 votes
The problem was the Supply Voltage. I have connected it to 24DC V. when i connect it to 12V problem was solved.

---
Tags: stepper, stepper-motor
---


# Question
Title: Arduino Nano Fried on Music Reactive Led Strip
I'm doing a project that involves an Arduino Nano, a sound detection microphone module and a RGB Led strip (individually adressable leds). I also bought an accumulator so I can connect everything straight to the outlet.

The problem is that on 12V this accumulator cannot power the led strip at all and when I connected it to the laptop the Nano micro USB fried after I did about 4 tests.

My question is why can't the accumulator power everything and why the Nano got fried from the laptop which should have even less power? Would an Arduino Mega solve the problem or is it something about the wiring? (the wiring was checked by someone with experience)

# Answer
> 1 votes
I assume you are powering the Nano through VIN or USB, and you are then powering the LED strip from the Nano's 5V pin.

* From the 12V battery the current flows through an LM1117 linear voltage regulator. Draw too much current (\>800mA) and it will overheat and either shut down (if it's a good one) or melt (if it's an inferior Chinese clone).
* From USB the current flows through an SS1P3L diode with a maximum rating of 1.5A. If you draw more than that you will blow the diode and the board will appear dead.

So basically you're drawing too much current.

The proper way of powering a setup like this is:

* USB connection to power the Arduino *only*
* 12V into a 5V switching ("buck") regulator rated for *at least* the maximum current the LED strip needs
* 5V switching regulator into the LED strip directly
* Connect the ground of the 5V to the ground of the Arduino

**or**

* 12V into a 5V switching ("buck") regulator rated for *at least* the maximum current the LED strip needs
* 5V switching regulator into the LED strip directly
* 5V switching regulator *also* to the 5V (and ground) pin of the Arduino to power the Arduino

**or**

As above but with a 5V power supply instead of the 12V and switching regulator

Note that it is important that your supply can provide you with *at least* as much current as the *peak* current your system will need. If that is a problem then you can split the LED strip into chunks and power each chunk separately from a lower current supply.

---
Tags: arduino-mega, arduino-nano, power, rgb-led, sound
---


# Question
Title: How many I2C lines does the Arduino Due have?
According to the Arduino pin Mapping

```
20  PB12    SDA 3   6
21  PB13    SCL 3   6
70  PA17    SDA1    3   6
71  PA18    SCL2    15  9

```

The first one seems pretty obvious, the second one though is confusing. They have different labels. I also do not see other SDA or SCL in the table. So is this a typo?

# Answer
According to the Wire library documentation https://forum.arduino.cc/index.php?topic=132130.0:

> The Arduino Due has two I2C / TWI interfaces SDA1 and SCL1 are near to the AREF pin and the additional one is on pins 20 and 21.

And the table:

Arduino Due: 20 (SDA), 21 (SCL), SDA1, SCL1

So it seems in your table SCL2 should be SCL1.
> 1 votes

---
Tags: i2c, arduino-due
---


# Question
Title: EthernetClient not initializing properly
I am trying to make a connection with the EthernetClient, but it always fails with code 0. I decided to write a small code just to test if the client ever becomes ready, and as I suspected it does not.

```
#include <SPI.h>
#include <Ethernet.h>

byte mac[] = {0x2A, 0x27, 0x55, 0x08, 0x1E, 0x6A};
IPAddress ip(172, 16, 48, 133);
EthernetClient client;

void setup() {
  Ethernet.init(10);
  Ethernet.begin(mac, ip);
  Serial.begin(9600);
  while (!Serial) {;}

  for (auto link = Ethernet.linkStatus(); link != LinkON; link = Ethernet.linkStatus()) {;}
  Serial.println("Link ON");

  while(!client){
    Serial.println("Client not ready");
    delay(1000);
  }

  Serial.println("Client ready!");
}

void loop() {}

```

If I try to run the code above, it gets stuck at the "Client not ready" loop, and I can't figure it out what I'm missing for it to work.

Obs.: I have already configured a web server with success with my shield, so I'm guessing the problem is not with it.

# Answer
An `EthernetClient` expects to connect to a remote socket. At no point do you instruct it to connect to a socket, so it never succeeds.

At some point before checking for a connection you need to initiate that connection:

```
// arduino.cc is 100.24.172.113
IPAddress server(100, 24, 172, 113);
client.connect(server, 80);

```

The `if (client)` operation relies on `sockindex` having been assigned a valid value, and that is only ever done either by `EthernetClient::connect()` or by being explicitly set by `EthernetServer::available()`.
> 0 votes

---
Tags: ethernet, ethernet-shield
---


# Question
Title: Where is the definition of system_adc_read() in the esp8266 Arduino code?
Where is the definition of `uint16 system_adc_read(void)` in the esp8266 Arduino code?

I can see it being declared in `Arduino/tools/sdk/include/user_interface.h`, however there seems to be no definition of this. `system_adc_read()` gets called in `analogRead()` in `Arduino/cores/esp8266/core_esp8266_wiring_analog.c`

I suspect `system_adc_read()` calls `system_adc_read_fast()` to read the ADC, but can't actually find it in the code! Could somebody please point me to this? I've been struggling for quite some time.

***Purpose:*** *To manipulate the system\_adc\_read() in ESP8266 to get higher ADC sampling rates. Right now ADC sampling rate is 10ksps. I want it to be more than 30-40ksps.*

# Answer
The "definition" of `uint16 system_adc_read(void)` is inside the compiled archive/object file `libmain.a` inside one of the `NONOSDK` folders which is located in `/tools/sdk/lib/` . The version is selected in `platform.txt`. For example in my platform.txt:

```
# default SDK for all boards
# (generic board overrides this variable)
build.sdk=NONOSDK22x_190703
#build.sdk=NONOSDK22x_191024
#build.sdk=NONOSDK22x_191105

```

Running the `xtensa-lx106-elf-objdump.exe -d` on this file I can find this section inside:

```
00000258 <system_adc_read>:
     258:   020c                    movi.n  a2, 0
     25a:   f0c112                  addi    a1, a1, -16
     25d:   0109                    s32i.n  a0, a1, 0
     25f:   fffc01                  l32r    a0, 250 <system_pp_recycle_rx_pkt+0x18>
     262:   0000c0                  callx0  a0
     265:   fff901                  l32r    a0, 24c <system_pp_recycle_rx_pkt+0x14>
     268:   f42020                  extui   a2, a2, 0, 16
     26b:   1b1207                  beq a2, a0, 28a <system_adc_read+0x32>
     26e:   b30c                    movi.n  a3, 11
     270:   902220                  addx2   a2, a2, a2
     273:   1122e0                  slli    a2, a2, 2
     276:   fff701                  l32r    a0, 254 <system_pp_recycle_rx_pkt+0x1c>
     279:   0000c0                  callx0  a0
     27c:   f42020                  extui   a2, a2, 0, 16
     27f:   00a402                  movi    a0, 0x400
     282:   013027                  bltu    a0, a2, 287 <system_adc_read+0x2f>
     285:   020d                    mov.n   a0, a2
     287:   f42000                  extui   a2, a0, 0, 16
     28a:   0108                    l32i.n  a0, a1, 0
     28c:   10c112                  addi    a1, a1, 16
     28f:   f00d                    ret.n
     291:   00                          .byte 00
     292:   00                          .byte 00
     293:   00                          .byte 00
     294:   ff ff 00 00
    ...

000002a0 <system_adc_read_fast>:
     2a0:   e0c112                  addi    a1, a1, -32
     2a3:   11c9                    s32i.n  a12, a1, 4
     2a5:   21d9                    s32i.n  a13, a1, 8
     2a7:   31e9                    s32i.n  a14, a1, 12
     2a9:   5129                    s32i.n  a2, a1, 20
     2ab:   41f9                    s32i.n  a15, a1, 16
     2ad:   0109                    s32i.n  a0, a1, 0
     2af:   03fd                    mov.n   a15, a3
     2b1:   fff901                  l32r    a0, 298 <system_adc_read+0x40>
     2b4:   0000c0                  callx0  a0
     2b7:   4fbc                    beqz.n  a15, 2ef <system_adc_read_fast+0x4f>
     2b9:   fff6e1                  l32r    a14, 294 <system_adc_read+0x3c>
     2bc:   0c0c                    movi.n  a12, 0
     2be:   51d8                    l32i.n  a13, a1, 20
     2c0:   90dcd0                  addx2   a13, a12, a13
     2c3:   001d32                  l16ui   a3, a13, 0
     2c6:   1a13e7                  beq a3, a14, 2e4 <system_adc_read_fast+0x44>
     2c9:   902330                  addx2   a2, a3, a3
     2cc:   1122e0                  slli    a2, a2, 2
     2cf:   b30c                    movi.n  a3, 11
     2d1:   fff201                  l32r    a0, 29c <system_adc_read+0x44>
     2d4:   0000c0                  callx0  a0
     2d7:   f44020                  extui   a4, a2, 0, 16
     2da:   00a402                  movi    a0, 0x400
     2dd:   003d                    mov.n   a3, a0
     2df:   013047                  bltu    a0, a4, 2e4 <system_adc_read_fast+0x44>
     2e2:   043d                    mov.n   a3, a4
     2e4:   005d32                  s16i    a3, a13, 0
     2e7:   cc1b                    addi.n  a12, a12, 1
     2e9:   f4c0c0                  extui   a12, a12, 0, 16
     2ec:   ce9fc7                  bne a15, a12, 2be <system_adc_read_fast+0x1e>
     2ef:   11c8                    l32i.n  a12, a1, 4
     2f1:   21d8                    l32i.n  a13, a1, 8
     2f3:   31e8                    l32i.n  a14, a1, 12
     2f5:   41f8                    l32i.n  a15, a1, 16
     2f7:   0108                    l32i.n  a0, a1, 0
     2f9:   20c112                  addi    a1, a1, 32
     2fc:   f00d                    ret.n
     2fe:   00                          .byte 00
     2ff:   00                          .byte 00
     300:   ff ff 00 00
    ...

```
> 2 votes

---
Tags: esp8266, adc
---


title: MD5 Password in Sketch

text:
# Question
Title: MD5 Password in Sketch
I'm playing with Over The Air (OTA) updates in my LoLin. I can make connections to my router and OTA updates seem to work well.

I'm uncomfortable storing my WiFi router SSID and password unencrypted in every sketch. Can I store an encrypted password instead for use in `WiFi.begin()`?

For example, Linux has wpa\_pasphrase, which generates a 32-byte number which is an encrypted version of the password which can safely be stored in plaintext configuration files.

# Answer
> 2 votes
> Can I store an MD5 password hash instead

No. MD5 is a "trapdoor" algorithm. It's one-way. You can make a hash from a password but you *cannot* make a password from a hash.

You could AES encrypt it, but you would need to have the AES key in your sketch to decrypt the password, which just moves the problem elsewhere.

Typically in a real-world situation you wouldn't have either the SSID or the password in the sketch. Instead you'd create a configuration system which would allow you to set (and of course change) both the SSID and password at runtime, and have the data stored somewhere (either EEPROM or in a file in SPIFFS, for example).

You might want to take a look at WiFiManager which automates that process for you.

# Answer
> 3 votes
I use Tzapu's WiFiManager https://github.com/tzapu/WiFiManager.

That starts your ESP as a WiFi access point (AP mode) which presents a web page at http://192.168.4.1 where you enter your WiFi SSID and password. It then stores the password and restarts WiFi as a station (STA mode).

On restart if the password is already stored then it just connects as a station.

If the SSID can't be found it runs the access point again.

# Answer
> 1 votes
I laud your intention and wish there were a good solution on the ESP8266 for what you're trying to do.

MD5 is a one-way hash function, so you won't be able to simply recover the original string to use in `WiFi.begin()`.

MD5 is also considered to be "cryptographically broken and unsuitable for further use" as of 2008. So if you're concerned about more than just a casual eavesdropping attack sniffing out your password, MD5 isn't considered good for any kind of security application these days.

You'd need to use some form of reversible encryption, but you'd still need to store the key somewhere. If you were using an ESP32, it has the capability of encrypting its flash storage, but the ESP8266 can't do that, so you'll always be vulnerable to someone recovering keys or passwords if they get sufficient access to the CPU.

# Answer
> 0 votes
While it *IS* possible to reverse a password hash, especially MD5 (https://md5decrypt.net/en/), it doesn't buy you anything in the way of security since everyone else can also reverse them.

If you happen to have a second LoLin, you could set it up as an Access Point and have the first device connect to it instead of having it connect to your router. Then you could relay the communication to a PC over USB.

Sure, it's a bit of a pain, but it at least means that you don't have to expose your router's password on a device that someone can pick up and walk off with.

---
Tags: esp8266, arduino-uno-wifi
---


# Question
Title: Maximum frequency that can be converted with Arduino Uno?
Arduino Uno Board use successive approach ADC of 12 bits and 16 MHz frequency clock. What is the maximum voice frequency can be converted using arduino uno board? I want the step by step solution with calculations.

# Answer
First of all, the ADC on the Uno is 10 bits, not 12.

The naive approach of having `analogRead()` in a tight loop can give you up to 8.9 kS/s (112 µs per sample), but you won't be able to do much else, as the CPU spends most of it's time just waiting for the ADC to do its job. If you configure the ADC manually, then you can set it into the so called “free running mode”. You then get about 9.6 kS/s (104 µs/S), but then the CPU is free to process one sample while the next one is being converted.

If you need to go faster, you can tweak the frequency of the internal ADC's clock. Then it's a compromise between speed and accuracy: the faster you go the less accurate. You may get rough but kind of usable samples at up to 77 kS/s (13 µs/S).

For a detailed comparison of the different clocking options, with speed and accuracy estimation, see the article ADC conversion on the Arduino (analogRead), by Nick Gammon.
> 2 votes

---
Tags: arduino-uno, adc, analog-sampling
---


# Question
Title: Is it permissible to use strlcpy to copy an array to itself?
**Task:** delete "\n" at the beginning of the array.

**Example:**

```
char s_msg[15] = "\nHello world!";

void setup()
{
  Serial.begin(115200);
  Serial.println("Load");
  // Search \n
  if(strstr(s_msg, "\n") != NULL) {
    Serial.println(s_msg);
    strlcpy(s_msg, &s_msg[1], sizeof(s_msg));
    Serial.println(s_msg);
  }
}

void loop() {}

```

**Description:** If the \ n character is present at the beginning of the message, then we copy the original character to the same character, but without \ n.

**Question:** is it ok to copy char to itself (s\_msg is the destination buffer and the source string at the same time)

# Answer
This manual page of `strlcpy()` is quite clear:

> If the `src` and `dst` strings overlap, the behavior is undefined.

This means you should avoid it, even if it works on some tests. The advice you got of just trying is *not* good advice. Use `memmove()` instead.
> 4 votes

---
Tags: programming, c
---