title: Variable updated in ISR is miscounting

text:
# Question
Title: Variable updated in ISR is miscounting
I'm using a timer to fire a interrupt in configurable time periods. In that ISR, a pin is toggled, and a `uint32_t` variable is incremented.

In the main program, a `while` loop waits until that variable has reached a certain threshold - to then disable the timer via its clock source selection.

```
while(stepcounter <= threshold) {
}
disablecounter();

```

Sometimes - depending on optimization level, whether I put a small delay in the while loop, etc., this check seems to fail - advancing to `disablecounter()` even though `stepcounter` has not reached `threshold`.

If I stack the `while` loop like this:

```
while(stepcounter <= threshold) {
}
while(stepcounter <= threshold) {
}
disablecounter();

```

it runs just fine. This also works:

```
while(stepcounter <= threshold) {
  while(stepcounter <= threshold) {
  }
}
disablecounter();

```

I'm assuming there's some odd behaviour when comparing rapidly changing 32-bit numbers against a threshold. This issue also occurs when using a `uint16_t` for `stepcounter`, but after a higher number of cycles.

For analysis, I'm simply running this loop over and over again; setting `stepcounter` back to `0` and restarting the timer. With `uint32_t`, it usually fails after the 5th or so loop. For `uint16_t`, it fails after around 25 loops.

Using a `tempstepcounter` like this also seems to work, but only when comparing against both counters at the same time:

```
while(tempstepcounter <= threshold || stepcounter <= threshold) {
  tempstepcounter = stepcounter;
}
disablecounter();

```

Any ideas on this? It this because 32-bit numbers take longer to read from the registers than the time from ISR to ISR? ISR frequency should be around 32 kHz during this.

ISR code:

```
ISR(TIMER1_COMPA_vect) {
  PORTF ^= (1 << PORTF0));
  stepcounter++;
}

```

# Answer
You need to declare it volatile in both places *and* shut off interrupts while reading it. The mainline has to read it byte-by-byte, and an interrupt could otherwise occur between any two byte-reads, rendering the result of the 4-byte read as garbage.

'volatile' informs the compiler that the variable might not contain what it did last time (which the compiler might otherwise expect if the code being compiled doesn't change it. Turning off the interrupts protects the variable being changed while it's being read.

An even better way to protect the reads than turning off interrupts, is for the ISR to update the counter, then set a single-byte flag to indicate that there's a new count. The mainline would monitor that flag and read the counter only when the flag gets set, then clear the flag. This can work as long as the mainline checks the flag frequently enough that it will never not notice the flag until just before the next update by the ISR. But if you can keep to that constraint, this is a better idea than turning off interrupts.

If too many sub-tasks resort to turning off interrupts, it can have a negative effect on response time or even cause missed interrupts in some cases. This is less likely to be a problem for the relatively simple programs most of us write and run, most of the time. But when you get to tracking and controlling more complex processes and make heavier use of the interrupt system, bad habits have a way of coming back to bite you.
> 2 votes

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


title: Attiny85 Watchdog fires only once

text:
# Question
Title: Attiny85 Watchdog fires only once
I build something like a flashlamp with different modi. From the hardware site it's quite simmilar to the Nanjg105c. There is a Attiny85 which generates a PWM signal to an AMC7135.

I have one push button, if I click it the Attiny go to sleep, if I hold the button the Attiny changes his mode.  For checking the battery voltage I use the watchdog timer to make the ADC conversion every 8sec.

```
    #include "OneButton.h"
#include <avr/sleep.h>               // Sleep Modes
#include <avr/power.h>              // Power management
#include <avr/wdt.h>              // Watchdog Timer
#include <util/delay.h>

#define mid 4000                // BAttery Level Mid
#define low 3200                // Battery Level low, flash and start dimming the Led
#define crit 2600               // Battery Level critical, shut down

const byte LEDr = 1;              // pin 1
const byte LEDw = 4;              // pin 4
const byte ModeNr = 3;
volatile bool WDR_flag = false;
bool PWR_flag = false;

OneButton button1(2, true);
int count = 1;
int flag = 0;
long Vcc;
int PWMr = 255;
int PWMw_l = 50;
int PWMw_h = 255;

ISR(PCINT0_vect)
{
    // do something interesting here
}

ISR(WDT_vect){
  WDR_flag=true;
 }

void setup()
{
    pinMode(3, OUTPUT);
    pinMode(LEDr, OUTPUT);            // turn the LED on (HIGH is the voltage level)
    pinMode(LEDw, OUTPUT);
    digitalWrite(LEDr, HIGH);           // turn the LED on (HIGH is the voltage level)
    digitalWrite(LEDw, HIGH);
    delay(1000);
    button1.attachClick(sleep);
    button1.attachLongPressStart(changeMode);
    WDT_on();
}

void loop()
{
  uint8_t i = 0;
    button1.tick();               // keep watching the push buttons:
  if(WDR_flag == true){           // do every 8s
    WDR_flag = false;           //reset WDT Flag
    digitalWrite(3, HIGH);      //debug with third LED
    delay(250);
    digitalWrite(3, LOW);
    WDT_off();
    //ADC_on();
    /*Vcc = readVcc();            //read Battery voltage
    if(Vcc < low && count == 3){
      if(PWMw_h <= PWMw_l){       //change Mode to low when PWM output is smaler then low PWM
        count = 2;
      }else
    {
    i = 0;
        while (i++<3 && PWR_flag == false) {         //flash 3 times the red LED befor dimm the white LED
          analogWrite(LEDr, PWMr);
          _delay_ms(500);
          digitalWrite(LEDr, LOW);
          _delay_ms(250);
      PWR_flag = true;
        }
      PWMw_h = PWMw_h / 2;        //halve the PWM output of the white LED
      }
      if(Vcc <= crit){          //go to sleep when Battery is empty
        sleep();
      }
    }
    if(Vcc < low && count == 1){
      i = 0;
      while (i++<3) {
        digitalWrite(LEDr, LOW);
        _delay_ms(250);
        analogWrite(LEDr, PWMr);
        _delay_ms(500);
        }
      PWMr = PWMr / 2;
      if(Vcc <= crit){
        sleep();
      }
    }*/
    //ADC_off();                //save power
    WDT_on;                 //start watchdog again

  }
  switch (count) {
    case 1:                 //Mode red LED
    analogWrite(LEDr, PWMr);
    digitalWrite(LEDw, LOW);
    break;
  case 2:                   //low Mode white LED
    digitalWrite(LEDr, LOW);
    analogWrite(LEDw, PWMw_l);
    break;
  case 3:                   //high Mode white LED
    digitalWrite(LEDr, LOW);
    analogWrite(LEDw, PWMw_h);
    break;
  }
}

void sleep()                  // This function will be called when the button1 was pressed 1 time
{
    digitalWrite(LEDr, LOW);
    digitalWrite(LEDw, LOW);
    //prepare sleep
    WDT_off();
    GIFR |= bit(PCIF);              // clear any outstanding interrupts
    GIMSK |= _BV(PCIE);             // Enable Pin Change Interrupts
    PCMSK |= _BV(PCINT2);             // Use PB2 as interrupt pin
    ADC_off();
    set_sleep_mode(SLEEP_MODE_PWR_DOWN);    // replaces above statement

    sleep_enable();               // Sets the Sleep Enable bit in the MCUCR Register (SE BIT)
    sei();                    // Enable interrupts
    sleep_cpu();                // sleep

    cli();                    // Disable interrupts
    PCMSK &= ~_BV(PCINT2);            // Turn off PB2 as interrupt pin
    sleep_disable();              // Clear SE bit
    WDT_on();

    flag = 1;                 //set flag, uc was in sleepmode before
}

void changeMode()               // This function will be called once, during pressed for a long time.
{
    if (flag == 1) {
        flag = 0;
    }
    else {
        if (count < ModeNr) {
            count++;
        }
        else {
            count = 1;
        }
    }
}

void WDT_on() {
  // Setup watchdog timer to only interrupt, not reset
  cli();                    // Disable interrupts
  wdt_reset();                // Reset the WDT
  WDTCR |= (1 << WDCE) | (1 << WDE);       // Start timed sequence
  WDTCR = (1 << WDIE) | (1 << WDP3) | (1<<WDP0);      // Watchdog cycle = 8 s
  //WDTCR = (1 << WDIE);             // Watchdog Interrupt enable
  sei();                    // Enable interrupts
}

void WDT_off(){
  cli();                    // Disable interrupts
  wdt_reset();                // Reset the WDT
  MCUSR &= ~(1<<WDRF);            // Clear Watchdog reset flag
  WDTCR |= (1<<WDCE) | (1<<WDE);        // Start timed sequence
  WDTCR = 0x00;               // Disable WDT
  sei();                    // Enable interrupts
}

void ADC_on() {
  ADCSRA = (1 << ADEN );            // ADC power on
}

void ADC_off() {
  ADCSRA &= ~(1<<7);              //ADC off
}

long readVcc() {
  // Read 1.1V reference against AVcc
  // set the reference to Vcc and the measurement to the internal 1.1V reference

  ADMUX = _BV(MUX3) | _BV(MUX2);
  delay(2);                  // Wait for Vref to settle
  ADCSRA |= _BV(ADSC);              // Start conversion
  while (bit_is_set(ADCSRA,ADSC));        // measuring

  uint8_t low_adc  = ADCL;              // must read ADCL first - it then locks ADCH
  uint8_t high_adc = ADCH;              // unlocks both

  long result = (high_adc<<8) | low_adc;

  result = 1126400L / result;           // Calculate Vcc (in mV); 1126400 = 1.1*1024*1000
  int x = 0;
  /*while (x++<2) {         //debug with third LED
          digitalWrite(3, HIGH);
          _delay_ms(500);
          digitalWrite(3, LOW);
          _delay_ms(250);
        } */
  return result;                // Vcc in millivolts
}

```

my problem is that the watchdog fires only once. after putting the attiny to sleep the watchdog fires also only once.

I think the problem is in the WDT\_off() function...

# Answer
> 2 votes
The line below lacks parens `()` to make it a function call; as it stands, it's not actually calling `WDT_on`.

```
WDT_on;                 //start watchdog again

```

should be:

```
WDT_on();                 //start watchdog again

```

---
Tags: interrupt, attiny, watchdog
---


title: I2C Wire.onRequest not detected

text:
# Question
Title: I2C Wire.onRequest not detected
I want to know why `Wire.onRequest` can not detect below massage and what I can do to detect it.(I am not able to change I2C massage)

I was able to read this part of the massage with `wire.onReceive`:

But I can not read this massage at all, which is requesting:

```
#include <Wire.h>
byte val = 170;
int sendv;

char c;

byte dataArray[16];

void setup() {
  Wire.begin(0x77);                // join i2c bus with address #8
  Wire.onReceive(receiveEvent); // register event
  Wire.onRequest(requestEvent); // register event
  Serial.begin(9600);           // start serial for output
}

void loop() { }

void receiveEvent(int howMany) {
  Serial.println(howMany);

  if (howMany >= 2) {
    for (int i = 0 ; i < howMany; i++) {
      dataArray[i] =  Wire.read();
      Serial.println(dataArray[i], HEX);
    }

  } else {
    c =  Wire.read();
    Serial.println(c, HEX);
  }
}

void requestEvent() {
  Serial.println("REqEVENT");
}

```

# Answer
> 1 votes
I was able to solve the issue with by adding twi\_stop(); to twi.c

base on this website enter link description here

---
Tags: i2c, wire-library
---


# Question
Title: Which sensors to choose to detect movement direction
So I'm planning to build a sort of light switch for my Philips Hue bulbs with an Arduino. This project will be mounted on a shelf next to my door to the room, parallel to the walking direction. In order to detect the movement direction to either turn on or off the lights when a person is entering or leaving the room, I need one or two sensors. I've tried HC sr04 before but got inaccurate results which resulted in random changes of the lightstate.

So what sensors will be best for my application? I was thinking about the Sharp IR sensors (i.e. Sharp GP2Y0A60SZLF) but I'm not sure about any possible interference that comes with it when I mount to of these right next to each other. Any ideas?

Thanks in advance!

# Answer
The PIR sensors can work in your case. They are passive and detect only moving objects that emit IR radiation. So anything that's hotter than background like people, cats, dogs but not doors.

The raw sensor looks like this:

But it's usually available as a part of an IC that includes a plastic lens that focuses IR rays from broader area on the sensor.

Remove that lens (or not) and add something made of cardboard to limit the area that sensor sees and you have a directional sensor that detects moving hot things.

Technically you can completely hack the raw sensor and get info if the hot object is moving left or right. Read this article and look at the sensor response graph.
> 1 votes

# Answer
1. I guess you want to use 2 IR sensors with a little distance, so that you can check the direction by checking, which one detected an object first. You surely can do this with the mentioned sensor. To avoid interference, you can measure by one one, deactivating the other over it's enable pin during that time. It should be fast enough, so that you can do this sufficiently.
2. I would say using a distance sensor is overkill here. For checking, if someone comes in or out, you don't need distance information. Just 2 light barriers would be sufficient. For example a little laser pointer (could also be IR), a little mirror at the other side and a fitting photodiode. I think there are ready made modules to buy. Their output would only be digital, not analog.
> 0 votes

---
Tags: sensors
---


# Question
Title: I want to print onto serial monitor when it's detected the value change
This code is measuring distance from object by using the Ultrasonic Sensor and print onto serial monitor.

However, serial monitor constantly output values. I want to print only one time if detected value not change. and serial monitor print again only when detected value change. and The above condition keeps repeating.

How can i change the code?

```
int distance ;
int trig = 3;
int echo = 2;

void setup()
{
  Serial.begin(9600);
  pinMode(trig, OUTPUT);
  pinMode(echo, INPUT);
}

void loop()
{
  digitalWrite(trig, HIGH);
  delayMicroseconds(10);
  digitalWrite(trig, LOW);
  distance = pulseIn(echo, HIGH) / 58;
  Serial.println(distance);
}

```

# Answer
```
int distance;
int last_distance; // <== To hold the value from the previous pass
int trig = 3;
int echo = 2;

void setup()
{
  Serial.begin(9600);
  pinMode(trig, OUTPUT);
  pinMode(echo, INPUT);
}

void loop()
{
  digitalWrite(trig, HIGH);
  delayMicroseconds(10);
  digitalWrite(trig, LOW);
  distance = pulseIn(echo, HIGH) / 58;
  if (distance != last_distance) {  // <== Check if new distance is different
    Serial.println(distance);       //     Print only if the values are different
  }
  last_distance = distance;         // <== Store this loop's distance for next round
}

```
> 1 votes

---
Tags: arduino-uno, serial, sensors
---


# Question
Title: How do I repurpose Arduino's reset button
Is there a way to repurpose the reset button for the code, like an on-board button? I don't need it to reset, but it would be useful to make it run through a list of RGB LED cycles.

# Answer
If you just want the reset button to change the program mode, the simplest thing would be to let the button reset the Arduino and switch modes each time your program restarts. Then you do not need to change the fuses or get a high voltage programmer. The code would look like this:

```
void setup()
{
    // At startup, switch to the next mode.
    if (++mode >= NUMBER_OF_MODES) mode = 0;

    // etc...
}

```

There is just a small issue here: when the program starts, all the global variables (like `mode` above) are supposed to be initialized by the C runtime. This can be avoided by using a non-standard feature of gcc: if you request the variable to be stored in the special `.noinit` section, then it will not be initialized. Here is the program I used to test this idea:

```
const unsigned int NUMBER_OF_MODES = 5;

__attribute__((section(".noinit"))) unsigned int mode;

void setup()
{
    // At startup, switch to the next mode.
    if (++mode >= NUMBER_OF_MODES) mode = 0;

    Serial.begin(9600);
    Serial.print("Current mode: ");
    Serial.println(mode);
}

void loop() {}

```

Now, each time I press the reset button, it goes to the next mode among (0, 1, 2, 3, 4). The main drawback compared to using a regular input is the delay added by the bootloader, which is slightly more than one second.

A word about the cold boot initialization: the RAM is not initialized by the hardware and contains essentially random bits. This means you cannot count on `mode` having initially a valid value. This is why:

* I am testing for `++mode >= NUMBER_OF_MODES` rather than `++mode == NUMBER_OF_MODES`, as the initial mode could be way larger than `NUMBER_OF_MODES`
* `mode` is an unsigned integer, otherwise I would need to also test for it being negative.
> 9 votes

# Answer
Reset button is connected to the reset pin of Atmega328P-PU. So, when you press that button, the reset pin gets a LOW, which resets the chip!

Here is the thing, yes, you may disable the reset pin to use it as general I/O. However, if you disable it, you will not be able to reprogram your Arduino anymore! You'll effectively brick your Arduino...

By the way, yes you do need it to reset. When you program your arduino, the IDE sends a reset command from your PC via USB to reset your Arduino. When Arduino is resetted, bootloader looks for an incoming sketch, which is provided by the IDE and so on....
> 2 votes

# Answer
As noted in other answers, if you re-purpose the reset pin, PC6, by programming the RSTDISBL fuse, then some of the usual methods of loading a program into flash memory are made unavailable. Specifically, the usual serial-port programming using Arduino's Optiboot depends on the chip resetting upon demand. So does ISP programming, as done for example using a USBasp or similar device.

However, parallel programming remains available. This requires an STK500 or similar, or can be simulated using another Arduino.

Here are a couple of references from Atmel's doc8271 datasheet for ATmega48A/PA/88A/PA/168A/PA/328/P:

> **§14.3.2 Alternate Functions of Port C**
> “When the RSTDISBL Fuse is programmed, this pin \[PC6\] functions as a normal I/O pin, and the part will have to rely on Power-on Reset and Brown-out Reset as its reset sources. ...”
>
> **§28.6 Parallel Programming Parameters, Pin Mapping, and Commands**
> (Describes Parallel Programming wiring and protocol)

As it can be inconvenient having to hook up a parallel programmer to load new programs, instead of programming the RSTDISBL fuse you could modify the hardware. You would cut the trace from the reset switch close to the switch (for example, lightly touch the trace with a fast-spinning 1-mm drill bit, using a small Dremel or drillpress), then run a fine jumper wire from the switch or its trace to an input pin.

This method leaves all the other reset-circuit stuff (pullup resistor to 5V, capacitor to DTR) in place so that ISP programming would work without change.
> 1 votes

# Answer
I concur with everything Maximus has said.

It is possible - you can change the reset pin to be a normal I/O pin.

To do so you will need to program one of the ATmega328P's fuse bits. For that you will need an ISP programmer like the AVRISPmkII or Atmel ICE. You will also need a program such as Atmel Studio or AVRdude.

The reset disable fuse is part of the high byte fuses. First you will need to calculate high fuse. I use eleccelerator Fusecalc for this

Based on my boards.txt file, the default for the high fuse on the Arduino Uno is DE. Adding the reset disable fuse makes it 5E.

Program the fuse using Atmel Studio or AVRdude using your ISP programmer.

Complete Fusecalc settings
> 0 votes

# Answer
The other answers weren't working for me (on an ATmega168), but I found this solution:

```
const unsigned int NUMBER_OF_MODES = 5;
int * mode;

void setup() {
    mode = (int *) malloc (sizeof (int));

    // At startup, switch to the next mode.
    if (++(*mode) >= NUMBER_OF_MODES) (*mode) = 0;

    Serial.begin(9600);
    Serial.print("Current mode: ");
    Serial.println((*mode));
}

```

output:

```
Current mode: 0
Current mode: 1
Current mode: 2
Current mode: 3
Current mode: 4
Current mode: 0

```
> 0 votes

---
Tags: button, reset
---


title: Dice is not showing the correct numbers

text:
# Question
Title: Dice is not showing the correct numbers
I've made a dice roller (to make it easier to roll the dice) using an Arduino UNO and an LCD keypad shield but I can't get the correct numbers (1, 6 (7)) to show up, I've tried using int, float and everything in between. the buttons on the shield are connected to A0, can someone help me please?

```
#include <LiquidCrystal.h>
// select the pins used on the LCD panel
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);

#include "DFRkeypad.h"
String line2 = "Press Select to roll"; // Scrolling line

// just some reference flags
//int stringStart, stringStop = 0;
//int scrollCursor = screenWidth;

// define some values used by the panel and buttons
int lcd_key     = 0;
int adc_key_in  = 0;
#define btnRIGHT  0
#define btnUP     1
#define btnDOWN   2
#define btnLEFT   3
#define btnSELECT 4
#define btnNONE   5

// read the buttons
int read_LCD_buttons()
{
  adc_key_in = analogRead(0);      // read the value from the sensor

  // For V1.0 comment the other threshold and use the one below:

  if (adc_key_in > 1000) return btnNONE; // We make this the 1st option
  for speed reasons since it will be the most likely result
  // For V1.1 us this threshold
  if (adc_key_in < 50)   return btnRIGHT;
  if (adc_key_in < 195)  return btnUP;
  if (adc_key_in < 380)  return btnDOWN;
  if (adc_key_in < 555)  return btnLEFT;
  if (adc_key_in < 790)  return btnSELECT;

  return btnNONE;  // when all others fail, return this...
}

void setup() {
  randomSeed(analogRead(1));
  lcd.begin(16, 2);              // start the library
  lcd.setCursor(3, 0);
  lcd.print ("Catan Dice");
  lcd.setCursor(0, 1);

  // while(line2)
  //
  // lcd.print(line2);
  // break;
}

void loop() {

  //Dice
  byte DiceOne = random(1, 7);
  byte DiceTwo = random(1, 7);

  //local varables
  int buttonState = read_LCD_buttons(); // read the button pad
  int lastButtonState = btnNONE; // previous state of the button

  // the following variables are unsigned longs because the time, measured in
  // milliseconds, will quickly become a bigger number than can be stored in an int.
  unsigned long lastDebounceTime = 0;  // the last time the output pin was toggled
  unsigned long debounceDelay = 50;    // the debounce time; increase if the output flickers

  switch (buttonState)
  {
    case btnSELECT:
      lcd.clear();
      //Row, Colum
      lcd.setCursor (0, 4);
      lcd.print(DiceOne);
      lcd.setCursor (1, 4);
      lcd.print(DiceTwo);
      break;
  }

  DELAY(100)

  // read the state of the switch into a local variable:
  int reading = digitalRead(buttonState);

  // check to see if you just pressed the button
  // (i.e. the input went from LOW to HIGH), and you've waited long enough
  // since the last press to ignore any noise:

  // If the switch changed, due to noise or pressing:
  if (reading != lastButtonState) {
    // reset the debouncing timer
    lastDebounceTime = millis();
  }

  if ((millis() - lastDebounceTime) > debounceDelay) {
    // whatever the reading is at, it's been there for longer than the
    debounce
    // delay, so take it as the actual current state:

    // if the button state has changed:
    if (reading != buttonState) {
      buttonState = reading;
    }
  }

```

UPDATE, i got it working now

# Answer
> 2 votes
You are calling setCursor() with:

```
//Row, Colum
lcd.setCursor (0, 4);
lcd.print(DiceOne);
lcd.setCursor (1, 4);
lcd.print(DiceTwo);

```

While your comment notes the order is `Row`, `Column`, there appear to be several LiquidCrystal libraries floating about, some of which use `Column`, `Row` order in the `SetCursor()` function. The official Arduino library source indicates the `col`, `row` order.

You are writing both values on row 4 (even though that doesn't exist on your display), and in columns 0 and 1, thus you are correctly computing the Dice values, but they are being written with no gap between.

# Answer
> 1 votes
It seems that your issue is probably connected with LCD timing. Sending data to LCD requires a precise timings, and the onboard chip of the LCD module very much like a few milliseconds of time to finish processing the data sent, instead you pass the entire clear and draw command each loop cycle.

I used the default Tinkercad LCD display example. This code works fine:

```
#include <LiquidCrystal.h>

LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

void setup() {
  randomSeed(analogRead(1));
  lcd.begin(16, 2);
  lcd.setCursor(3, 0);
  lcd.print ("Catan Dice");
  lcd.setCursor(0, 1);
}

void loop() {
  byte DiceOne = random(1, 7);
  byte DiceTwo = random(1, 7);

  lcd.clear();
  lcd.setCursor (0, 4);
  lcd.print(DiceOne);
  lcd.setCursor (1, 4);
  lcd.print(DiceTwo);
  delay(100);
}

```

but as soon as I remove the `delay(100)`

```
void loop() {
  byte DiceOne = random(1, 7);
  byte DiceTwo = random(1, 7);

  lcd.clear();
  lcd.setCursor (0, 4);
  lcd.print(DiceOne);
  lcd.setCursor (1, 4);
  lcd.print(DiceTwo);
  //delay(100);
}

```

Weird things start to show on the LCD.

Try rewriting your code that the commands are sent to LCD only once per button press.

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


title: mBlock update firmware

text:
# Question
Title: mBlock update firmware
Total Arduino newbie here. I was playing with mBlocks, with the Arduino Uno extension enabled. That extension offers you to "update firmware" which I accidentally did. What exactly is this firmware? Is it just a compiled sketch or does it alter stuff like bootloader or reside permanently in the memory?

# Answer
> 0 votes
Usually by Firmware we understand "a program that was prepared by company that produced the hardware and that is necessary for that hardware to work correctly". I suppose that developers of mBlock are smart enough not to allow people to "brick" their Arduino's. I suspect that ether you updated your bootloader (it's also a firmware) to latest version or simply nothing happened. In both cases your device should be operational. Burning a bootloader onto an Arduino is not as hard as it seems so even if you broke something you should be able to fix it.

---
Tags: arduino-uno
---


title: How to manage button state

text:
# Question
Title: How to manage button state
Extreme Newbie here ...I am using an Arduino Uno and a PCA9685 16 Ch. Driver board to control servos using a push button and LED feedback. When I pust the button, the servo move but when I release the button, the servo move back to it original position. What I would like to have happen is that when I push the button once, the servo moves and holds its position. When I push the button again, return to its starting position. Thanks in advance for the assistance.

Here is the sketch:

```
#include <Wire.h>
#include <Adafruit_PWMServoDriver.h>

Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver();

int buttonPin0 = 2;   // Can add as many buttons as needed
int ledPin0C = 3;     // C designates Closed position of turnout
int ledPin0T = 4;     // T designates Thrown position of turnout
int buttonState0 = 0;

int buttonPin1 = 5;
int ledPin1C = 6;
int ledPin1T = 7;
int buttonState1 = 0;

void setup() {
    Serial.begin(9600);
    Serial.println("pca9685_TurnoutFinal!");
    pwm.begin();
    pwm.setPWMFreq(60);
    delay(30);

    pinMode(ledPin0C, OUTPUT);
    pinMode(ledPin0T, OUTPUT);
    pinMode(buttonPin0, INPUT);
    pinMode(ledPin1C, OUTPUT);
    pinMode(ledPin1T, OUTPUT);
    pinMode(buttonPin1, INPUT);
}

void loop() {
    ///////////
    buttonState0 = digitalRead(buttonPin0);
    if (buttonState0 == HIGH) {
        pwm.setPWM(0, 0, 370);
        digitalWrite(ledPin0T, LOW);
        digitalWrite(ledPin0C, HIGH);
    }
    else {
        pwm.setPWM(0, 0, 285);
        digitalWrite(ledPin0C, LOW);
        digitalWrite(ledPin0T, HIGH);
    }
    //////////
    buttonState1 = digitalRead(buttonPin1);
    if (buttonState1 == HIGH) {
        pwm.setPWM(1, 0, 370);
        digitalWrite(ledPin1T, LOW);
        digitalWrite(ledPin1C, HIGH);
    }
    else  {
        pwm.setPWM(1, 0, 285);
        digitalWrite(ledPin1C, LOW);
        digitalWrite(ledPin1T, HIGH);
    }
    //////////
}

```

# Answer
The code in loop is always running so when you release the button, the code sees this as digitalRead(btn) = HIGH.

You need a state variable to know where the motor is currently. Something like this:

```
boolean state = false;
int oldButton = HIGH;

void loop() {
    delay(20); // enough to debounce very most buttons

    int newButton = digitalRead(buttonPin0);
    if (oldButton == HIGH && newButton == LOW) { // only when button changes from "released" to "pressed"
        state = !state;

        // tell the servo where to go
        if (state) {
            pwm.setPWM(0, 0, 370);
        } else {
            pwm.setPWM(0, 0, 285);
        }
    }
    oldButton = newButton;
}

```
> 0 votes

---
Tags: servo
---


# Question
Title: Can you connect BH1790GLC and TMP117 sensors to an Arduino board?
I would like to use those two components for an upcoming project :

I especially like the fact that they’re so tiny.

Could I connect them directly to an Arduino board or some other well-known microcontroller ?

# Answer
> 1 votes
Yes, the sensors will work with microcontroller(s). What you look for is the **interface** they use. In this case it is **I2C** interface. Be careful thou: You have to check voltage levels your microcontroller works with and selected sensor voltage level. Some of the Arduino works with 5V levels and some sensors may accept max of 3.3V or 4.5V on I2C pins. This is why you would need either:

* Choose 3V powered microcontroller
* Use 5V powered microcontroller (like Arduino Uno) and voltage level converter

Also worth to note that these two sensors would need some additional circuitry to work with your microcontroller. Before any commitment I would try to find a development board (a board with mentioned circuitry with easy to acces pins for providing necessary signals/voltages/ground/etc).
Good luck!

---
Tags: sensors, communication, temperature-sensor
---


# Question
Title: How to use more than 2 I2S microphones on MKR Zero?
I am trying to build a portable device that can record from at least 3 microphones. I had a look and saw I2S is good for audio so I bought an Arduino MKR Zero to read them with. I was wondering how to record from multiple microphones on the I2S bus at once. The only thing that I have been able to do is record stereo from two mics but I need the microphone readings to be mono. I am using the Adafruit I2S MEMS Microphone SPH0645LM4H.

# Answer
> 1 votes
By definition, the I2S bus only allows up to 2 channels to be transmitted at the same time. Here is a quote from the Details section of the Wikipedia's I2S page:

> The word select clock lets the device know whether channel 0 or channel 1 is currently being sent, because I²S allows two channels to be sent on the same data line.

This is further illustrated in Figure 8 / Page 6 of the Knowles SPH0645LM4H data specifications. In this figure we see where 2 SPH0645LM4H microphones are configured (ground or Vcc to the SEL pin 2) such that they can be multiplexed onto the I2S bus by the I2S bus master.

---
Tags: sound, mkr1000
---


# Question
Title: How fast is flash reading compared to SRAM?
I'm working on a project that will eventually scale to 864 LEDs on WS2815 LED strips (three rows of 288 LEDs). I'm currently running it on an Arduino Uno with a single test strip of 144 LEDs.

FastLED stores its data in 3-byte structs, so I obviously cannot simply hold all of the data in SRAM and work with it directly (at least not without upgrading to a controller with more memory). I'm going to use a Raspberry Pi to send the Arduino data, one section at a time. To *further* save memory, I want to implement an RGB color lookup table in flash, then instead of

```
CRGB pixels[PIXEL_COUNT];

```

taking up over 2KiB of memory 800+ values, or

```
CRGB pixels[PIXEL_BUFFER_COUNT];

```

with a buffer of 288 RGB values consuming most of my working memory (864 bytes), I would have

```
CRGB *pixels[PIXEL_BUFFER_COUNT];

```

Where each pointer would reference a location in a `PROGMEM` 256-entry table of `CRGB` values. This is a more manageable 576 bytes in SRAM.

**I realize FastLED does not work this way**. There's a lot of work ahead of me if I do this, but before I get started, my question:

---

Will I run into issues with reading the actual data from flash memory while sending to the LED strips? As currently implemented in FastLED, RGB data is in SRAM, but each pointer dereference will require reading from flash. Is the subsequent delay enough that it will cause an issue with sending data to the strips?

# Answer
On an Arduino Uno, or other AVR-based Arduino, reading a byte from RAM takes 2 CPU cycles. Reading it from flash takes 3 cycles. So flash vs. RAM is not such a high overhead. However, if you store a LUT in flash, and the color indexes in RAM, then each pixel would require:

* 2 cycles for reading the color index from RAM
* 3 × 3 cycles for reading the RGB values from flash.

That's a total of 11 cycles, vs. 6 cycles it would take to read the RGB values from RAM, as is done in the stock FastLED library.

It sounds bad, but it could be that the precise timing is not such a big issue. I don't know the WS2815, but if they are similar to the WS2812, then you don't need to be anywhere as precise with the timings as the datasheet suggests. C.f. the blog post NeoPixels Revealed: How to (not need to) generate precisely timed signals.

**Edit**: there will be a few more cycles needed for the pointer arithmetic. I estimate something around 7 cycles. At low level, the code for getting a color should look roughly like this:

```
uint8_t *pixel = ...;
uint8_t index = *pixel;            // read from RAM: 2 cycles
uint8_t pgm_p;                     // pointer to flash
pgm_p = &pgm_lut + 3 * index;      // pointer arithmetic: ≥ 7 cycles
struct CRGB color;
color.r = pgm_read_byte(pgm_p++);  // read from flash: 3 cycles
color.g = pgm_read_byte(pgm_p++);  // read from flash: 3 cycles
color.b = pgm_read_byte(pgm_p);    // read from flash: 3 cycles

```
> 1 votes

# Answer
Because flash is on a different data bus to SRAM there is extra shuffling around needed internally in the CPU to get the data to where it needs to be. This uses a special "LPM" instruction (Load Program Memory), which takes an extra clock cycle to operate. On top of that the only way of using it is through the Z "index" register - there's no kind of immediate or offset loads. So it can be a little clunky to work with. All that is masked by the provided C functions, of course.

The upshot is that yes, it is somewhat slower reading from flash. How much slower, though, is impossible to say. Best case scenario: each access will take 1 more clock cycle. Worst case: well, it's impossible to know. That somewhat depends on both how you implement your reading of the CLUT and how the compiler batches things together.

I would suggest that you will need to employ the use of an oscilloscope and just try it out. Implement your changes, then manually adjust the delays and timing to get the output waveform just right.
> 1 votes

---
Tags: flash, memory, led-strip
---


title: Where is tcp.h?

text:
# Question
Title: Where is tcp.h?
This is for an esp8266 project that uses EasyAsyncTCP. In EasyAsyncTCP.cpp they `#include "lwip/tcp.h"`. But I can't figure out where that file is. I've found a tcp.h in the following directories on my c drive:

* c:\Program Files (x86)\Arduino\hardware\arduino\avr\firmwares\wifishield\wifiHD\src\SOFTWARE\_FRAMEWORK\SERVICES\LWIP\lwip-1.3.2\src\include\lwip
* c:\Program Files (x86)\Arduino\libraries\WiFi\extras\wifiHD\src\SOFTWARE\_FRAMEWORK\SERVICES\LWIP\lwip-1.3.2\src\include\lwip
* c:\Users\me\AppData\Local\Arduino15\packages\esp32\hardware\esp32\1.0.2\tools\sdk\include\lwip\lwip
* c:\Users\me\AppData\Local\Arduino15\packages\esp32\hardware\esp32\1.0.2\tools\sdk\include\lwip\lwip\prot
* c:\Users\me\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.5.2\tools\sdk\lwip\include\lwip
* c:\Users\me\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.5.2\tools\sdk\lwip2\include\lwip
* c:\Users\me\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.5.2\tools\sdk\lwip2\include\lwip\prot

but so far I've only tested the first two. I've tested them by either straight up deleting the directory and using the `#error got here` directive. No matter what I do my project builds. So I think I must either have the wrong file or it doesn't rebuild the entire thing.

How can I determine which tcp.h my program is including?

# Answer
While this isn't the right way of doing it I'm sharing the way that I figured it out.

**Step1:**

cd c:\

dir tcp.h /s

c:\Program Files (x86)\Arduino\hardware\arduino\avr\firmwares\wifishield\wifiHD\src\SOFTWARE\_FRAMEWORK\SERVICES\LWIP\lwip-1.3.2\src\include\lwip

c:\Program Files (x86)\Arduino\libraries\WiFi\extras\wifiHD\src\SOFTWARE\_FRAMEWORK\SERVICES\LWIP\lwip-1.3.2\src\include\lwip

c:\c:\Users\Me\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.5.2\tools\sdk\lwip2\include\lwip\protUsers\Me\AppData\Local\Arduino15\packages\esp32\hardware\esp32\1.0.2\tools\sdk\include\lwip\lwip

c:\Users\Me\AppData\Local\Arduino15\packages\esp32\hardware\esp32\1.0.2\tools\sdk\include\lwip\lwip\prot

c:\Users\Me\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.5.2\tools\sdk\lwip\include\lwip

c:\Users\Me\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.5.2\tools\sdk\lwip2\include\lwip

**Step2:**

I went through and tested each one. It was... `C:\Users\Me\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.5.2\tools\sdk\lwip2\include\lwip\tcp.h`
> 1 votes

---
Tags: programming, arduino-ide
---


# Question
Title: ESP8266 seems to be bricked , how to recover?
In a part of my sketch I put by mistake `pinMode(7,INPUT_PULLUP);`  Which is dedicated pin for external flash chip (gpio7/SDIO\_DATA\_0/SPI\_MISO) that not supposed to use for sketch. after uploading sketch now ESP is not responding to any further programming.

Could be Flash chip got corrupted due to the above mistakes?. Is it possible to recover? I already bricked two of my modules with same sketch before identifying above mistake. Sketch where working normal on Modules without above code.

When I connect to module with boad-rate 74880 chip returns  `ets Jan 8 2013,rst cause:2, boot mode:(3,7)` please check what happens when I try to upload the code upload error

# Answer
No, you have not bricked your ESP8266 by turning on GPIO7's pullup. All that will do is provide a weak pullup on the MISO line of the flash chip, which itself will have no effect - the flash chip's SPI Data Out pin will be able to easily override that weak pullup.

You can remove the flash chip and replace it with a completely blank brand new flash chip with nothing on it and still upload new code. There is nothing in the flash chip that the ESP8266 relies on to operate.

The boot sequence of the ESP8266 is as follows:

```
- Start executing the bootloader from the built-in ROM
  - Read the GPIO pins to determine code execution source
  - If flash is selected then initialize flash chip and read from address 0
    - Code on flash examines partition table to find code entry point
    - Jump to code entry point
  - If UART is selected then initialize UART
    - Wait for commands over the UART and respond accordingly

```

The startup code (boot stage 0) is in ROM. It's impossible to "brick" that. All that is in the flash is the code that tells the ESP8266 how to find the user's code, and that gets flashed to the chip every time you reprogram it.

You can think of it like BIOS boot on a PC. In the ROM is the BIOS that tells the CPU how to read from the hard drive. Then at the start of the hard drive is the code that tells the CPU how to load the operating system. The hard drive doesn't come with that code on it - you install that along with the operating system. But the motherboard has the BIOS built into ROM which tells it how to get going and read that boot sector.

However it is possible to destroy an ESP8266 by connecting the wrong things up to it in the wrong way. It is also possible to destroy some USB chips (the CH340G in particular) by wiring things up wrong.

So chances are that if you *have* bricked your ESP8266 it has nothing to do with your program and everything to do with what you have wired to it.
> 1 votes

# Answer
No, your sketch can not brick the device in that way. It's the bootloader that decides after a reset/power-up whether the esp has to accept a firmware (flash button is pressed) or has to run the uploaded sketch. At that point, nothing of your sketch has yet been executed and gpios have their default configuration, which is input anyway.

Also, when a pullup is in charge, one can still apply a logic level to the respective pin. The gpio then won't see any effect from the pullup.
> 0 votes

---
Tags: esp8266, flash
---


# Question
Title: How to set "IPAddress ip" using a variable?
Created a "variableInput.h" file for editing variables in one place; instead of searching multiple lines of code, to find lines needing editing.

```
//   variableInput.h
//
//   User defineable variables; one location for editing variables

// Replace with your network details
#define host = "esp32"
#define ssid = "YOURSSID"
#define password = "YOURPASSWORD"

//NTP Time Servers
#define udpAddress1 = "198.50.238.156"  //NTP Time server
#define udpAddress2 = "132.163.96.3"  //NTP Time server

//publicIP accessiable over Internet with Port Forwarding; know the risks!!!
//WAN IP Address.  Or use LAN IP Address --same as server ip; no Internet access.
#define publicIP = "YOURPUBLICIP"
#define LISTEN_PORT  8030  //default listening Port 80 for "GET" requests.

//Graphing requires "FREE" "ThingSpeak.com" account..
//Enter "ThingSpeak.com" data here....
//iframes of graphed data are available from "ThingSpeak.com."
#define myChannelNumber = 123456
#define myWriteAPIKey = "E12345"

//FTP Credentials
#define ftpUser = "FTPUSER"
#define ftpPassword = "FTPPASSWORD"

//setting the addresses
#define ip(10,0,0,200);
#define gateway(10,0,0,1);
#define subnet(255, 255, 255, 0);
#define dns(10,0,0,1);

//Restricted access to client ip list.
#define Restricted = "/ANYNAME"

//OTA Credentials
//default username: USERNAME
//default password: PASSWORD

// "setting the addresses" is the part that I do not understand.

```

Segment of related code from "wifi\_Start" function:

```
//setting the addresses
IPAddress ip;
IPAddress gateway;
IPAddress subnet;
IPAddress dns;

```

Is there a solution?

William

# Answer
> 0 votes
You are not using #define correctly. The syntax is #define {name} {value}. There is no = between name and value so for your IP address lines you want #define myIp ip(192, 168, 1, 11)

# Answer
> 1 votes
Here's how I do it (for an Arduino that connects to my Mosquitto server) using wired ethernet (WiFi works the same way):

```
#include <Ethernet.h>
#include <PubSubClient.h>
EthernetClient ethClient;
PubSubClient client(ethClient);

byte mac[]    = {
  0xde, 0xad, 0xbe, 0xef, 0xca, 0xfe
};
IPAddress ip(192, 168, 1, 75);
IPAddress server(192, 168, 1, 11);
void setup() {

  client.setServer(server, 1883);
  client.setCallback(callback);

  Ethernet.begin(mac, ip);

}

```

---
Tags: library
---


# Question
Title: RTC DS1307 VCC not getting connected to 5V of Arduino Uno
I am using RTC DS1307 with "TINY RTC I2C modules" written on it.I had downloaded RTClib library from adafruit and using the example code. I connected GND-\>GND, VCC-\>5V, SDA-\>A4 and SCL-\>A5. However after connecting the VCC to 5V the "ON" Led does not lights up and the code is not getting uploaded. I tried connecting the VCC to 3.3 V the code gets uploaded but does not shows any output on the screen.

# Answer
> 1 votes
It seems an hardware problem on Arduino Uno board.

Try to connect the 5V pin of Arduino Uno to a digital pin (e.g D7) and write a program for read a digital pin.

```
int inPin = 7;     // digital pin 7
int val = 0;       // variable to store the read value

void setup()
{
  pinMode(inPin, INPUT);        // sets the digital pin 7 as input
}

void loop()
{
  val = digitalRead(inPin);     // read the input pin
  Serial.println(val);          // print read value on serial
}

```

If you're **not** able to load this sketch on your Arduino, most likely it's an hardware problem on Arduino.

# Answer
> 1 votes
Soldering was not done properly. The vcc and ground got "short" that's what the shopkeeper said. We again soldered it on the other side. Now its working

# Answer
> 0 votes
Just another point,

From my experience, any module that uses a serial connection can disrupt the sketch uploading process to the Arduino.

The best is to upload to Arduino when all serial connections are dis-connected.

---
Tags: arduino-uno, rtc
---


title: Copy one SD card to another

text:
# Question
Title: Copy one SD card to another
I want to copy an SD card to another.

What is the best way to attack this problem?

Should i get two sd card shields? If yes, is it possible to stack two together, or will there be problems with the interface protocols (SPI/I2C)?

# Answer
> 2 votes
It should be perfectly possible to do it. As long as the SD cards and shields play ball then there should be no problem from a hardware perspective.

From a hardware perspective you should be able to share the MOSI, MISO and SCK lines and just have separate CS pins per card.

However some SD card shields employ level translation that doesn't properly release the SPI bus when idle, and some cheap SD cards don't release the bus in a timely manner too.

From a software perspective though it may be a different matter. I am not sure how well you can run two instances of the SD classes at once on an Arduino. You may be better off looking at FatFS instead which is far more flexible.

You have two strategies when copying cards, each of which has a different way of programming it.

1. Block copy the entire card: this involves reading a 512 byte block from one card and writing it to the other one. This would be the most efficient from a resource perspective (you don't need to care about the contents of the card, so don't need any filesystem code), but if the card is not close to full it will be very inefficient from a runtime perspective. Also the two cards have to be the same size for it to work well.
2. File copy. For this you need much more complex code, but it you only copy each file from one card to the other. It's much better though if the cards don't have much data on them - also the cards can be different sizes.

---
Tags: sd-card
---


title: I2C Communication with the ICM-20789

text:
# Question
Title: I2C Communication with the ICM-20789
I am trying to interface with the ICM-20789 over I2C. DataSheet

I have been successfully able to get all three gyroscope readings and all three accelerometer readings. I am now trying to get the pressure readings from the device, since it has a built-in pressure sensor, but cannot seem to get it working.

In the datasheet, it says to enable Bypass Mode.

> Bypass Mode: Set register INT\_PIN\_CFG (Address: 55 (Decimal); 37 (Hex)) bit 1 to value 1 and I2C\_MST\_EN bit is ‘0’ (Address: 106 (Decimal); 6A (Hex). Pressure sensor data can then be accessed using the procedure described in Section 10

In the setup I use this code:

```
  Wire.beginTransmission(gyro_address);
  Wire.write(0x37);      //INT_PIN_CFG
  Wire.write(0x02);      //00000010
  Wire.endTransmission();

```

I am having trouble finding I2C\_MST\_EN in the datasheet as well, as I cannot find it in the 6A Address.

Once I have the bypass bit enabled, I try to request the pressure and temperature data from the sensor using this code:

```
Wire.beginTransmission(0x63);
Wire.write(0x7866);
Wire.endTransmission();
Wire.requestFrom(0x63, 16);

while (Wire.available() < 16);
pressure = Wire.read() << 16 | Wire.read() << 8 | Wire.read();
temp_2   = Wire.read() << 16 | Wire.read() << 8 | Wire.read();

```

Unfortunately, the device freezes when I try to run this code. I know I am obviously doing something wrong here, just don't know exactly what yet.

# Answer
There are four things wrong with your code.

1. You are not sending the "start measurement" command properly. The `Wire.write()` function can only send 8 bits, but you are passing it a 16-bit value. Instead you should break it apart into 2 separate 8-bit values:

Wire.beginTransmission(0x63);
Wire.write(0x78);
Wire.write(0x66);
Wire.endTransmission();
2. The data returned is spread over 9 bytes, not 16. According to the datasheet:

> Temperature data is transmitted in two 8-bit words and pressure data is transmitted in four 8-bit words.

and:

> Two bytes of data are always followed by one byte CRC checksum

That's 2 + 4 = 6 + (6/2) = 9

3. You aren't waiting for the conversion to complete. According to the datasheet, in "ultra low noise" mode (0x7866) it takes up to 94.5ms to perform the measurement. So you should add a delay of slightly more than that to allow it to do what it needs to do.
4. The command you are sending responds with temperature first, not pressure, but you are reading pressure first (and reading the wrong bytes anyway).

In all, your code should look more like:

```
Wire.beginTransmission(0x63);
Wire.write(0x78);
Wire.write(0x66);
Wire.endTransmission();

delay(100);

Wire.requestFrom(0x63, 9);
uint8_t tmsb = Wire.read(); // Temperature highest byte
uint8_t tlsb = Wire.read(); // Temperature lowest byte
Wire.read();

uint8_t pmmsb = Wire.read(); // Highest pressure byte
uint8_t pmlsb = Wire.read(); // Next highest pressure byte
Wire.read(); // Discard checksum
uint8_t plmsb = Wire.read(); // Next lowest pressure byte
uint8_t pllsb = Wire.read(); // Lowest pressure byte
Wire.read(); // Discard checksum

pressure = (pmmsb << 24) | (pmlsb << 16) | (plmsb << 8) | pllsb;
temp_2   = (tmsb << 8) | (plsb << 8);

```
> 1 votes

---
Tags: i2c, pressure
---


# Question
Title: LED and MOTOR "ON" when A BLE DEVICE APPROACH ESP32 MICROCONTROLLER DFR0575
I have this code that is working perfectly but I want my device to start vibrating too (right now only the led is working)

On a Wemos Battery Module I have simply connected the vibration motor on the same PIN of the LED and it works perfectly.

Now I want to do the same on an **Beetle ESP32 Microcontroller DFR0575**. I used the same code But I can't make the module vibrating (The led light is working perfectly)

this is the code:

```
 #include <BLEAdvertisedDevice.h>
   #include <BLEDevice.h>
   #include <BLEScan.h>

   const int PIN = 2;
   const int CUTOFF = -50;

   void setup() {
     pinMode(PIN, OUTPUT);
     BLEDevice::init("tkr");
   }

   void loop() {
     BLEScan *scan = BLEDevice::getScan();
     scan->setActiveScan(true);
     BLEScanResults results = scan->start(1);
     int best = CUTOFF;
     for (int i = 0; i < results.getCount(); i++) {
       BLEAdvertisedDevice device = results.getDevice(i);
       int rssi = device.getRSSI();
       if (rssi > best) {
         best = rssi;
       }
     }
     digitalWrite(PIN, best > CUTOFF ? HIGH : LOW);
   }

```

# Answer
> 2 votes
It is generally very dangerous to drive any motor directly from a digital output pin. Motors often need way more current, than the digital pin can provide. Based on the answer to this question, an ESP8266 can provide 20mA or 12mA depending on current direction (may be a bit different for an ESP32, but not substantially). Drawing more current, than the pin can provide, can lead to the destruction of the output hardware of the pin. It is not easy to say, when this will happen, because it depends not only on the current draw, but also on time and fabrication variation.

Also a motor is an inductive load, which means, that fast changes (for example turning on and off) will induce a reverse voltage in the motor coils. These can easily be very high relative to the supply voltage and thus destroy you output pin or even the complete microcontroller.

I cannot give you a full reasoning, why it works with the first board, but not with the second. I think, it has to do with the above.

You should always do 2 things, when driving motors with a microcontroller:

1. **Use a motor driver circuit:** You can either buy a ready to use motor driver or you can build one yourself. If you only want to turn the motor in one direction (as with a vibration motor), all you need is a MOSFET, which will act as a switch between the motor and the power supply. This switch get's controlled by the Arduino's output pin (which only needs to supply a very low current for switching). You can google "MOSFET as a switch". Be sure to use a MOSFET, that can provide the needed current and that is good in saturation for the used gate voltage (the working voltage of the microcontroller).
2. **Use a flyback diode:** The reverse induction voltage can also hurt MOSFETs. You want to let these voltage spikes quickly plenish by letting the current flow to ground. You can do this with a flyback diode. That is a diode, that bridges drain and source of the MOSFET. It is oriented so that block for normal operation (the normal positive supply voltage). When the MOSFET get's turned off, a great negative voltage will build up in the motor, but since the diode is conducting in this way, the voltage will safely flow to ground, so that the induction voltage cannot hurt the other electronic parts.

---
Tags: esp32
---


title: Push Button to Drive Power to Servo

text:
# Question
Title: Push Button to Drive Power to Servo
I am currently doing a project for a class which uses a few other components such as an LCD, a servo, and such. I want to use a button which acts as a circuit breaker on the Vin of the servo in which the servo will only be powered when the switch is pressed. I wanted to implement something like this because I wanted to minimize the power consumption and also acts as a mechanical counter-measure in case the servo keeps on spinning in unwanted situations, such as having the servo entangled by hair or something like that.

I know that I can just connect the button to the I/O pins but I wanted to rely on a hardware solution for power minimization and safety reason.

The servo draws 170mA when idle and can draw a maximum of 1.2A, but I believe it will only draw about 500-600mA with the intended load. It can run between 4.8-6V.

So my question is, would my circuit configuration work for my application? Would it be safe? Do I need any other additional components? Thanks for anyone that can help!

# Answer
There is a chance that this arrangement *could* damage the servo and possibly the Arduino. The problem is that, depending on the internals of the servo, it could try and draw power for the servo through the data pin when the button is not pressed. This would both over-stress the internals of the servo and the internals of the Arduino's GPIO pin.

What you could do to mitigate that is to connect the servo's switched power to another GPIO pin of the Arduino, which is set as INPUT. That will then tell the Arduino when the button is pressed and when it's not pressed. Then you use that information to `attach` and `detach` the servo in your code so it is only being actively driven when the button is pressed.
> 1 votes

# Answer
Yes, that should be safe, as long as the button can conduct the needed current. That depends on the type of button. You can simply test this. If the button get's hot, it is too small for this.

If it should happen, that the button cannot conduct the needed current, you have 2 ways to go:

1. Just use a bigger button. You can buy buttons, that are meant for mains supply, which will be able to conduct way enough. Every button, that you buy (at least at electronics shops, maybe not on aliexpress or ebay), should have some kind of data sheet, which states the absolute maximums for the electrical characteristics. A maximum current can be found there.
2. You can use a MOSFET (that is capable of providing the needed current) and control it with your button. That would be the way to go, if you really need or want to use this specific button.
> 0 votes

---
Tags: arduino-nano, power, servo, button
---


# Question
Title: Is digitalWrite(pinnumber,LOW) different from ground pin
I am using Tinkercad simulator, but an unusual thing happened. When I connect one wire of dc motor to pin 9 with `digitalWrite(9,HIGH)` and other wire to ground, the motor runs with rpm of 5555.

```
void setup()
{
  pinMode(9, OUTPUT);
}

void loop()
{
  digitalWrite(9, 1);
}

```

But instead if I connect the other wire to pin 13(say) and set `digitalWrite(13,LOW)` the motor runs at an rpm of 3846.

```
void setup()
{
  pinMode(9, OUTPUT);
  pinMode(13, OUTPUT);
}

void loop()
{
  digitalWrite(9, 1);
  digitalWrite(13,0);
}

```

Can anyone explain this?

# Answer
> 5 votes
Yes, it is different.

First: **Never run a motor directly from IO pins - you will damage your Arduino**. Not only can a real Arduino not supply enough current, but motors generate a lot of back-EMF that will kill an Arduino.

Secondly a pin doesn't connect direct to GND or VCC - it is connected through a MOSFET that performs the switching. That MOSFET has an ON resistance, which causes a voltage drop across it determined by the current being sourced or sunk through the pin.

You can read more about GPIO pins here.

# Answer
> 2 votes
In the real world, either pin sinks current to Gnd via an onchip N-channel MOSFET. They will safely sink 20, 25mA. If your motor allows more than 40mA to flow, you risk damaging the pin and likely the whole chip.

Similarly, either pin can source the same current to a load, likely via P-channel MOSFET, with the same current limitations.

Using both together, you have one transistor sourcing current, one transistor sinking current, so you have twice the Rds (MOSFET on-resistance) limiting current to the load, hence the simulator might have the motor going slower due to less current being available.

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


# Question
Title: My DS18B20 is reading high. How can I get it to return the correct temperature?
I am working on a heating control system for my home, but having problems with the temperature sensor reading higher than I expect.

I have a 5V Arduino Mini Pro clone hooked up to a relay module, an HD47780 display and a Tiny RTC module, with a DS18B20 attached to it.

The DS18B20 is powered from the 5v Vcc applied to the Tiny RTC module rather than using parasitic power on the DQ line (as I wasn't sure if the Onewire libraries supported this mode of operation) and the DS18B20 datasheet says that Vcc may be between 3.0v and 5.5v. I measured the regulated power from the Mini Pro's being at 5.2v.

I am comparing the temperature from the DS with the existing room thermostat (bi-metallic), an RS desktop temperature monitor with two sensors, a small 'thermo-hygrometer' and a bi-metallic fridge thermometer (in the upper quarter of its temperature range). The readout from the DS is always around 1-2 degrees higher than the readout from the other sensors, which are within a degree of each other.

<sup>† Not the actual one, but something similar.</sup>

Reading various forums I have heard that these sensors are quite accurate but can suffer from localised heating from components near them, so I moved the sensor onto a 20cm cable and positioned it well away from the rest of the electronics. This made no difference.

I then read that the DS can become self heating if it is supplied with too high a Vcc voltage, so I added a Red LED with 1.7v drop and measured the new voltage over the DS as 3.5v, but again, after waiting for the temperatures to stabilise once more, this made no difference.

Can anyone suggest why the DS may be reading high and what I can can do to prevent this?

# Answer
I've put a lot of DS18B20 sensors in place now on various sensor nodes - maybe 50 or so. I've learnt a bit about the readings returned from them. I know you have isolated some of these as not being the cause, but it is good to confirm that they are issues.

I don't know if you are using Celsius or Fahrenheit, so the degree of the problem isn't clear.

**Localised heating**

I don't think of Arduino as a "hot" chip, but putting a DS18B20 in an enclosure with an Arduino and LCD caused me to see readings 2-3°C higher than expected.

Moving it outside the enclosure fixed this.

**Heating from high Vcc/frequent conversions**

If you supply the chip with a high Vcc and perform frequent conversions (i.e. as frequently as you can), the chip does warm up. I have seen this increase readings by 1-2°C.

I haven't seen the problem with high Vcc alone, but I operate most DS18B20 in parasitic mode and convert at most once every 10s. The ones operated in active mode generally have the powered turned off when not being used.

OneWire and DallasTemperature do support parasitic mode.

**Not all temperature sensors are created equal**

I had a number of temperature sensors before I started playing around with DS18B20. Almost without exception, these under-read. Most of them are based on thermistors and calibration is poor. I thought the DS18B20 were over reading, but when I used a good thermocouple and meter, I could validate that they were correct.

This was about learning to trust the DS18B20.

**Heat conducted along wire**

If you have the sensors on a wire, the wire conducts a surprising amount of heat. This can be an issue when running wiring along pipes.

**Fake DS18B20**

These sensors are very popular, and this seems to have caused fakes to appear. I have a batch of stainless steel waterproof sensors that over-read and the timings were out. They worked with the OneWire library, but not a DS2482 OneWire master. I have heard of the normal TO-92 cased ones being fake as well.
> 12 votes

# Answer
In my case, the wiring between my uC and the sensor was too short, and was transmitting some heat. I thought that couldn't be the case at first, since another temp sensor was reporting accurate temps at the same distance. I moved it to another location on the board and voila!
> 2 votes

# Answer
Perhaps you might want to calibrate your sensor.

What does it read when immersed in boiling water (assuming sea level) ? 102.5 Celsius? That would give you a high-temperature calibration of -2.5C.

Obviously it's better to calibrate around the temperatures you expect to me measuring. That means trusting (or averaging?) some measuring device and calibrating to that.
> 1 votes

# Answer
I have seen offsets of several degrees C when using DS18B20 on a 3.3V bus, switching to a stable 5.0V bus and I got more reasonable values. (tested with and without parasitic power)
> 1 votes

# Answer
I've made some experiments. If DS18B20 was on short cable \<1cm to my Arduino Pro Micro the readings was 5 degrees more than environment was. On cable lenght \>10cm from arduino board and no matter where the resistor was mounted (near arduino or near DS18B20) the readings was fine.
> 1 votes

---
Tags: sensors, temperature-sensor
---


# Question
Title: Arduino wont start up and it wasnt succesfully booted in any time it was downloaded
I know the title sounds stupid but I never found a question like mine so I wanted to be specific because I downloaded the Arduino IDE to start my first project and I never managed to boot it because nothing happens when I try and I also tried every kind of thing to make it work I could think of. I reinstalled it, downloaded from another link like the zip version and also tried the windows repairtool. I also tried to boot it as admin several times but nothing changed anything. I did all of that yesterday and today when I started the Pc and retried I atleast saw something of a bootingscreen of the app so I thought I just had to restart but then it just went off again and the pain from yesterday began once again.

´´ I own windows 7 64 bit ´´ and tried every download except the one for windows 8.1 and 10

I saw a question about Arduino IDE not starting but this person atleast got any response from the program and the tipp they suggested with the folder in

´´ AppData/Lokal where you delete broken data to reinstall doesnt work too because the arduino folder doesnt even excist in the whole appdata section. ´´

´´ Windows repair tool said the program is not compatible, only in Windows xp (service pack 2) version but in compatibility mode nothing changes ´´

Ok *thew* this question is really long but I gave my best to explain everything I could about my problem so I really hope somebody could help me on my problem so I didnt waste my 45 Euro and time on tech stuff that I cant use

one thing to meantion I have left is that i bought my stuff from a teacher (Erik Verbene) on the internet

but that doesnt matter because it is your program that is not working so yeah hope somebody can help me out on this dilemma

# Answer
> 1 votes
The Arduino IDE is written in Java. It's 100% platform independent, so the version that you download makes no real difference.

The most likely culprit is the version of Java that is installed in your computer. I am not sure off hand what versions of Java the Arduino IDE works with, but for certain version 8 will be your best bet. Make sure that you have the latest version of Java 8 installed. If you have any older version installed you should uninstall it and replace it with Java 8. I'm not sure how the IDE works with newer versions than 8, but removing anything newer than 8 and installing Java 8 may be a good idea.

---
Tags: arduino-ide
---


# Question
Title: Concern myself with current draw from digital pins used as INPUT with internal pullups?
My project is using a genuine Arduino Mega 2560, probably 3-4 yrs old since purchased (I don't see any revision numbers on the PCB). It's being used to read a lot of switches, buttons and drive some LED's and displays.

When using a digital pin as INPUT with the internal 10k pullup enabled, do I need to consider the draw with respect to the 200mA total through all pins? Is it simply the 10k ohm resistor with 5V so 0.5mA? Can I just ignore it? (there's only so many pins I suspect I can ignore it)

I've seen several posts/pages about driving LED's using transistor arrays powered by an external source and those spec sheets describe the transistor input currents so I can estimate the draws for those elements, but not sure if I need to concern myself with the Arduino pins used as INPUT.

# Answer
You are right. The current through digital inputs is so low, that you can normally ignore it.

And the 0.5mA, that you calculated don't flow all the time, just, when the corresponding button is pressed and thus shorted to ground, because only then a current will flow through the pullup resistor. The current into the actual input hardware is even smaller. So, as long as not all buttons are pressed at once, the current will be even lower as calculated.

Buttons are somewhat voltage devices. They don't need a specific amount of current, just of voltage. So the actual value of pullup/pulldown resistors are not critical. LEDs in contrast are current devices. They need a specific current to light up, which is often higher, than the maximum output current of a digital pin. Thus they are often driven with an additional transistor.
> 0 votes

---
Tags: atmega2560
---


# Question
Title: Connecting Logitech F310 gamepad to Arduino Uno and Arduino USB Shield
I am trying to connect Logitech F310 gamepad to Arduino Uno with ARDUINO USB HOST SHIELD https://store.arduino.cc/arduino-usb-host-shield using http://github.com/felis/USB\_Host\_Shield\_2.0 library.

The closest is https://github.com/felis/USB\_Host\_Shield\_2.0/tree/master/examples/HID/USBHIDJoystick example After compiling there is no print output in serial window after "Start". Tried keyboard sketch on same board - it worked.

There is "Mode" button on joystick - by pressing green led is switched ON and OFF. Behind the joystick there is switch between "X" and "D" . On "D" green led is working, on "X" - not.

Is this joystick even compatible with HID library? Is there other way how to configure it to USB shield? Joystick is working on different other devices.

# Answer
> 0 votes
I found it here : https://github.com/AlanFord/Logitech\_F310\_and\_Arduino So there is a glitch in library and driver customization was necessary

---
Tags: arduino-uno, usb
---


# Question
Title: Weird sound when modulating the pulse width on Arduino
I'm trying to generate a pulse width modulated sound using Arduino Nano.

But it generates the weird sound unlike my expectation.

**Here's my code:**

```
class Phasor
{
public:
    Phasor(const float frequency)
    :frequency(frequency)
    ,phase(1.0f)
    ,lastTimeMicros(0){};
    virtual ~Phasor(){};
    void setFrequency(const float frequency)
    {
        this->frequency = frequency;
    }
    float process()
    {
        const unsigned long currentTimeMicros = micros();
        if (phase == 1.0f) lastTimeMicros = currentTimeMicros;
        const unsigned long elapsedTimeMicros = currentTimeMicros - lastTimeMicros;
        const unsigned long cycleDurationMicros = static_cast<unsigned long>(1000.0f / frequency) * 1000;
        if (elapsedTimeMicros < cycleDurationMicros)
            phase = static_cast<float>(elapsedTimeMicros) / static_cast<float>(cycleDurationMicros);
        else
            phase = 1.0f;
        return phase;
    }
private:
    float frequency;
    float phase;
    unsigned long lastTimeMicros;
};

class PulseOsc
{
public:
    PulseOsc(const float frequency, const float pulseWidth)
    :phasor(frequency)
    ,pulseWidth(pulseWidth){};
    virtual ~PulseOsc(){};
    void setFrequency(const float frequency)
    {
        this->phasor.setFrequency(frequency);
    }
    void setPulseWidth(const float pulseWidth)
    {
        this->pulseWidth = pulseWidth;
    }
    float process()
    {
        const float phase = phasor.process();
        if (phase <= pulseWidth)
            return 1.0f;
        else
            return -1.0f;
    }
private:
    Phasor phasor;
    float pulseWidth;
};

Phasor *phasorLFO;
PulseOsc *pulseOsc;

void setup()
{
    Serial.begin(9600);
    pinMode(9, OUTPUT);
    phasorLFO = new Phasor(0.1f);
    pulseOsc = new PulseOsc(440.0f, 0.5f);
}

void loop()
{
    pulseOsc->setPulseWidth(phasorLFO->process());
    int outVal = LOW;
    if (pulseOsc->process() > 0.0f) outVal = HIGH;
    digitalWrite(9, outVal);
}

```

The resulting sound is very weird and glitchy. It works fine when I fix the pulse width value. (without LFO)

What is wrong with my code? How do I fix this? I would appreciate any advice.

# Answer
I see two issues with this program. The first one has already been pointed out by Majenko in a comment: you are doing too much floating point calculations. The second has to do with the way your `Phasor` manages the time.

If you take a look at the Blink Without Delay Arduino tutorial, you will see something along these lines:

```
if (currentMillis - previousMillis >= interval) {
    previousMillis = currentMillis;
    toggle_the_LED();
}

```

In this code, `interval` is the *minimum* time between toggles. Whenever the program gets a little bit late and `currentMillis - previousMillis` is strictly larger than `interval`, this extra time is lost and the program will be late for all the subsequent LED toggles. If instead of the minimum you are interested in the *average* time between toggles, then you should write:

```
if (currentMillis - previousMillis >= interval) {
    previousMillis += interval;  // <- advance by exactly one period
    toggle_the_LED();
}

```

Now, `previousMillis` is no more the time when the last toggle was *performed*, it is the time when the last toggle was *scheduled*. With this version you can still have some jitter, but at least the average frequency should be right. If the program is so busy that it can get late by a full period, then it would be better to replace the `if` by a `while`, in order to catch up all the missed periods.

Your `Phasor::process()` method is a little bit more involved than the tutorial above, yet the line

```
if (phase == 1.0f) lastTimeMicros = currentTimeMicros;

```

is going to get you out of schedule for exactly the same reason.

That being said, here is my take at your phasor idea, *completely untested*:

```
class Phasor()
{
public:
    Phasor(float frequency_Hz)
    {
        period = round(1e6 / frequency_Hz);
        frequency = 0x10000 / period;
    }
    uint16_t process()
    {
        uint16_t now = micros();
        while (now - last_time >= period)
            last_time += period;
        return (now - last_time) * frequency;
    }
private:
    uint16_t period;     // unit = 1 us
    uint16_t frequency;  // unit = 1/(2^16 us) ~ 15.3 Hz
    uint16_t last_time = 0;
};

```

I changed a few things from your implementation:

* removed the `setFrequency()` method because YAGNI
* no floating point except in the constructor, for performance reasons
* only 16-bit arithmetics, for the same reason
* no division in `process()`, because division is expensive
* the phase is not stored, because there is no use to storing it
* the phase is an integer in units of 2<sup>−16</sup> periods

Note that the unit chosen for the phase is the most natural one when dealing with 16-bit arithmetics. Note also that storing microseconds in 16-bit variables only works for frequencies higher than 15.3 Hz. A very low frequency phasor (your “LFO” for instance) would need 32-bit arithmetics.
> 1 votes

# Answer
Seems like you are using the system clock `micros()` to calculate `elapsedTimeMicros`, so probably the time spent on the process of calculation and sending signal to the pin may affect it, which may lead to inconsistent duty cycle.
> 2 votes

---
Tags: arduino-nano, c++
---


title: RtcUtility.h: No such file or directory

text:
# Question
Title: RtcUtility.h: No such file or directory
I have a problem with remaining headers. Can't seem to find the first header "RtcUtility.h". Anyone how to fix? I've provided a picture for you to see.

Error Messages:

> Arduino: 1.8.10 (Windows 7), Board: "NodeMCU 1.0 (ESP-12E Module), 80 MHz, Flash, Disabled, All SSL ciphers (most compatible), 4M (no SPIFFS), v2 Lower Memory, Disabled, None, Only Sketch, 115200"
>
> sample\_time:6:24: error: RtcUtility.h: No such file or directory
>
> Multiple libraries were found for "ArduinoOTA.h" #include
>
> Used: C:\Users\user\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.5.2\libraries\ArduinoOTA ^
>
> Multiple libraries were found for "Wire.h" compilation terminated.
>
> Used: C:\Users\user\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.5.2\libraries\Wire Multiple libraries were found for "ESP8266WiFi.h" Used: C:\Users\user\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.5.2\libraries\ESP8266WiFi Multiple libraries were found for "ESP8266mDNS.h" Used: C:\Users\user\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.5.2\libraries\ESP8266mDNS exit status 1 RtcUtility.h: No such file or directory
>
> This report would have more information with "Show verbose output during compilation" option enabled in File -\> Preferences.

# Answer
> 1 votes
Please add the RTC library in the Arduino as below.

*Open the Library Manager and search for "Rtc by Makuna" and install.*

You can also checkout the Github page for that particular library at

https://github.com/Makuna/Rtc

---
Tags: esp8266, arduino-ide, rtc
---


# Question
Title: esp_partition_get_sha256() mismatches PHP's hash() function in HTTPUpdate
Disclaimer: It may be that this question belongs to a PHP forum instead of this one. However, this question is *also* very ESP32/Arduino related. Please correct me if this is the case.

The scenario:

* Implementing self-update routines for my ESP32 project, using HTTPUpdate Using a server-side PHP script to decide which binary image to serve to the device, or return HTTP 304 return code if no updates available.
* Using the sketch's MD5 **and** SHA-256 hashes provided by the HTTPUpdate library as request headers, server-side, to check binary version.

The problem:

* The MD5 hash contained in the request header "x-ESP32-sketch-md5" *is the same* as the MD5 hash calculated by a simple `md5()` call using the raw binary for the currently running version.
* The SHA256 hash contained in the request header "x-ESP32-sketch-sha256" **is not the same** as the hash obtained by calling PHP's `hash("sha256", $v)` (where `$v` contains the same raw binary).

Example:

* MD5 (HTTPUpdate): c93d814989b53a24a0164e561b6a8bf8
* MD5 (PHP): c93d814989b53a24a0164e561b6a8bf8 (no difference)
* SHA256 (HTTPUpdate): 5634674253E095600CD863A34287FCA742BCFCF9B5BF409870DD65AF0ADEF7A0
* SHA256 (PHP): 1ECDDF3215520C79AAD13BBC1D116D9286910490DF316B9B203FCBFC89CBCCC2 (different)

Am I doing something wrong?

Note: The `esp_partition_get_sha256()` function is called internally by the `update()` method of the HTTPUpdate library.

PHP Code (for calculating the hashes):

```
<?php

$v = file_get_contents("fw.bin");

print("MD5: ". md5($v)."\r\n");
print("SHA256: ".hash("sha256", $v)."\r\n");

```

Arduino code (the relevant part):

```
// Called once or twice a day
void update_fw()
{
    Serial.println("Checking for updates...");

    t_httpUpdate_return ret = httpUpdate.update(client, "http://my_server/fw/check_fw.php");  // For now it only logs the headers and returns HTTP 304 code

    switch (ret)
    {
      case HTTP_UPDATE_FAILED:
        Serial.printf("HTTP_UPDATE_FAILED Error (%d): %s\n", httpUpdate.getLastError(), httpUpdate.getLastErrorString().c_str());
        break;

      case HTTP_UPDATE_NO_UPDATES:
        Serial.println("HTTP_UPDATE_NO_UPDATES");
        break;

      case HTTP_UPDATE_OK:
        Serial.println("HTTP_UPDATE_OK");
        break;
    }
}

```

PHP code (logs headers and returns HTTP 304 code):

```
<?php

$headers = getallheaders();

if (!file_exists("log.txt"))
{
    file_put_contents("log.txt", print_r($headers, true));
}

http_response_code(304);            // No updates.

exit;

```

Thanks in advance.

# Answer
Your problem stems from a misunderstanding of what the functions are doing.

Your MD5 hashes are the hash of the binary file itself. And so they match.

Your PHP SHA256 is the hash of the binary file (like the MD5), but the ESP's SHA256 is not.

The file itself contains an SHA256 hash of the *content* of the file, not the whole file. The function esp\_partition\_get\_sha256 merely returns that SHA256 hash.

According to the SDK documentation:

> For apps with SHA-256 appended to the app image, the result is the appended SHA-256 value for the app image content. The hash is verified before returning, if app content is invalid then the function returns ESP\_ERR\_IMAGE\_INVALID. For apps without SHA-256 appended to the image, the result is the SHA-256 of all bytes in the app image. For other partition types, the result is the SHA-256 of the entire partition.

If you were to take the binary file and somehow strip off the extra sha256 information and then perform a hash of the results you should (theoretically) get the same hash, which would be the same has as is contained within the file itself.
> 1 votes

---
Tags: esp32
---


# Question
Title: Connecting 2-pin JST PH connector to Arduino Mega
I’m want to connect 50 LDR to my Mega, I wondering if I use a 2-female pin JST PH connector to connect the LDR, how can I link 2-pin male JST PH connector board to the Mega and does this board exist?

# Answer
> 0 votes
There exists 2.00 to 2.54mm adapters, like in this link.

They look like below (example of 1.27, 2 and 2.54mm):

---
Tags: arduino-mega, pins, connector
---


title: Arduino round to nearest 0.5

text:
# Question
Title: Arduino round to nearest 0.5
I am having a double value for example: 34.26 or 11.92 or 2.51. It should be rounded to the nearest 0.5 so 1.34 -\> 1.50 and 32.78 -\> 33 and 21.09 -\> 21.00

How do to do this?

# Answer
> 7 votes
It is a very bad idea to use float.
That being said. multiply by 2 and do a standard round.
Then divide back by 2.

For example:

```
1.34     *2 = 2.68
round(2.68) = 3
3        /2 = 1.5

```

and

```
32.78    *2 = 65.56
round(65.56)= 66
66       /2 = 33

```

# Answer
> 0 votes
I made a little algorithm from the first thing that popped into my mind. I'm using integers, since I believe it works better as floats.

For example, you can represent euro's (with floating points) by expressing them in cents.

```
unsigned int roundToFifty(unsigned int nonRound){
    unsigned int rest = nonRound % 50;
    unsigned int fits = floor(nonRound / 50);
    unsigned int add = 0;
    if(rest >= 25){
        if(rest >= 75){
            add = 100
        }else{
            add = 50
        }
    }
    return fits*50+add
}

```

I actually think the algorithm is a tad weird and something simpler/more effective could also exist. It was just the first thing that popped into my mind.

# Answer
> 0 votes
```
float i=1.5237475984328953;
#include "math.h"
void setup()
{
 Serial.begin(9600);
}

void loop() {
 Serial.println(i,6);
 float price = i*1000;
 Serial.println(price,2);

 float roundNearest = roundf(i*1000) ; // x 100 for two decimal place
  roundNearest = roundNearest/1000;
 Serial.println(roundNearest,6);

 price = (roundNearest*1000);
 Serial.println(price,2);
 while(1){}
}

```

you u can use roundf() like in this video Demo Video

---
Tags: arduino-uno
---


title: Audio Recording using Arduino BT module

text:
# Question
Title: Audio Recording using Arduino BT module
I want to take audio signal through mic connected to Arduino and then transfer it to PC using BT module. I want to do it with BT (HC05) and Arduino Mega. I need audio packages at 44 KHz and 24-32 bits per sample.

Can I use AudioInI2S library to receive audio samples? Does HC05 support this type of communication?

I want to save and analyze the audio samples later on. I have worked on Arduino before but I am totally new to audio streaming and I am not sure where to begin from. Any guidance would be appreciated.

# Answer
> 0 votes
In short: No and no.

---

> Can I use AudioInI2S library to receive audio samples?

No. The library is not for the Mega:

> This library provides simple way to play and analyze audio data using Arduino on SAMD21 based boards (i.e Arduino or Genuino Zero, MKRZero or MKR1000 Board) using the I2S bus.

---

> Does HC05 support this type of communication?

No. The HC05 is a serial module. It works at baud rates that are far to low to transfer the data in a timely fashion, and can't send data in a form the PC sees as audio (so you'd need to write your own translation software to convert serial data into an audio file).

---

> Any guidance would be appreciated.

Just buy a cheap bluetooth headset.

---
Tags: audio, hc-05, baud-rate
---


title: Receiving i2c bytes on an attiny85

text:
# Question
Title: Receiving i2c bytes on an attiny85
I've been trying to write a small i2c lib in C over the past week. I managed to get writing to slaves working (for example I can write to an ssd1306 oled) but reading (for example date/time from an ds3231) never works as my slaves don't seem to set SDA high when I request bytes.

```
uint8_t
i2c_read(uint8_t ack)
{
    uint8_t i, val;

    val = 0;
    cbi(SCL);
    DDRB &= ~(1 << SDA); /* Use SDA for input. */
    cbi(SDA); /* We need to pull down SDA to receive input. */

    /* Read 8bit from the slave. */
    _delay_us(DELAY);
    for (i = 0; i < 8; ++i) {
        sbi(SCL); /* Request one more bit. */
        _delay_us(DELAY); /* Wait a little so the slave can send his answer. */
        if (PORTB & (1 << SDA)) { /* Here the slave should have set SDA to 1 but it never does. */
            PORTB |= (1 << PB4);
            val = (val << 1) | 1;
        } else {
            val = (val << 1);
        }
        cbi(SCL);
        _delay_us(DELAY);
    }

    /* Send back an ACK or NAK. */
    DDRB |= 1 << SDA; /* Use SDA for writing. */
    if (ack)
        cbi(SDA); /* Set SDA to 0 to send ACK. */
    else
        sbi(SDA); /* Set SDA to 1 to send NAK. */

    sbi(SCL);
    _delay_us(DELAY);
    cbi(SCL);
    cbi(SDA);

    return val;
}

```

I set PB4 with to 1 when a slave actually sends a 1. Apparently that never happens. I also had a look at how the various other libs out there do it but I didn't spot anything that would make a difference.

Any clues on what I migth be missing? Before reading my program sends the slave address to the bus. Also: please don't tell me to use other libraries since this is a learning project.

# Answer
> 1 votes
Not sure, if this is the only problem, but you are reading from the wrong register.

There are 3 registers associated with a digital output pin: DDR, PORT and PIN. To read a pin, you need to read from the PIN register. Currently you are reading the PORT register, which will only ever have the value, that you set it to (zero in this case, because you cleared the bit beforehand with `cbi(SDA);`). When you configure the pin as input with the DDR register, the PORT register determines, if the internal pullup resistor is activated or not, so it cannot reflect the actual state of the pin. For this you need the PIN register.

---

Besides that, you might want to look into another thing, that might or might not be a problem in your case: I2C is an open drain bus, meaning, that it is driven actively low and passively high (through pullup resistors). I guess you already have external pullup resistors on your lines, so that you really can deactivate the internal pullup without breaking the communication. But imagine the following situation: The slave get's a request, but cannot clock it out that fast (for whatever reason). It can pull the clock to LOW, until it is ready to push out the data bit, slowing down the clock speed. (This can be done for every bit, unless you are in highspeed mode, then only before the start of a new byte). (This behavior is called clock stretching - Thanks to Edgar for the information) You don't monitor the line, so it can happen, that you drive the clock line actively to high, before the slave has released it. This results in a significant current between master and slave, since the master drives actively high and slave actively low.

There are implementations of I2C communication, that are just doing that and are working fine in most situations. I just wanted to give you this information. And if you at some point want to implement bus arbitration (to allow a multi-master setup), you definitely need this open drain behaviour.

---
Tags: i2c, c, attiny85
---


title: Weird Arduino Code Problem

text:
# Question
Title: Weird Arduino Code Problem
I'm currently getting started with Arduino, so I do not have very much knowledge. In this project I have a receiver and a transmitter with 2 buttons. So, I'd like to switch something to on, when I press the A button. If A is pressed longer I'd like something else to happen. Same thing goes on with the B button, but for some reasons, when I long press A, then B gets triggered and I have no clue why...

Btw. this code is not purely made by me, but copied and edited for my use. If anyone could help me I'd be very happy :)

code:

```
//ButtonAEvents

long prevA = 0;
long prevB = 0;
int buttonStateA = 0; // 0 = not pressed   --- 1 = long pressed --- 2 short pressed
int buttonStateB = 0; // 0 = not pressed   --- 1 = long pressed --- 2 short pressed
int ButtonAPin = 2;
int ButtonBPin = 3;
int DURATION_A_IN_MILLIS = 1000;
int DURATION_B_IN_MILLIS = 1000;

//ONE TIME SETUP

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

//LOOP BEGIN

void loop()
{

    //BUTTON A CHECK
    buttonStateA = 0;
    if (digitalRead(ButtonAPin)) {
        prevA = millis();
        buttonStateA = 1;
        while ((millis() - prevA) <= DURATION_A_IN_MILLIS) {
            if (!(digitalRead(ButtonAPin))) {
                buttonStateA = 2;
                break;
            }
        }
    }

    if (!buttonStateA) {
        // Nothin pressed
    }
    else if (buttonStateA == 1) {
        //LONG PRESS

        Serial.println("LongpressA");
        digitalWrite(A1, HIGH);
        delay(100);
    }
    else if (buttonStateA == 2) {
        //SHORT PRESS
        digitalWrite(A1, HIGH);
        Serial.println("ShortpressA");
        delay(100);
    }

    //BUTTON B CHECK
    buttonStateB = 0;
    if (digitalRead(ButtonBPin)) {
        prevB = millis();
        buttonStateB = 1;
        while ((millis() - prevB) <= DURATION_B_IN_MILLIS) {
            if (!(digitalRead(ButtonBPin))) {
                buttonStateB = 2;
                break;
            }
        }
    }

    if (!buttonStateB) {
        // Nothin pressed
    }
    else if (buttonStateB == 1) {
        //SHORT PRESS

        Serial.println("LongpressB");
        delay(100);
    }
    else if (buttonStateB == 2) {
        //LONG PRESS
        digitalWrite(A1, LOW);
        Serial.println("ShortpressB");
        delay(100);
    }
}

```

# Answer
> 1 votes
Not sure if this is just an academic exercise on your part to learn (which is totally cool), but if you're just trying to move forward and get something working you may consider one of the many excellent button libraries out there for Arduino.

I recently used a library called ButtonKing that allowed me to do some very sophisticated menu interactions on a MKR1010 with a display and single button interface. There are several other libraries out there as well that take care of debouncing, long clicks, double clicks, etc.

---
Tags: programming, arduino-ide
---


title: Pressure Gauge analog reading via RS232

text:
# Question
Title: Pressure Gauge analog reading via RS232
I am trying to read the analog signal from a Pfeiffer TPG 261 Single Gauge (https://www.idealvac.com/files/brochures/Pfeiffer\_Single\_Gauge\_TPG261.pdf)

The pin assignment of the connector I am using is the following:

Here is the circuit I have built:

And here is the code used:

```
int pressureSensorPin = A0;

int analogValueP = 0;

void setup(void)
{
  Serial.begin(9600);
}
void loop()
{
  analogValueP = analogRead(pressureSensorPin);
  Serial.println(analogValueP);
  delay(1000);
}

```

Unfortunately the ouput I get with such a build is only 0 with now and then a 1023.

Any idea of what I am doing wrong ?

# Answer
> 4 votes
You have a misconception, which signals get's outputted where. If you want to simply read the analog signal of the sensor, you need to use the "control" connector. There you can find the analog signal on pin 2. But this analog signal goes up to 10V, so you need a voltage divider between the sensor and the Arduino, to divide the voltage down to 5V max.

Currently you are using the RS232 connector. RS232 is a communication standard, which transmits digital data, not analog data. Thus you read only digital values (min voltage and max voltage, nothing inbetween). You can use it do talk with the sensor, change configuration settings and reading data digitally. But to actually do this, you need to consider 2 important things:

1. RS232 is an interface, which involves it's own voltage levels (namely +-12V), which do not fit the TTL level (0 - 5V) that the Arduino Uno uses. You can very well destroy your Arduino by connecting it directly to RS232. For making this work, you need a level converter chip (I think the MAX232 is commonly used for this), to convert the voltage levels to TTL logic. From there on this communication is normally called UART.
2. You need to understand and then implement the sensors communication protocol (when to send what data), so that the sensor and Arduino are understanding each other

---

For me it seems, that the analog signal from the "control" connector is all, that you currently need, so for simplicity you can use this. RS232 is used for more control over the functionality of the sensor.

---
Tags: arduino-uno, rs232
---


# Question
Title: How can I connect 6 solenoid locks to an arduino
Im in college and our research is about a fingerprint based door lock system. We really dont have any idea about arduino. Now we bought arduino mega for our research but I dont know how to connect all 6 solenoid locks to an arduino. Please help It would be very much appreciated if you answer and it will be very helpful to us. I know there are same research about this in the internet but i cant find any of these. If you have any website about this research it would be very helpful. Thanks

# Answer
Supposing the lock you use is a simple solenoid that works with 12V, you should connect them to the output of a relay module, and then connect the Arduino to the module. Like this example here: link.

You will probably want to connect each solenoid to an individual relay, so you can activate each one of them individually. With that in mind you might want to use an 8-channel relay module like DataFiddler recommended. example

You will need a 12V power supply, and be sure to check the current drawn from your solenoids and see if the power supply can handle it.
> 3 votes

# Answer
To follow up on CrossRoads' suggestion of a power MOSFET circuit, there is more detail on how to do it in an answer over in the Electrical Engineering group. Digikey.com is a great source for components.

https://electronics.stackexchange.com/questions/29065/how-to-control-a-12v-solenoid-valve-with-a-mosfet
> 1 votes

# Answer
You aren't going anywhere without external drivers. The Arduino simply can't output that much current. 8 channel drivers are widely available. Remember to connect an external power source.
> -1 votes

---
Tags: wifi, c, spi
---


# Question
Title: Is there a way to add external RAM (let's say 100 MB or 200 MB) in this audio buffer mixing context?
I'm coding a music sampler device: for fast playback / minimal latency (only a few milliseconds), it's better to have all audio .wav samples we want to use in RAM, so that when some of them are played, the data arrays are immediately accessible. That's what I did for a Raspberry Pi project called SamplerBox. It was possible because RPi had 1 GB RAM.

Note: When using SDcard reading, and playing many notes at the same time (imagine a pianist playing a big chord), it's usually not good in terms of latency.

Now I'm thinking about porting this project to Arduino: in which extent can we add external RAM to an ATmega? Or if not "RAM", some volatile memory (let's call it "RAM2") that would be 10 times faster than reading an SD card.

What I'd like to achieve:

* load 200 MB of audio samples into the "RAM2"
* Max polyphony allowed = 100, so at a given time, all audio buffers that have to be mixed can be copied from "RAM2" to the "real" RAM of the microcontroller, and the mixing will be done with the (maximum 100 of them) buffers in the real RAM

# Answer
There are SRAM ICs / boards, however, don't expect 100 MB, more like 1 MB (with the pin numbers and connectivity / protocols that an Arduino offers).

With Flash you can get much further, but it can only be written a number of times; not sure if that suits your requirements.

Beyond that, I'm afraid the real problem is in the processing speed. Mixing 100 samples with 48 KHz stero would mean (48000 * 2) = 96 KSamples/s. Since the Arduino is only 16 MHz you have just 16e6/96e3 = 166 clock cycles to mix all those 100 samples. Probably way too less.

**Update**

Winbond is a brand that is supported by Arduino libraries and the biggest supported IC is e.g. W25Q128FVSSIG, which is 128 Mbit, thus 8 MB. For 200 MB you need 25 of them which is quite a lot, and not sure if there will be issues using so many (let alone the cost). For this you do not need a file system, however you need to write it per page (if you want to do it efficiently). Which should be ok, since the SD card also is read per page (maybe not the same page size though). However, you still have to copy the Flash memory into SRAM to be able to process it, so it's not the same as SRAM. Getting 200 MB SRAM will be very costly.
> 5 votes

# Answer
I'd also suggest looking into different microprocessors. The Teensy models often have an SD card socket, and the Teensy 4 (especially if they release one with a built-in SD socket) is extremely fast and capable (600MHZ, dual instructions/cycle). That would be far better suited than an Arduino, though you'll still have RAM limits. (Nowhere near 200 megs, but you'd have slightly less of an issue than with the Arduino's mere 2-8K of RAM. These have a few hundred K up to maybe a couple MB (note that I'm not sure if it actually goes that high))

There's also the RPI Zero, Zero W, and Compute Module to try using. Those are the Raspberry Pi system you are used to using at a low-ish cost or easily-integrated form factor.

In short, to do audio processing, you also need a better processor than a stock Arduino probably has. Lots of RAM is the easy-to-see issue, but having the computing power to do something with it is also important.

Do note that the Winbond chips mentioned in the other answer ARE a flash memory, so they may go bad on you if they see a lot of writes.
> 1 votes

---
Tags: atmega328, memory-usage, sram
---