# Question
Title: ESP32 preferences. One error returned, all others work. SOLVED
I am using the Preferences.h library in my Arduino code. I initialize some values. I save them with the preference library. I then modify all the values, then read back the original saved values.

All the values, **except one**, are restored with the associated get instruction. The one still shows the modified value. I can't see why it is wrong.

Can someone point out my error with calibratedWeight? And if you see some other general errors with the code, please point them out. (I'm not a programmer)

```
#include <Preferences.h>

Preferences preferences;

int currentFile = 1;
int outputRate = 10;           // milliSeconds
float outputGain = 1.23;
int zeroWeight = 900;          // dac value to produce Zero on scale
int calibratedWeight = 2800;   // dac value equal to 100lb calibration weight.
float DACmultiplier = 20.1;

//---------------------------------------
void savePreferences() {
    preferences.begin("ScaleSetup", false);      // false for read/write
    preferences.putInt("currentFile", currentFile);
    preferences.putInt("outputRate", outputRate);
    preferences.putFloat("outputGain", outputGain);
    preferences.putInt("zeroWeight", zeroWeight);
    preferences.putInt("calibratedWeight", calibratedWeight);  // ???
    preferences.putFloat("DACmultiplier", DACmultiplier);
    preferences.end();
}

//---------------------------------------
void getPreferences() {
    preferences.begin("ScaleSetup", false);        // false for read/write

    currentFile = preferences.getInt("currentFile", currentFile);
    outputRate = preferences.getInt("outputRate", outputRate);
    outputGain = preferences.getFloat("outputGain", outputGain);
    zeroWeight = preferences.getInt("zeroWeight", zeroWeight);
    calibratedWeight = preferences.getInt("calibratedWeight", calibratedWeight);  // ???
    DACmultiplier = preferences.getFloat("DACmultiplier", DACmultiplier);
    preferences.end();
}

//============================================
void setup() {
  Serial.begin(115200);
  Serial.println();

  preferences.begin("ScaleSetup", false);        // false for read/write
  preferences.clear();
  preferences.end();
  delay(90);

  savePreferences();
  Serial.println("\n save preferences");
  Serial.println("\n Original asigned values. \n");

  Serial.printf("currentFile: %i\n", currentFile);
  Serial.printf("outputRate: %i\n", outputRate);
  Serial.printf("outputGain: %f\n", outputGain);
  Serial.printf("zeroWeight: %i\n", zeroWeight);
  Serial.printf("calibratedWeight: %i\n", calibratedWeight);  // ???
  Serial.printf("DACmultiplier: %f\n", DACmultiplier);

  Serial.println("\n modify values. \n");

  currentFile = 5;
  outputRate = 50;           // milliSeconds
  outputGain = 0.45;
  zeroWeight = 1333;         // dac value to produce Zero on scale
  calibratedWeight = 2200;   // dac value equal to 100lb calibration weight.
  DACmultiplier = 12.34;

  Serial.printf("currentFile: %i\n", currentFile);
  Serial.printf("outputRate: %i\n", outputRate);
  Serial.printf("outputGain: %f\n", outputGain);
  Serial.printf("zeroWeight: %i\n", zeroWeight);
  Serial.printf("calibratedWeight: %i\n", calibratedWeight);  // ???
  Serial.printf("DACmultiplier: %f\n", DACmultiplier);

  Serial.println("\n Get original saved preferences. \n");
  getPreferences();

  Serial.printf("currentFile: %i\n", currentFile);
  Serial.printf("outputRate: %i\n", outputRate);
  Serial.printf("outputGain: %f\n", outputGain);
  Serial.printf("zeroWeight: %i\n", zeroWeight);
  Serial.printf("calibratedWeight: %i\n", calibratedWeight);  // ???
  Serial.printf("DACmultiplier: %f\n", DACmultiplier);

//  Serial.println("Restarting in 10 seconds...");
  delay(10000);
//  ESP.restart();
}

//============================================
void loop() {}

```

The following is the result.

```
 save preferences

 Original asigned values.

currentFile: 1
outputRate: 10
outputGain: 1.230000
zeroWeight: 900
calibratedWeight: 2800
DACmultiplier: 20.100000

 modify values.

currentFile: 5
outputRate: 50
outputGain: 0.450000
zeroWeight: 1333
calibratedWeight: 2200
DACmultiplier: 12.340000

 Get original saved preferences.

currentFile: 1
outputRate: 10
outputGain: 1.230000
zeroWeight: 900
calibratedWeight: 2200
DACmultiplier: 20.100000

```

# Answer
> 1 votes
At the end of the comments above I said I thought the problem was with the variable name length.

Today I tried the debug option and then ran the code. And the following error message was included in the com output.

\[E\]\[Preferences.cpp:163\] putInt(): nvs\_set\_i32 fail: calibratedWeight **KEY\_TOO\_LONG**

So I guess I was right. I didn't know anything about the debug option before.

---
Tags: esp32, code-review
---


# Question
Title: Error 101 Server Did Not Report Size from OTA Upgrade framework via git hub
I have tried this video:

ESP8266 Self Update OTA from GitHub

Instruction and made this GitHub repo:

And changed the main code to this type, but I get this error:

```
HTTP_UPDATE_FAILD Error (-101): Server Did Not Report Size

```

when the  `FirmwareUpdate();` code is running. So I don't know why GitHub don't answer to the esp8266, as said here:

> The error has nothing to do with your sketch. Also, the error code is not a HTTP 101 error. The problem is that your server does not send the response header 'Content-Length'

I have some dupt about the bin URL file address which have many dot on the end of it (`https://github.com/soheilpaper/ota_github_blink/blob/main/BlinkWithoutDelay.ino.esp8285.bin`) on it, could it be the reason for none answering and giving the 101 code form GitHub server!

Any suggestion would be good help to fix this bug.

**Update 1:**

> I have changed the bin file name to this kind :
>
> ```
>  BlinkWithoutDelay.ino.esp8285.bin  ---->      BlinkWithoutDelay_ino_esp8285.bin
>
> ```
>
> But I have again the same GitHub 101 error.

**Update 2:**

Based on the timemage answer, I have changed the address of `bin` and `TXT` file by finding the download link of those files form the GitHub. And it has been working by changing the `blob` part of address to `raw`, so the bin address changed form `https://github.com/soheilpaper/ota_github_blink/blob/main/BlinkWithoutDelay_ino_esp8285.bin` to `https://github.com/soheilpaper/ota_github_blink/raw/main/BlinkWithoutDelay_ino_esp8285.bin` And the `https://github.com/soheilpaper/ota_github_blink/blob/main/version.txt`to `https://raw.githubusercontent.com/soheilpaper/ota_github_blink/main/version.txt`

And now that error has been fixed as you can see below:

Although I gave some dupt about upgrading the main code by getting this output via serial port:

```
Device already on latest firmware version

```

And I would check it after some resting!.

Thanks.

# Answer
> 2 votes
The ESP8266httpUpdate library wants to know in advance how large the file is before it starts downloading it. It wants to know this so it can tell, before trying to download (and program), whether or not there's enough space for it. If the size of the file isn't provided by the server it will report the error that you are seeing.

The size of the file is provided by the web server by means of the Content-Length HTTP response header read by HTTPClient. This header is received in advance of the file content.

Your main code appears to contain a correct link to raw .bin file, `#define URL_fw_Bin "https://raw.githubusercontent.com/programmer131/otaFiles/master/firmware.bin"`, and reports the following headers:

```
cache-control: max-age=300
content-security-policy: default-src 'none'; style-src 'unsafe-inline'; sandbox
content-type: application/octet-stream
etag: "b2ecfb5dc91587c089acdaace446b0d7b00863c9f42dffb36c7983c103d3a98a"
strict-transport-security: max-age=31536000
x-content-type-options: nosniff
x-frame-options: deny
x-xss-protection: 1; mode=block
via: 1.1 varnish (Varnish/6.0), 1.1 varnish
x-github-request-id: 8728:2B67:9AFD3:AD0EC:6008FCFF
accept-ranges: bytes
date: Thu, 21 Jan 2021 04:03:32 GMT
x-served-by: cache-bos4651-BOS
x-cache: MISS, HIT
x-cache-hits: 0, 1
x-timer: S1611201812.154162,VS0,VE1
vary: Authorization,Accept-Encoding
access-control-allow-origin: *
x-fastly-request-id: bfc9702929b91be55d7aa040465a230436918e01
expires: Thu, 21 Jan 2021 04:08:32 GMT
source-age: 20
content-length: 270016

```

The **content-length: 270016** at the bottom shows that this should work. But your changed code that uses `#define URL_fw_Bin "https://github.com/soheilpaper/ota_github_blink/blob/main/BlinkWithoutDelay_ino_esp8285.bin` is to the HTML page for downloading the file, which does **not** report `Content-length`, for me anyway, but then it's the wrong URL anyway.

Regarding the "101 error", it's `-101` (negative) defined here, and like they said, it is not an HTTP status code, it is just a value used by the ESP8266httpUpdate library.

---
Tags: web, ota
---


title: Not able to upload code to NodeMCU

text:
# Question
Title: Not able to upload code to NodeMCU
Im now working on a Node MCU based project but the problem is that i cannot upload the code to the board. Further more whenever i connect the usb to the NodeMCU my keyboard stops working and only works again after i turn off and on my pc this happens whenever i disconnect and connect the Node MCU. The error is COM port is not found or board is not connected and sometimes after i disconnect the Node MCU my system gives a message The Last USB device malfunctioned Can anyone help I'm using a basic NodeMCU 12E CP2021??

# Answer
I'd check 3 things:

1. If it's a specific USB port/cable problem, not related to the NodeMCU itself (your said it interacted with your USB keyboard, what makes sense if it's a computer-usb issue). Try to connect the NodeMCU to a different USB port/hub in your computer using another USB cable.
2. Of course it could be a USB-Serial driver issue. Please make sure what chip is used on your NodeMCU (CH340 or CP1202) and make sure the correct driver is installed.
3. Most important - you must make sure your Serial pins on the NodeMCU (TX, RX) are not connected to anything during program upload. They are bridged to the Serial connection that is coming from the computer (through the USB-to-Serial chip) and interact and interfere with them.

Good luck!
> 1 votes

---
Tags: serial, nodemcu, uploading, serial-data, upload
---


# Question
Title: How to put Arduino Nano in low power sleep mode (<0.05mA)
I'm trying to put an Arduino Nano in low-power mode using this guide: Arduino Low Power - How To Run ATmega328P For a Year On Coin Cell Battery.

The article suggests 3 things: use the Low-Power library from Rocketscream, cut the power to the power LED, and remove the voltage regulator.

So far I've only done the first two and reduced the clock speed to 8 MHz.

The important part of the source code that puts the Arduino in deep sleep looks like this:

```
void setup() {
  CLKPR = 0x80; // (1000 0000) enable change in clock frequency
  CLKPR = 0x01; // (0000 0001) use clock division factor 2 to reduce the frequency from 16 MHz to 8
}

void loop() {
  // Go to sleep until the next scheduled wake up
  int32_t waitSeconds = 60;
  while (waitSeconds > 0) {
    period_t waitFor = SelectWaitTime(waitSeconds);
    LowPower.powerDown(waitFor, ADC_OFF, BOD_OFF);
    waitSeconds -= PeriodToSeconds(waitFor);
  }
}

period_t SelectWaitTime(int32_t secondsToWait) {
  if (secondsToWait >= 8)
    return SLEEP_8S;
  else if (secondsToWait >= 4)
    return SLEEP_4S;
  else if (secondsToWait >= 2)
    return SLEEP_2S;
  else if (secondsToWait >= 1)
    return SLEEP_1S;
}

```

In essence, sleep for up to 8 seconds, remove the seconds from the counter, then sleep again.

So far I've only scratched off the trace to the power LED and haven't removed the voltage regulator. According to the article above, this should reduce the power consumption to around 0.05 mA but I get around 1.7 mA, which is over 30 times more!

Electrically, I only have a MOSFET as a power switch connected to one of the analog pins (I use it as a digital output) and another controller, connected to the I2C pins (the Arduino acts as Slave). The other controller is turned off through the MOSFET when I take the measurements. Physically removing the connections doesn't change the consumption, so I don't think any of that is related.

Is there something I did wrong? What can I do to achieve power consumption similar to the one in the article?

# Answer
Turns out the voltage regulator was AMS1117 - not MIC5205-KB50/KB33/KBAA like the one in the article. Ripping it off gave me the 0.026 mA idle current which is even better than what I was hoping for.
> 3 votes

---
Tags: arduino-nano, power, i2c
---


title: Push button restarts the arduino

text:
# Question
Title: Push button restarts the arduino
I have linked an external push red colored button to my arduino but when I press it, instead of giving me HIGH or LOW, it resets the arduino. I am a beginner to this stuff so could someone help?

# Answer
If your button creates a short circuit between 5V and GND pins... it will certainly act like a RESET. Let's try to make sure you are not creating a dead short on an Arduino pin so you avoid prematurely killing your controller.
> 5 votes

---
Tags: button
---


title: 7-segment displays are not working

text:
# Question
Title: 7-segment displays are not working
```
/*
MODIFIED TRAFFIC LIGHT SYSTEM W/ A COUNTDOWN TIMER FUNCTION
BY JOHN SEONG

THIS IS A QUITE ACCURATE SIMULATION OF TORONTO'S TRAFFIC LIGHT SYSTEM
WHICH INCLUDES TWO 7-SEGMENT DISPLAYS THAT SHOW THE SECONDS LEFT
TILL THE PEDESTRIAN LIGHT SWITCHES BACK TO RED.

ENJOY!
*/

const int redLED = 4;
const int yellowLED = 5;
const int greenLED = 6;
const int pedestrianRedLED = 13;
const int pedestrianGreenLED = A5;
const int buzzer = 12;
const int button = 7;

int segmentPins[] = {11, 10, 9, 8};

int buttonHitCount = 0;

void setup() {

  Serial.begin(9600);

  // Car Traffic LEDs
  pinMode(redLED, OUTPUT);
  pinMode(yellowLED, OUTPUT);
  pinMode(greenLED, OUTPUT);

  // Pedestrian Traffic LEDs
  pinMode(pedestrianRedLED, OUTPUT);
  pinMode(pedestrianGreenLED, OUTPUT);

  // 7-Segment Display Pins
  pinMode(2, OUTPUT);
  pinMode(3, OUTPUT);
  pinMode(11, OUTPUT);
  pinMode(10, OUTPUT);
  pinMode(9, OUTPUT);
  pinMode(8, OUTPUT);

  // Piezo Speaker Pin
  pinMode(buzzer, OUTPUT);

  // Pedestrian Push Button
  pinMode(button, INPUT_PULLUP);

  displayNumber(9, 2);
  displayNumber(9, 3);
}

void loop() {

  // Read the state of the button
  int buttonState = digitalRead(button);

  Serial.println(buttonState);

  if (buttonState == LOW) {
    buttonHitCount = 1;
  }

  if (buttonHitCount == 1) {
    switchToRed();

  } else if (buttonHitCount == 0) {
    defaultState();
  }
}

void displayNumber(int num, int displayPin) {

  bool binaryValue[][4] = {
    {0, 0, 0, 0}, // 0
    {0, 0, 0, 1}, // 1
    {0, 0, 1, 0}, // 2
    {0, 0, 1, 1}, // 3
    {0, 1, 0, 0}, // 4
    {0, 1, 0, 1}, // 5
    {0, 1, 1, 0}, // 6
    {0, 1, 1, 1}, // 7
    {1, 0, 0, 0}, // 8
    {1, 0, 0, 1}, // 9
  };

  for(int i = 0; i < 4; i++) {
    digitalWrite(segmentPins[i], binaryValue[num][i]);
  }

  digitalWrite(displayPin, HIGH);
  delayMicroseconds(10);

  digitalWrite(displayPin, LOW);
}

void switchToRed() {

  delay(5000);

  // YELLOW
  digitalWrite(yellowLED, HIGH);
  digitalWrite(redLED, LOW);
  digitalWrite(greenLED, LOW);
  delay(2000);

  // RED
  digitalWrite(redLED, HIGH);
  digitalWrite(greenLED, LOW);
  digitalWrite(yellowLED, LOW);

  // GREEN
  digitalWrite(pedestrianGreenLED, HIGH);
  digitalWrite(pedestrianRedLED, LOW);

  switchToGreen();
}

void switchToGreen() {

  // 15
  noTone(buzzer);
  displayNumber(1, 2);
  displayNumber(5, 3);
  tone(buzzer, 1000);
  delay(1000);

  // 14
  noTone(buzzer);
  displayNumber(1, 2);
  displayNumber(4, 3);
  tone(buzzer, 1000);
  delay(1000);

  // 13
  noTone(buzzer);
  displayNumber(1, 2);
  displayNumber(3, 3);
  tone(buzzer, 1000);
  delay(1000);

  // 12
  noTone(buzzer);
  displayNumber(1, 2);
  displayNumber(2, 3);
  tone(buzzer, 1000);
  delay(1000);

  // 11
  noTone(buzzer);
  displayNumber(1, 2);
  displayNumber(1, 3);
  tone(buzzer, 1000);
  delay(1000);

  // 10
  noTone(buzzer);
  displayNumber(1, 2);
  displayNumber(0, 3);
  tone(buzzer, 1000);
  delay(1000);

  // 9
  noTone(buzzer);
  displayNumber(0, 2);
  displayNumber(9, 3);
  tone(buzzer, 1000);
  delay(1000);

  // 8
  noTone(buzzer);
  displayNumber(0, 2);
  displayNumber(8, 3);
  tone(buzzer, 1000);
  delay(1000);

  // 7
  noTone(buzzer);
  displayNumber(0, 2);
  displayNumber(7, 3);
  tone(buzzer, 1000);
  delay(1000);

  // 6
  noTone(buzzer);
  displayNumber(0, 2);
  displayNumber(6, 3);
  tone(buzzer, 1000);
  delay(1000);

  // 5
  noTone(buzzer);
  displayNumber(0, 2);
  displayNumber(5, 3);
  tone(buzzer, 1000);
  delay(1000);

  // 4
  noTone(buzzer);
  displayNumber(0, 2);
  displayNumber(4, 3);
  tone(buzzer, 1000);
  delay(1000);

  // 3
  noTone(buzzer);
  displayNumber(0, 2);
  displayNumber(3, 3);
  tone(buzzer, 1000);
  delay(1000);

  // 2
  noTone(buzzer);
  displayNumber(0, 2);
  displayNumber(2, 3);
  tone(buzzer, 1000);
  delay(1000);

  // 1
  noTone(buzzer);
  displayNumber(0, 2);
  displayNumber(1, 3);
  tone(buzzer, 1000);
  delay(1000);

  noTone(buzzer);

  // YELLOW
  digitalWrite(yellowLED, HIGH);
  digitalWrite(redLED, LOW);
  digitalWrite(greenLED, LOW);
  delay(2000);

  // GREEN
  digitalWrite(redLED, LOW);
  digitalWrite(greenLED, HIGH);
  digitalWrite(yellowLED, LOW);

  // PEDESTRIAN - RED
  digitalWrite(pedestrianGreenLED, LOW);
  digitalWrite(pedestrianRedLED, HIGH);

  // Reset the value
  buttonHitCount = 0;
}

void defaultState() {

    // GREEN
    digitalWrite(greenLED, HIGH);
    digitalWrite(yellowLED, LOW);
    digitalWrite(redLED, LOW);

    // PEDESTRIAN - RED
    digitalWrite(pedestrianRedLED, HIGH);
    digitalWrite(pedestrianGreenLED, LOW);
}

```

Clearly something is wrong with my code and the 7-segment displays are off the whole time the program is running. I also posted a link below which directs to the tinkercad project I made.

https://www.tinkercad.com/things/7pnnbXoaqrG-improved-stop-light-john-seong/editel?sharecode=jR86i\_srV7QgP11u1CxOFzeVwehzjIRr8wCC7vbbLaY

# Answer
> 0 votes
Not really a solution, but changing the code for the `displayNumber` function as shown below, will make it more apparent where the real problem is.

```
void displayNumber(int num, int displayPin) {

  bool binaryValue[][4] = {
    {0, 0, 0, 0}, // 0
    {0, 0, 0, 1}, // 1
    {0, 0, 1, 0}, // 2
    {0, 0, 1, 1}, // 3
    {0, 1, 0, 0}, // 4
    {0, 1, 0, 1}, // 5
    {0, 1, 1, 0}, // 6
    {0, 1, 1, 1}, // 7
    {1, 0, 0, 0}, // 8
    {1, 0, 0, 1}, // 9
  };

  // turn off both displays
  digitalWrite(2, LOW);
  digitalWrite(3, LOW);

  for(int i = 0; i < 4; i++) {
    digitalWrite(segmentPins[i], binaryValue[num][i]);
  }

  digitalWrite(displayPin, HIGH);
  /* // remove these two lines
  delayMicroseconds(10);
  digitalWrite(displayPin, LOW);
  */
}

```

---
Tags: arduino-uno, 7-segment
---


# Question
Title: How to add the previous value to current value from sensor
```
const byte interruptPin = 4;
void ICACHE_RAM_ATTR count();
void setup() {
  Serial.begin(115200);

  // Set up our digital pin as an interrupt
  pinMode(interruptPin, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(interruptPin), count, RISING);
}

void loop() {

}

void count() {
  volatile float rainrate = 3;
  volatile float rate;
  volatile float total;

  rate = rainrate * 0.1;
  Serial.println(rate);

```

Every time it tips, it returns 0.3. How do I add the previous value(0.3) to a new tip, to make it 0.6, and save it into a variable.

Thanks!

# Answer
Btw, you can make the `volatile` variables global, by putting them above `void Setup`.

To put the total (new) value, use:

```
total += <sensorValue>;

```

where `<sensorValue>` is a call to get the sensorValue (or the value that has the sensor value stored in it), but I cannot see that in your sketch.

```
total += 0.3;

```

is the same as writing:

```
total = total + 0.3;

```

The value right of the '='sign is copied (assigned) to the left part of the '=' sign.
> 0 votes

# Answer
Why bother doing that arithmetic at every tip, when you could just count tips, and multiply the count by 0.3 whenever a result is needed?

`tips += 1; // each time the bucket tips.`

and

`Serial.println(0.3 * tips); // each time you want a result`
> 0 votes

---
Tags: datalogging
---


# Question
Title: ESP8266-01E is not responding after successful flash
I have flashed an ESP8266 with the ESP8266 flash downloader that said my flashing had succeeded.

But when I sent an AT command from the serial monitor it didn't respond and the TX/RX LED from the ESP8266 didn't respond either. I checked all baudrates from 300-200000, but nothing.

I was using CH340 USB to TTL for flashing wired like this:

```
USB -> ESP8266
3,3v ->CH_PD and VCC
GND -> GND and GPI0 (only when flashing)
TX -> RX
RX -> TX

```

I was flashing to downgrade the firmware; the default firmware from shop was SDK 1.5.4, AT VERSION 1.1.0.0.

I have been frustrated with this, because this is my second module.

# Answer
SOLVED

My module is esp8266-01S, i need to set the SPI MODE to DOUT, BAUDRATES=115200, SPI SPEED 40MHz and the software is NODEMCU FLASHER.

The important keyword is "DOUT".

I have been flash many times but with not DOUT SPI METHOD. I thought change it will not fix that. I was using QIO SPI MODE but it doesn't work.
> 1 votes

---
Tags: esp8266, firmware
---


# Question
Title: Cannot display a chr string using Wire.read() and u8g2.drawStr()
I'm still getting myself acquainted with C++, so I expect this is a very basic issue I'm facing. I've got an OLED screen connected to a Teensy LC and can display text on it just fine. The Teensy receives bytes via I2C, and I want to reassemble those bytes into strings and display them on the OLED.

My relevant code:

```
#define I2C_ADDRESS 4
char buf[16];

void setup(void) {
  Serial.begin(9600);
  Wire.begin(I2C_ADDRESS);
  Wire.onReceive(receiveData);
  u8g2.begin();
}
void loop(void) {
  // U8G2 setup code snipped
  // This line doesn't output anything on the screen:
  u8g2.drawStr(0, 0, buf);
  // This line does:
  u8g2.drawStr(0, 20, "Foobar!");
  u8g2.sendBuffer();
  delay(1000);
}

void receiveData(int byteCount){
  Serial.print("Data received: ");
  int i;
  for (i=0; i<byteCount; i++)
  {
    buf[i] = Wire.read();
    Serial.println(buf[i]);
  }
  buf[i] = '\0';
  Serial.println(buf);
}

```

In the receiveData() function, the Serial.println() within the for loop prints out each letter of the payload as it's received, one after the other - but the Serial.println() below the for loop, which in my estimation should print out the whole message, prints out a blank line. I presume that's related to the fact that the received string doesn't show up on the OLED display.

# Answer
> 2 votes
This is kind of convoluted to put as a comment and it is *sort of* an answer, so I'm making it *an* answer. Just to warn you, I have not tried to compile any of the code snippets here.

`Wire.onReceive(receiveData);` registers your function so that it can be later called back in the context of the interrupt service routine used for handling I2C ("Wire") data. Or at least this is how it usually works. So when your `receiveData` function is running you are in the middle of handling an interrupt associated with the I2C peripheral.

Using `Serial.print()`, `.println()`, `.write()`, and many other things, including non-serial related things like `delay()` inside of an interrupt service is usually a no-no. On the AVR Arduino core, if the outbound serial buffer happens to fill, your code will deadlock with the underlying `.write()` waiting for there to be room in the outbound serial buffer and the serial transmit interrupt waiting for `.write()` to get done waiting for it. I don't know how the Teensy LC and its MCU are configured, whether or not it prioritizes interrupts, etc, but it is likely that you're still not supposed to call functions like these inside the interrupt context.

There's really not a lot you're supposed to do in an ISR except:

* communicate with hardware (which is being done for you here)
* manage the non-`volatile` variables that belong to the ISR itself.
* set global `volatile` qualified variables to communicate with the main line of execution.
* call functions that have no shared state with the main line of execution.
* call functions that have shared state but are carefully designed to be called from both ISR contexts and main line of execution.

That said, I don't know precisely why you're seeing what you're seeing, but I'm not overly surprised either. The above *may* be related to it, but I haven't drawn that connection yet.

The way you currently have `receiveData`, it may overflow `buf`. All that's required for that is for the sending side to send more than 15 bytes. Any number of weird things can happen if you manage to overflow. Is it related? Maybe.

For communicating between the `receiveData` running in the ISR context and the main line of execution in `loop`, `buf` should be `volatile` qualified. Without that the main line of execution can behave as though `buf` never changes after it is first seen. Because of how you're using it and familiarity with the compiler, I'm going to guess that this isn't manifesting as a bug, but I don't *know* that; it *could* be related.

So I'd recommend updating something like your `buf` declaration to `volatile` qualified and removing the Serial `print` calls from the `receiveData` function, and preventing overflow:

```
volatile char buf[16];

/// ...

void receiveData(int byteCount){
  static const size_t room_for_non_null_chars = sizeof buf - 1;
  const size_t read_amount = min(byteCount, room_for_non_null_chars);

  int i;
  for (i = 0; i < read_amount; ++i) {
    buf[i] = Wire.read();
  }

  buf[i] = '\0';
}

```

If it weren't for the fact that we need to read into something `volatile` qualified the above loop could really just be a `read` call taking the buffer and size. You can see that's updated to prevent overflow.

Part of `loop` would then become something like:

```
void loop() {
  char non_volatile_buf[sizeof buf];
  size_t write_index = 0;

  noInterrupts();
  for (char c: buf) {
    non_volatile_buf[write_index++] = c;
  }
  interrupts();

  // U8G2 setup code snipped
  // This line doesn't output anything on the screen:
  u8g2.drawStr(0, 0, non_volatile_buf);

  // ...

```

We're turning off interrupts while copying the data into a local buffer so that the onReceive handler cannot interrupt the use of the `buf`, updating while you're in the middle of using it in `drawStr`.

If you care about losing messages there's more that would need to be done. Surrounding what to do if you've got a call to `receiveData` while there's a message currently in `buf`. The way the above is written it just drops whatever is in there whether it's been seen by `loop()` or not.

# Answer
> 0 votes
I didn't get a load of sleep last night but I finally figured it out, thanks to timemage's post. I'm concerned that my solution is hyper-specific, but I'd rather share it to save someone the trouble in future.

1. timemage was right in that the buffer should really be `volatile` qualified and that as little processing as possible should happen in what I now understand is an ISR. I couldn't get their code to work, but I eventually stumbled on i2c\_t3, an enhanced I2C library specifically for Teensy 3.0/3.1/LC. Looking at the library's code and especially its basic peripheral example, it looks like it implements similar techniques to those timemage recommended.
2. The other thing I didn't consider was the way the controller was communicating. I was using the smsbus2 Python library, and at one point I changed the address offset from `0x00` to `0x01`. This mysteriously seemed to make the Teensy code work, but I don't know why!

```
data = [1, 2, 3, 4, 5, 6, 7, 8]
bus.write_i2c_block_data(0x21, 0x01, data)

```
3. Lastly, from reading forum posts about saving data to variables from I2C, it looks like a lot of quite simple code that does work on other Arduino devices doesn't work on the Teensy.1 I'd have to get an Arduino device to test this theory, though.

Because I'm a bad scientist, I haven't checked whether any of my original code or timemage's improved code works when I offset the address in the smbus2 code. But for what it's worth, these are the things I did to solve my problem!

---

1. See for example: https://forum.arduino.cc/index.php?topic=570597.0; https://forum.arduino.cc/index.php?topic=619902.0.

---
Tags: c++, i2c, teensy, wire-library, u8glib
---


title: INA219 with L298N POWER LOGGER

text:
# Question
Title: INA219 with L298N POWER LOGGER
I Have been working on a power logger with INA219 and L298N the thing is, the voltage and current displayed on Serial Monitor is not the same on my multimeter. the Arduino is connected to the pc to view the result on the serial

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

Adafruit_INA219 ina219;

//Adafruit_INA219 ina219_A;
//Adafruit_INA219 ina219_B(0x41);

void setup(void)
{
  Serial.begin(115200);
  while (!Serial) {
      // will pause Zero, Leonardo, etc until serial console opens
      delay(1);
  }

  uint32_t currentFrequency;

  Serial.println("Hello!");

  if (! ina219.begin()) {
    Serial.println("Failed to find INA219 chip");
    while (1) { delay(10); }
  }
  ina219.setCalibration_32V_1A();

  Serial.println("Measuring voltage and current with INA219 ...");
}

void data(void)
{
  float shuntvoltage = 0;
  float busvoltage = 0;
  float current_mA = 0;
  float loadvoltage = 0;
  float power_mW = 0;
    delay(2000);
  shuntvoltage = ina219.getShuntVoltage_mV();
  busvoltage = ina219.getBusVoltage_V();
  current_mA = ina219.getCurrent_mA();
  power_mW = ina219.getPower_mW();
  loadvoltage = busvoltage + (shuntvoltage / 1000);

  Serial.print("Bus Voltage:   "); Serial.print(busvoltage); Serial.println(" V");
  Serial.print("Shunt Voltage: "); Serial.print(shuntvoltage); Serial.println(" mV");
  Serial.print("Load Voltage:  "); Serial.print(loadvoltage); Serial.println(" V");
  Serial.print("Current:       "); Serial.print(current_mA); Serial.println(" mA");
  Serial.print("Power:         "); Serial.print(power_mW); Serial.println(" mW");
  Serial.println("");

  delay(2000);
}

void loop() {

    analogWrite(9, 245); //ENA pin
    digitalWrite(8, HIGH);
    digitalWrite(7, LOW);
    data();
    delay(5000);

    analogWrite(9, 200); //ENA pin
    digitalWrite(8, HIGH);
    digitalWrite(7, LOW);
    data();
    delay(5000);

    analogWrite(9, 150); //ENA pin
    digitalWrite(8, HIGH);
    digitalWrite(7, LOW);
    data();
    delay(5000);

    analogWrite(9, 0); //ENA pin
    digitalWrite(8, LOW);
    digitalWrite(7, LOW);
    data();
    delay(5000);

}

```

# Answer
> 1 votes
The INA219 gives you the instantaneous current and voltage at a given moment in time, whereas your DMM shows you the *average* over a period.

The L298N is giving out a PWM waveform that is rapidly being turned on and off.

You see where this is going?

Your Arduino detection will be giving you either full power or no power (or somewhere in between owing to the low-pass filter effect of the motor), pretty much randomly, whereas the DMM will give you the average over a number of samples.

You would need to rapidly sample the PWM signal over a period of time and calculate the average to get an idea of what the current and voltage might be.

---
Tags: arduino-uno, current, voltage, l298n
---


# Question
Title: HTTP-POST returns 400 when posting a value from the sensor
I'm trying to POST the data of `total`, but it returns 400. but when I try a sample data like

`int httpResponseCode = http.POST("{\"amount\":\"total\"}");` (400)

into

`int httpResponseCode = http.POST("{\"amount\":\"15\"}");` it works (201).

How to make it work? Thanks!

```
#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
#include <WiFiClient.h>

const byte interruptPin = 4;
const int interval = 500;
volatile unsigned long tiptime = millis();
volatile float rainrate = 0.3;
volatile float total;
void ICACHE_RAM_ATTR count();

void loop() {
  if ((millis() - lastTime) > timerDelay) {
    //Check WiFi connection status
    if (WiFi.status()== WL_CONNECTED) {
      HTTPClient http;

      // Your Domain name with URL path or IP address with path
      http.begin(serverName);

      // Specify content-type header
      http.addHeader("Content-Type", "application/json");

      // Data to send with HTTP POST
      int httpResponseCode = http.POST("{\"amount\":\"total\"}");

      Serial.print("HTTP Response code: ");
      Serial.println(httpResponseCode);

      // Free resources
      http.end();
    }
    else {
      Serial.println("WiFi Disconnected");
    }
    lastTime = millis();
  }
}

void count() {
  // Grab the current ms count for common calculations
  unsigned long curtime = millis();

  // Make sure we don't record bounces
  if ((curtime - tiptime) < interval) {
    return;
  }

  // How long since the last tip?
  unsigned long tipcount = curtime - tiptime;
  tiptime = curtime;

  total += rainrate;
  Serial.println(total);
}

```

# Answer
> 5 votes
Your line

```
int httpResponseCode = http.POST("{\"amount\":\"total\"}");

```

is not doing what you think it's doing. You're not placing the contents of the variable called `total` in the string, you're placing the *word* `total` in the string.

Instead you need to build up the string from components before sending. I'd use something like:

```
char temp[32];
snprintf(temp, 32, "{\"amount\":\"%.2f\"}", total);
int httpResponseCode = http.POST(temp);

```

That is assuming the `http.POST()` function will take a `char *` parameter. If not you may need to resort to a `String`:

```
String temp = "{\"amount\":\"";
temp += String(total, 2);
temp += "\"}";

```

However it is best to avoid `String` as it can cause heap fragmentation causing your code to become unstable over time.

---
Tags: http, datalogging
---


title: Built-in LED lighs up spontaneously

text:
# Question
Title: Built-in LED lighs up spontaneously
I'm trying to connect my ESP32 to this CO2 measurement device. I admit I am clueless about connecting devices with independent power sources to one another.

I connected ground to ground and CLK to PIN2. Just to be on the safe side, I put a resistor between CLK and PIN2.

I started with 4.8KOhm of resistance. ESP's ADC measured 2.1V and it seemed fine. But when I switched to 1K resistor, trying to get closer to the level of "logical 1" (the way I understand it), something unexpected happened. ADC measured 2.65V, which is still beyond 3.3V ESP should be able to handle, and the built-in LED lit up, although nothing in my sketch called for it.

Though the configuration worked stably for some minutes while I was testing it, and no smoke appeared, I am afraid the LED lighting spontaneously might be a sign of an electrical breakdown.

The both devices are sitting on the same USB hub.

Here is the sketch I am using:

```
#define PIN_CLOCK  2

void setup() {
  pinMode(PIN_CLOCK, INPUT);
  Serial.begin(4800);
}

bool last = 0;

void loop() {
  int x = analogRead(PIN_CLOCK);
  bool val = x > 1500;
  if (last != val)
    Serial.println(x*3.3/4095);
    last = val;
  }

```

Can someone explain why the LED lights up?

Can someone recommend a good article/video on basic rules about interconnecting such devices?

# Answer
You do not need a resistor in the circuit. Just connect the devices together directly as shown in the tutorial you link to. They are both 3.3V devices and operate perfectly together with no additional components.

Reading an analog value from a clock signal is pretty meaningless anyway, so there's really no point in your experiments at the moment. They prove nothing.

As to why the light came on - that is most likely because the ESP is configured to use that LED to indicate the WiFi status or something similar. The thing with an ESP32 is there is a whole lot more going on than just your code. Your code is just one thread in a complex system.
> 1 votes

---
Tags: sensors, esp32
---


# Question
Title: Is this class declaration wrong? " Declaration has no storage class or type specifier" error
While trying to setup an ESP32 as mqtt publisher I am getting strange errors. Here is my code:

```
#include "mqttSetup.h"
#include <WiFi.h>
#include <PubSubClient.h>

static byte httpFailCounter = 0;
byte counter = 0;

const char *ssid = "SSID";
// const char *password = "xxxxx";
const char *passphrase = "xxxxx";

WiFiClient espClient;

const char *mqtt_server = "192.168.1.39";
const int mqttPort = 1883;
const char *mqttUser = "xxxx";
const char *mqttPassword = "xxxxx";

PubSubClient pubClient(espClient);

pubClient.setServer(mqtt_server, mqttPort);

void checkConnection()
{
    if (WiFi.status() == WL_CONNECTED)
    {
        counter = 0; //reset counter
    }
    else if (WiFi.status() != WL_CONNECTED)
    {
        WiFi.begin(ssid, passphrase);
    }
    while (WiFi.status() != WL_CONNECTED)
    {
        delay(500);
        Serial.print(".");

        counter++;
        if (counter >= 60)
        {
            ESP.restart();
        }
    }
}

void reconnect()
{

    while (!pubClient.connected())
    {
        Serial.print("Attempting MQTT connection...");
        // Create a random client ID
        const char *clientID = "ESP32D-MQTT";
        // Attempt to connect
        if (pubClient.connect(clientID))
        {
            Serial.println("connected");
            // Once connected, publish an announcement...
            pubClient.publish("outTopic", "Hello from ESP");
            // ... and resubscribe
            //   client.subscribe("inTopic");
        }
        else
        {
            Serial.print("failed, rc=");
            Serial.print(pubClient.state());
            Serial.println(" try again in 5 seconds");
            // Wait 5 seconds before retrying
            delay(5000);
        }
    }
}

```

I don't understand why the compiler is spitting out the following two errors:

```
this declaration has no storage class or type specifier (referring to my pubClient declaration)

expected a ';'

```

It doesn't have any issue when I declare the pubClient but at the line :

`pubClient.setServer(mqtt_server, mqttPort);`

where I use the pubClient it gives the error.

Besides I don't see any ; missing in the code.

Could you please help me figure out the source of error?

---

Header file for this code chunk

```
#ifndef MQTTSETUP_H
#define MQTTSETUP_H

void checkConnection();
void reconnect();

#endif

```

------------ Main sketch---------

```
#include <Arduino.h>
#include "Wire.h"
#include "tempSensor.h"
#include "mqttSetup.h"

void setup()
{
  Wire.begin();

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

  shtBegin();
  checkConnection();
}

void loop()
{
  uint32_t newTime = millis();
  static uint32_t oldTime = 0;
  static uint32_t t2 = 0;

  float temp = 0.0;
  float humid = 0.0;

  char senVals[50];

  if (newTime - oldTime >= 10000)
  {
    oldTime = newTime;

    readsht(temp, humid);
    snprintf(senVals, 50, "Temp: %.2f Humid: %.2f", temp, humid);
    Serial.println(senVals);

  }
}

```

# Answer
> 0 votes
Code goes in functions, not the global scope.

Your line

```
pubClient.setServer(mqtt_server, mqttPort);

```

should be inside a function. Most probably `setup()` so it gets called when your program starts.

Incidentally - where are `setup()` and `loop()` \- the two functions that are required by Arduino code?

---
Tags: esp32, class
---


# Question
Title: What is the best way to power the ESP32 from a battery?
I am making a temperature sensor that can go in a freezer and I am trying to figure out what the best method is.

My research has taken me all over the place an I can't seem to find a straight answer. Some sites recommend using LiFePo4, while others say absolutely not, because it needs to be regulated.

One question I have is: could I use more voltage, say 6V from a series of batteries and connect it to the 5V pin since it is regulated, or is it better to go with an external regulator for the 3.3V pin with less voltage?

# Answer
> 1 votes
Since it is a freezer (operating temperature unknown) I am assuming it is connected to the mains why not do the same with the electronics. This will save you a lot work and time and when you find out it will not work in a Faraday cage as stated by timemage. Leave the sensor wire long enough to mount the electronics outside just in case. Also consider packaging, it will be cold, possibly below the operating range of some of the components requiring you to keep them warm (above minimum temperature). I would assume your freezer like ours has moisture concerns as ice will form when opened then removed by a defrost cycle. You will also have to protect for that. Then there is the operating temperature range of the batteries, are they capable of operating at your freezer temperatures. I would suggest you redefine your problem before starting the design, this process saves me a lot of grief.

---
Tags: power, esp32, battery
---


# Question
Title: How to shorten this code (because my sensor reads slowly)?
I'm making a fare meter for our school project. I have too much `lcd.print` code. This code is not finished yet. My only concern is how to minimize the usage of `lcd.print`. I think it's the one that makes my sensor reading slow.

I'm new at Arduino; sorry if I have too many mistakes. I appreciate any of your answers. Thank you!

```
#include <LiquidCrystal_I2C.h>
#include <Wire.h>
#include <virtuabotixRTC.h>

virtuabotixRTC myRTC(6, 7, 8);
float d[4] = {};
int x = 0;
int f = 0;
int dis = 0;
const uint8_t disBut = 13;
int input = A0;
int state = 0;
int disF = 0;
int buttonstate = 0;
LiquidCrystal_I2C lcd(0x27, 20, 4);
LiquidCrystal_I2C lcd1(0x26, 20, 4);

void setup() {
  Serial.begin(9600);
  lcd.init();
  lcd.backlight();
  lcd1.init();
  lcd1.backlight();
  pinMode(disBut, INPUT);
  pinMode(buttonstate, OUTPUT);
}

void loop() {
  myRTC.setDS1302Time(18, 10, 10, 7, 18, 9, 2020);

  Serial.print("Current Date / Time: ");
  Serial.print(myRTC.dayofmonth);
  Serial.print("/");
  Serial.print(myRTC.month);
  Serial.print("/");
  Serial.print(myRTC.year);
  Serial.print("  ");
  Serial.print(myRTC.hours);
  Serial.print(":");
  Serial.print(myRTC.minutes);
  Serial.print(":");
  Serial.println(myRTC.seconds);
  delay(500);

  d[0] = (x * 1.73);
  d[1] = (x * 1.73);
  d[2] = (x * 1.73);
  d[3] = (x * 1.73);

  lcd.setCursor(8, 0);
  lcd.print(d[0]);
  lcd.setCursor(8, 1);
  lcd.print(d[1]);
  lcd.setCursor(8, 2);
  lcd.print(d[2]);
  lcd.setCursor(8, 3);
  lcd.print(d[3]);

  lcd.setCursor(0, 0);
  lcd.print(F("P1"));
  lcd.setCursor(0, 1);
  lcd.print(F("P1"));
  lcd.setCursor(0, 2);
  lcd.print(F("P1"));
  lcd.setCursor(0, 3);
  lcd.print(F("P1"));

  lcd.setCursor(6, 0);
  lcd.print(F("D="));
  lcd.setCursor(6, 1);
  lcd.print(F("D="));
  lcd.setCursor(6, 2);
  lcd.print(F("D="));
  lcd.setCursor(6, 3);
  lcd.print(F("D="));

  lcd1.setCursor(0, 0);
  lcd1.print(F("W="));
  lcd1.setCursor(0, 1);
  lcd1.print(F("W="));
  lcd1.setCursor(0, 2);
  lcd1.print(F("W="));
  lcd1.setCursor(0, 3);
  lcd1.print(F("W="));

  lcd1.setCursor(6, 0);
  lcd1.print(F("dscnt="));
  lcd1.setCursor(6, 1);
  lcd1.print(F("dscnt="));
  lcd1.setCursor(6, 2);
  lcd1.print(F("dscnt="));
  lcd1.setCursor(6, 3);
  lcd1.print(F("dscnt="));

  lcd1.setCursor(15, 0);
  lcd1.print(F("F="));
  lcd1.setCursor(15, 1);
  lcd1.print(F("F="));
  lcd1.setCursor(15, 2);
  lcd1.print(F("F="));
  lcd1.setCursor(15, 3);
  lcd1.print(F("F="));

  int counter=digitalRead(A0);
  if (state == 0) {
    switch (counter) {
      case 1:
        state = 1;
        lcd.setCursor(11, 0);
        x = x + 1; lcd.print(x);
        break;
      case 0:
        state = 0;
        break;
    }
  }

  if (counter == LOW)
    state = 0;
  if (state == 0) {
    switch (counter) {
      case 1:
        state = 1;
        x = x + 1;
        break;
      case 0:
        state = 0;
        break;
    }
  }

 if (counter == LOW)
   state = 0;
}

```

# Answer
Your slowness is because on every single iteration of `loop()` you are updating the entirety of the display. That's bad and wasteful.

You need to do two things:

1. Only display static information (the labels) once. Do that in `setup()`.
2. Only display the variable data if it actually changes.

The first is simple: move any static text to `setup()`. That means things like `lcd1.print(F("dscnt="));`. It never changes, and the display doesn't "forget" it, so doesn't need constantly reminding.

The second is slightly harder. You need to keep two copies of the data. One that is the data at this moment, and one that is the data that is being displayed. Then you compare one with the other and for any items where they differ display them and update your saved copy.

So something like:

```
if (d[0] != d_saved[0]) {
    d_saved[0] = d[0];
    lcd.setCursor(8, 0);
    lcd.print(d[0]);
}

```

You can of course make that easier to program with a loop:

```
for (uint8_t i = 0; i < 4; i++) {
    if (d[i] != d_saved[i]) {
        d_saved[i] = d[i];
        lcd.setCursor(8, i);
        lcd.print(d[i]);
    }
}

```

Of course `d_saved[4]` needs creating in either the global scope or as a local `static` variable and initialising with some suitable "can never be" values (like -1 or something) so that the first time through it will always be different from the real values and display everything properly.
> 2 votes

---
Tags: code-optimization
---


title: Play audio on an ESP32 or an Arduino

text:
# Question
Title: Play audio on an ESP32 or an Arduino
I am in the process of making a talking robot and I have linked my ESP32 to a Google text-to-speech service. The service returns me a base64 8-bit audio response.

I need to play this audio and I can't figure out how to do it. I know that an audio playing library exist for PCM but the data that it requires is not base64.

# Answer
Base64 has nothing to do with audio. It is merely a way of encapsulating binary data into ASCII text so that it can safely be included in text-based structures like JSON, or transmitted over a text-based communication channel.

There is no library to "play" base64 simply because base64 is not something you play.

First you decode the base64 text into raw 8-bit binary. It's then *that* data that you play through whatever library is most suitable for your hardware.

For example on the ESP32 you have the function `base64_decode()` available. You can read up on how to use it in this tutorial.
> 1 votes

---
Tags: esp32, audio, thingspeak
---


# Question
Title: Need help with millis () function for two linear actuators
Last week I was grateful to receive help programming the Arduino to control two linear actuators.

I need help re-writing the code using the millis () function. I am more than happy to reimburse for time spent on this project. This is my first experience with Arduino and millis () is too involved for me.

The actuators control a set of barn doors in my house. The actuators are programmed to open and close with the push of a button (z-wave relay programmed as 6 second momentary switch). The actuators do not give feedback, so the program is used to control the speed from 0-255 using the PWM ports to make the actuators appear somewhat in sync. They move at three different speeds so that they don't slam when opening and closing. This is where millis () comes in. Right now I am using a delay to control the speed for various amounts of time, but using a delay creates a safety issue since the Arduino cannot do anything during this time.

The reason I need to utilize the millis () function is that I need to be able to make the doors stop and reverse in the event that there is something blocking their path. To accomplish this I will be using a garage door electric eye wired through a homemade circuit board. The output will go low any time the beam is broken and otherwise it will remain high. I'd like the Arduino program to utilize this signal any time the doors are closing and if the beam is broken - make the actuators reverse direction. I realize that without feedback I cannot make the doors open all the way depending on when the beam is broken. I am really not too concerned about that. As long as they stop and reverse for at least a little bit I will be happy. I don't want to crush my kids or pets.

Again, I am more than happy to reimburse anyone willing to help write the code for this. Here is the code I am using now which utilizes the delay function. I'd like this code to be changed to utilize the millis function and also add in programming for the sensor as described above.

```
/* Program enables momentary direction control of actuator using push button
 */

int RPWM = 10; //connect Arduino pin 10 to IBT-2 pin RPWM
int LPWM = 11; //connect Arduino pin 11 to IBT-2 pin LPWM
int RPWM2 = 5; //connect Arduino pin 5 to IBT-2 pin RPWM
int LPWM2 = 6; //connect Arduino pin 6 to IBT-2 pin LPWM
int downPin = 12;
int upPin = 13;
int speed1 = 0; // Top speed you can change it between [0-255]
int speed2 = 0; // Low speed you can change it between [0-255]
int speed3 = 0; // Low speed you can change it between [0-255]

void setup() {
  pinMode(RPWM, OUTPUT);
  pinMode(LPWM, OUTPUT);
  pinMode(RPWM2, OUTPUT);
  pinMode(LPWM2, OUTPUT);
  pinMode(downPin, INPUT_PULLUP);
  pinMode(upPin, INPUT_PULLUP);
}

void loop() {
  if(digitalRead(upPin)==LOW){ //check if extension button is pressed
    analogWrite(RPWM, 0);
    analogWrite(RPWM2, 0);
    analogWrite(LPWM, 255); // rotate motor with top speed
    analogWrite(LPWM2, 245); // rotate motor with top speed
    delay(3000);               // wait for x sec
    analogWrite(LPWM, 180); // rotate motor with low speed
    analogWrite(LPWM2, 176); // rotate motor with low speed
    delay(1500);               // wait for x sec
    analogWrite(LPWM, 80); // rotate motor with low speed
    analogWrite(LPWM2, 80); // rotate motor with low speed
    delay(1500);               // wait for x sec
    analogWrite(LPWM, 0);     // uncomment if you want to stop motor now
    analogWrite(LPWM2, 0);     // uncomment if you want to stop motor now
  }

  else if(digitalRead(downPin)==LOW){ //check if retraction button is pressed
    analogWrite(LPWM, 0);
    analogWrite(LPWM2, 0);
    analogWrite(RPWM, 250); // rotate motor with top speed
    analogWrite(RPWM2, 255); // rotate motor with top speed
    delay(3000);               // wait for x sec
    analogWrite(RPWM, 165); // rotate motor with low speed
    analogWrite(RPWM2, 165); // rotate motor with low speed
    delay(1500);               // wait for x sec
    analogWrite(RPWM, 80); // rotate motor with low speed
    analogWrite(RPWM2, 80); // rotate motor with low speed
    delay(1500);               // wait for x sec
    analogWrite(RPWM, 0);     // uncomment if you want to stop motor now
    analogWrite(RPWM2, 0);     // uncomment if you want to stop motor now
  }

  else{ //if no button is pushed, remain stationary
    analogWrite(RPWM, 0);
    analogWrite(LPWM, 0);
    analogWrite(RPWM2, 0);
    analogWrite(LPWM2, 0);
  }
}

```

# Answer
> 0 votes
You've come to the requirement called non-blocking programming. The gist of it is that your loop() function does little other than call a number of "maybe-do" functions - my name for functions that assess the need to act, and act or not, and return, as quickly as possible. So in pseudo-code, your loop might look something like:

```
void loop(){
   maybeStartMotor1();
   maybeSlowMotor1();
   maybeStartMotor2();
   maybeSlowMotor2();
   maybeStopMotor1();
   maybeStopMotor2();
   // Call maybe-do()s for ... whatever else might need to happen
}

```

Your maybe functions would probably look like, e.g.:

maybeSlowMotor1(){ if( millis() - millis\_at\_motor1\_start \> DECELTIME2 ) set motor1 to slow speed;

else if( millis() - millis\_at\_motor1\_start \> DECELTIME1 ) set motor1 to medium speed;

return; }

Note that my understanding of your mechanical system is limited and the above is meant to describe a software technique, not a solution.

Also note my complete agreement with @timemage's caution against depending on software for your safety interlocks. Your 3rd comment under your question - to directly reverse the doors with photocells and relays - in addition to the software detection and control - provides a necessary redundancy.

I'd also like to refer you to this somewhat more complete description I wrote to answer another, similar, question.

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


# Question
Title: Problem with sending IR with at ATMega328P-PU
I have a sketch that sends an IR code every second. It works fine (the correct code is received by my receiving Arduino next to it) on the Arduino but when I try to move the sketch to an ATMega328P-PU, the IR no longer sends (the serial monitor output still works).

I have used a camera to look at the IR LED and it just doesn't flash on the ATMega328 but does on the Arduino (and I have tested my LED, it does work). It uses pin 3 on the Arduino, so I use pin 5 on the ATMega328.

Are there extra components that are needed to make PWM work without the Arduino board? I am honestly stumped so any help would be appreciated. Thanks in advance.

Sketch:

```
#include <IRremote.h>

IRsend irsend; //Setup the IR transmitter

int codeToSend;
int team = 1;
int damage = 0;

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

void loop()
{
    team++;
    if (team > 8) team = 1;
    damage++;
    if (damage > 99) damage = 0;

    if (damage > 9) codeToSend = (String(team) + String(damage)).toInt();
    else codeToSend = (String(team) + "0" + String(damage)).toInt();

    Serial.println("sent");
    irsend.sendNEC(codeToSend, 32);
    delay(500);
}

```

# Answer
NOTE: The following comment was left on this answer (below) and indicates the principal problem the original poster was having above and beyond not having a resistor, etc.

> **SOLVED - my breadboard was broken on that rail. :/**

## Current limiting

What you have pictured looks alright for the most part with the exception of there appearing to be no current limiting resistor for the IRED. It is possible that you've damaged the IRED by setting the pin HIGH for an extended period of time. It is also technically possible to have damaged the AVR (or just the one pin) by doing that, though this wouldn't be my first guess.

Typical forward voltages for an IRED around around a volt. An AVR pin's **maximum** rating current is 40mA. To get proper logical levels out of it, it should be less than 20mA. You *could* perhaps operate near 30mA, since you're not doing much else with the AVR's ports and you're not trying to get logic level voltages out of the pin. For that you'd need a resistor in series with the IRED that is something like (5V - 1V) / 0.030A, approximately 133 ohms.

## Transistors

When people use IRED to make remotes, it is normal to use a transistor to offload the current requirement from the MCU. And also to operate the IRED above its continuous operation current, closer to it's rated peak/pulse current. Operating in the low tens of mA often only gets you a meter or so.

That arrangement might look something like the following for higher current pulses around 80mA:

## Asides

* I'm not able to read your reset resistor well. If you're not, do measure it to make sure it's 10K. If in doubt, remove it. There is a weaker internal pullup on the AVR reset and it's *usually* enough. If you wanted you could wire the reset signal over to the UNO reset pin to take advantage of the external pullup, reset switch, and DTR reset mechanism of the UNO itself.
* You may want to add .1uF capacitors from your VCC and AVCC pins to ground. You can often go without while experimenting, but when you're switching higher currents they'll become more important.
* I have a bunch of those jumpers with the rounded (cylindrical) ends. They often don't make good connections on breadboard. You can save some trouble sometimes with "Dupont" type jumpers or just making your own out of solid 22awg hookup wire.
> 0 votes

---
Tags: arduino-uno, led, pwm, atmega328, ir
---


title: Controlling LEDs with bit bang method

text:
# Question
Title: Controlling LEDs with bit bang method
I'm doing a research for RGB LED chips that MCU can control with one pin. I found this LED chip and it seems controlling LEDs is not as I've tought. I understand hardware part, software side is a problem.

In chip's datasheet, on page 6, you can find chapter four `Data Transfer Format`.

**My questions are:** Why `D2` has only `second 24 bit`, `third 24 bit` while `D3` has only `third 24 bit` and why `D4` has no bits? What should I do when I'm done with "updating LEDs"?

I thought controlling LEDs can be done like this:

* Lets say I have five LEDs to control. Every LED has Red, Green and Blue and every color is 8-bit. Five times three is 15 bytes array.
* First three bytes in array are for last LED chip. While sending the data, highest bit(bit 7) will go first.
* After first three bytes, MCU will stop for X microseconds. After delay, new three bytes will push old three bytes to second LED chip.
* After MCU is done with sending data, it will leave data pin low.

Thanks!

# Answer
You need to send the 5x24 bits out without a pause. If you then keep the line low for over 80us, that is interpreted by all LED drivers as the reset signal. It is not stated explicitly in the datasheet (at least I haven't found it), but I guess the reset signal means, that at that time all drivers will output the received values on the LEDs. That way you can light up all LEDs at the same time with their respective data.

The picture, that you refer to, explains the automatic data cascading. The first row is what you actually send from your microcontroller and also what is seen by the first LED driver in the row. That driver will then consume the first 24 bits, that it sees. After that, it will forward the rest of the data to the next LED driver. That will now consume the first 24 bits that it sees (thus the second 24 bits, that you have send). The third LED driver will do the same. But since in that example you only send data for 3 LEDs, no data is forwarded. Then the reset pulse happens and at some point in time you send a new set of data.

So each row represents, what the corresponding LED driver will see of the data, that you send. D1 sees all the data. Each following LED driver will see 24 bits less. D4 will see nothing, since you send only 3x24 bits in that example.
> 1 votes

---
Tags: led, rgb-led, serial-data, bit
---


title: HTTP_GET not clarified in scope

text:
# Question
Title: HTTP_GET not clarified in scope
I'm trying to do an async webserver with access point using an ESP32.

It's a little bit of a mix between This tutorial for AP and async and this tutorial since it's also with an async webserver and it uses inputs which I desperately need.

The part I don't understand is I included all the necessary libraries and I still got this error. If I copy-paste the code in one block everything is fine. It was never necessary to declare `HTTP_GET` since it should be a variable from a library.

So what's wrong?

These are my errors:

```
    In file included from C:\..\Arduino\libraries\ESPAsyncWebServer-master\src/ESPAsyncWebServer.h:467:0,
                     from C:\..\AppData\Local\Temp\arduino_build_497972\sketch\webserver.h:5,
                     from C:\..\Async Webserver ESP32\main\main.ino:3:
    C:\..\Arduino\libraries\ESPAsyncWebServer-master\src/WebHandlerImpl.h: In constructor 'AsyncCallbackWebHandler::AsyncCallbackWebHandler()':
    C:\..\Arduino\libraries\ESPAsyncWebServer-master\src/WebHandlerImpl.h:76:49: error: 'HTTP_ANY' was not declared in this scope
         AsyncCallbackWebHandler() : _uri(), _method(HTTP_ANY), _onRequest(NULL), _onUpload(NULL), _onBody(NULL), _isRegex(false) {}
                                                     ^
    In file included from C:\..\Arduino\libraries\ESPAsyncWebServer-master\src/ESPAsyncWebServer.h:467:0,
                     from C:\..\AppData\Local\Temp\arduino_build_497972\sketch\webserver.h:5,
                     from C:\..\AppData\Local\Temp\arduino_build_497972\sketch\webserver.cpp:1:
    C:\..\Arduino\libraries\ESPAsyncWebServer-master\src/WebHandlerImpl.h: In constructor 'AsyncCallbackWebHandler::AsyncCallbackWebHandler()':
    C:\..\Arduino\libraries\ESPAsyncWebServer-master\src/WebHandlerImpl.h:76:49: error: 'HTTP_ANY' was not declared in this scope
         AsyncCallbackWebHandler() : _uri(), _method(HTTP_ANY), _onRequest(NULL), _onUpload(NULL), _onBody(NULL), _isRegex(false) {}
                                                     ^
    C:\Users\Valentin\AppData\Local\Temp\arduino_build_497972\sketch\webserver.cpp: In function 'void setup_server(AsyncWebServer)':
    webserver.cpp:6:18: error: 'HTTP_GET' was not declared in this scope
       server.on("/", HTTP_GET, [](AsyncWebServerRequest * request) {
                      ^
    Multiple libraries were found for "WiFi.h"
     Used: C:\..\Arduino15\packages\firebeetle32\hardware\esp32\0.1.1\libraries\WiFi
     Not used: C:\Program Files (x86)\Arduino\libraries\WiFi
    Using library ESPAsyncWebServer-master at version 1.2.3 in folder: C:\..\Arduino\libraries\ESPAsyncWebServer-master
    Using library FS at version 1.0 in folder: C:\..\Arduino15\packages\firebeetle32\hardware\esp32\0.1.1\libraries\FS
    Using library WiFi at version 1.0 in folder: C:\..\Arduino15\packages\firebeetle32\hardware\esp32\0.1.1\libraries\WiFi
    Using library AsyncTCP-master at version 1.1.1 in folder: C:\..\Arduino\libraries\AsyncTCP-master
    exit status 1
    'HTTP_GET' was not declared in this scope

```

I already tried to use the standard Arduino WiFi library which resulted just in more errors so I switched it back.

I split up the code into three pieces for better visibility.

**main.ino**

```
#include <Arduino.h>
#include "webserver.h"

// REPLACE WITH YOUR NETWORK CREDENTIALS
const char* ssid = "blabla";
const char* password = "blabla";

void setup() {
  Serial.begin(115200);
  WiFi.softAP(ssid, password);
  IP = WiFi.softAPIP();

  Serial.println();
  Serial.print("IP Address: ");
  Serial.println(IP);

  setup_server(server);
}

void loop() {}

```

**webserver.cpp**

```
#include "webserver.h"

void setup_server(AsyncWebServer server) {
  // Send web page with input fields to client
  server.on("/", HTTP_GET, [](AsyncWebServerRequest * request) {
    request->send_P(200, "text/html", index_html);
  });

  // Send a GET request to <ESP_IP>/get?input1=<inputMessage>
  server.on("/get", HTTP_GET, [] (AsyncWebServerRequest * request) {
    // GET input1 value on <ESP_IP>/get?input1=<inputMessage>
    if (request->hasParam(PARAM_INPUT_1)) {
      inputMessage = request->getParam(PARAM_INPUT_1)->value();
      inputParam = PARAM_INPUT_1;
    }
    // GET input2 value on <ESP_IP>/get?input2=<inputMessage>
    else if (request->hasParam(PARAM_INPUT_2)) {
      inputMessage = request->getParam(PARAM_INPUT_2)->value();
      inputParam = PARAM_INPUT_2;
    }
    // GET input3 value on <ESP_IP>/get?input3=<inputMessage>
    else if (request->hasParam(PARAM_INPUT_3)) {
      inputMessage = request->getParam(PARAM_INPUT_3)->value();
      inputParam = PARAM_INPUT_3;
    }
    else {
      inputMessage = "No message sent";
      inputParam = "none";
    }
    Serial.println(inputMessage);
    request->send(200, "text/html", "HTTP GET request sent to your ESP on input field ("
      + inputParam + ") with value: " + inputMessage +
      "<br><a href=\"/\">Return to Home Page</a>");
    });
    server.onNotFound(notFound);
    server.begin();
  }

void notFound(AsyncWebServerRequest *request) {
  request->send(404, "text/plain", "Not found");
}

```

**webserver.h**

```
#ifndef WEBSERVER_H
#define WEBSERVER_H

#include "Arduino.h"
#include "ESPAsyncWebServer.h"
#include "AsyncTCP.h"
#include <WiFi.h>

const char* PARAM_INPUT_1 = "input1";
const char* PARAM_INPUT_2 = "input2";
const char* PARAM_INPUT_3 = "input3";

AsyncWebServer server(80);

String music_state;
IPAddress IP;

String inputMessage;
String inputParam;

// HTML web page to handle 3 input fields (input1, input2, input3)
const char index_html[] PROGMEM = R"rawliteral(
<!DOCTYPE HTML><html><head>
  <title>ESP Input Form</title>
  <meta name="viewport" content="width=device-width, initial-scale=1">
  </head><body>
  <form action="/get">
    input1: <input type="text" name="input1">
    <input type="submit" value="Submit">
  </form><br>
  <form action="/get">
    input2: <input type="text" name="input2">
    <input type="submit" value="Submit">
  </form><br>
  <form action="/get">
    input3: <input type="text" name="input3">
    <input type="submit" value="Submit">
  </form>
</body></html>)rawliteral";

void setup_server(AsyncWebServer server);

void notFound(AsyncWebServerRequest *request);

#endif

```

Thanks for the input, I will check back tomorrow and answer all questions and test every suggestion.

# Answer
## Macro Conflict

You have two basic problems here. The more significant one is that your use of SERVER\_H in your include guard:

```
#ifndef WEBSERVER_H
#define WEBSERVER_H

```

conflicts with a usage in ESPAsyncWebServer.h:

```
#ifndef WEBSERVER_H
typedef enum {
  HTTP_GET     = 0b00000001,
  HTTP_POST    = 0b00000010,
  HTTP_DELETE  = 0b00000100,
  HTTP_PUT     = 0b00001000,
  HTTP_PATCH   = 0b00010000,
  HTTP_HEAD    = 0b00100000,
  HTTP_OPTIONS = 0b01000000,
  HTTP_ANY     = 0b01111111,
} WebRequestMethod;
#endif

```

and that explains why your `HTTP_GET` etc are not found. They're not being defined because of your include guard macro.

Changing your code to:

```
#ifndef XENOSHELL_WEBSERVER_H
#define XENOSHELL_WEBSERVER_H

```

or something similar will get you past that problem.

## Multiply Defined Variables

You also have some non-static variables defined in your webserver.h that will also need to be changed somehow. A simple change just being to make them static:

```
static const char* PARAM_INPUT_1 = "input1";
static const char* PARAM_INPUT_2 = "input2";
static const char* PARAM_INPUT_3 = "input3";

```

`IPAddress IP;` is only used in main.ino, and should be moved there as a local `const IPAddress IP = WiFi.softAPIP();` If you leave it in the header you'll get multiple definitions because of that.

`String inputMessage;` and `String inputParam;` Same problem, only these belong inside your lambda expression in `server.on("/get", HTTP_GET, [] (AsyncWebServerRequest * request) {`

I don't know why your server variable is in the header either. The simplest thing to do is put it in webserver.cpp instead and don't pass it in to `setup_server`, in other word remove the parameter and use the variable defined in the same file as the function.

---

Having done that your code compiles fine. Whether or not it works is another question. I am unable to test that.
> 2 votes

---
Tags: esp32, web-server, http
---


# Question
Title: Transmit/Receive data Nodemcu(V3) + Bluetooth Module HC-05
I am trying to communicate with the HC-05 Bluetooth module for quite long time now, but with no success.

I am using the Nodemcu(V3) ESP8266 module.

I connect the HC-05 to Nodemcu in following sequence:

```
HC-05             Nodemcu
-----             -----------
RX       -->      Pin 1 (Tx)
TX       -->      Pin 3 (RX)
Vcc      -->      +3.3V
GND      -->      GND

```

For starters, i want to check if my Nodemcu is communicating properly with my HC-05 module.

I have written the following code to read the response of AT commands:

```
#include <SoftwareSerial.h>
SoftwareSerial BTserial(3, 1); // RX | TX
char Bluetooth_Name = ' ';

void setup()
{
    // Arduino IDE serial monitor
    Serial.begin(115200);

    // HC-05 default serial speed for AT mode is 38400
    BTserial.begin(38400);

    // Wait for hardware to initialize
    delay(1000);

    // Print debug string
}

void loop()
{

   // Keep reading from HC-05 and send to Arduino Serial Monitor
   if (BTserial.available())
   {
      reading = BTserial.read();
      Serial.println(reading);
   }

   // Keep reading from Arduino Serial Monitor and send to HC-05
   if (Serial.available())
   {
      reading = Serial.read();
      BTserial.write(reading);
   }
}

```

However, i do not get response for any AT command at all. The serial monitor just shows blank.

***Thanks in advance***

EDIT:- I connected the "EN" pin on the HC-05 to Vcc. Now, the led on the HC-05 blinks slowly, which means that the HC-05 is configured in command mode. However, i am still not able to receive the response for any AT commands. I have also selected "Both NL & CR" in the serial monitor, configured the baud rate correctly and double-checked the hardware connections.

Everything seems to be correct except that i don't get response for the AT commands.

Please help!!!

# Answer
> 2 votes
I changed the line

```
SoftwareSerial BTserial(3, 1); // RX, TX

```

to

```
SoftwareSerial BTserial(D4, D3); // RX, TX

```

And got it to work!

# Answer
> 3 votes
I had the exact same problem and got it to work doing these changes:

I had to add this under my library include statements

```
#ifndef D5
#if defined(ESP8266)
#define D5 (14)
#define D6 (12)
#define D7 (13)
#define D8 (15)
#define TX (1)
#endif
#endif

```

and changed

`SoftwareSerial BTserial(3, 1); // RX, TX`

to

`SoftwareSerial BTserial(D5,D6);`

I used D5 and D6 on my esp8266 instead of D1 and D3 but shouldn't matter

---
Tags: esp8266, bluetooth, nodemcu, hc-05
---


# Question
Title: How to fix "expected primary-expression before '%' token" error code?
I'm trying to use this code to get temperature and humidity values from DHT11 sensor and send it to Python and I need to write the temperature and humidity values in the same line. But I keep getting the error code

> expected primary-expression before '%' token

How can I fix this?

```
#include <dht.h>
#include <stdio.h>
int a = 0;
int b = 0;
char buffer [64];

dht DHT;

#define DHT11_PIN 7

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

void loop(){
  a = DHT.temperature;
  b = DHT.humidity;
  int chk = DHT.read11(DHT11_PIN);
  sprintf(buffer, %d %d, a, b);
  Serial.print(buffer);
  delay(1000);
}

```

# Answer
> 1 votes
You are missing quotes on the second parameter of `sprintf`:

```
sprintf(buffer, "%d %d", a, b);

```

---
Tags: communication, python
---


# Question
Title: SMPTE Timecode Reader with LCD display coding question
I've managed to adapt some code from the Arduino forums to display timecode on an LCD display.

What I would like some extra help with is first is there a way of defining the `one_time_max` etc differently depending on the high low state of a pin? This way I could use a switch to change the times so it could switch between NTSC and PAL.

Secondly would anyone be kind enough to explain what is happening in the middle part of this code? I've made some notes but any help would be really appreciated.

Here is a picture of how it's going so far. I'll keep you guys up to date as the project continues :)

\[!\[enter image description here\]\[1\]\]\[1\]

```
    // Code from forum post Dec 12, 2007

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

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

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

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

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

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

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

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

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

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

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

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

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

```

# Answer
> 1 votes
The one\_time\_max, one\_time\_min, zero\_time\_max and zero\_time\_min are all defines at the top of the file. This will insert them as constant values at compile time. This makes changing the code to deal with them slightly awkward, but not impossible.

Oddly, the one\_time\_max value isn't used, but the others are. To allow you to switch between PAL and NTSC, I would do the following (this is marginally lazy, but quick):

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

# Answer
> 1 votes
I am in the process of implementing exactly the same thing. The simplest way around this problem is simply to do away with the one\_time\_max and one\_time\_min variables and simply implement a mid\_point value, testing the bit\_time against this for one and zero values. By simply testing for a mid\_point value, it allows the routine to tune itself for integer/non-integer timecode values from 24fps thorough to 30fps.

# Answer
> 0 votes
I am implementing a similar project, but my timecode reader is built into the clapperboard itself.

https://improduction.ru/tags/imslate-1/

The thing is that the bit length depends on the FPS. I just "listened" to the signal from my Zoom F8 recorder and then started the reference data. While receiving data from the cable, I simply compare them and determine the frequency. That's all.

https://improduction.ru/all/elektronnaya-hlopushka-imslate-1-pro-chtenie-taymkoda/

---
Tags: arduino-uno, lcd
---


# Question
Title: What is the maximum frequency input signal that I can accurately track on a GPIO pin?
This all started with me wanting to use an Arduino to make a tachometer. This is all now working fine, but it got me wondering what the highest frequency digital signal that I could read?

So I built a simple test sketch and have run this on both a Nano and an ESP32. The result was about 6300Hz on both. Anything above this gives chaotic results. This is somewhat lower than I expected.

Has anybody done better than this?

# Answer
As Majenko wrote, when you only rely on software to measure the frequency on a IO pin, it will always be rather slow. And it also depends on the code, that you use. Functions like `digitalRead()` are always slower than directly working with the control registers of the pin (Reference). As you didn't show your code, we cannot say more about that.

If you need to measure higher frequencies or you want to do other things in between (like outputting the data somewhere), it is better to use the microcontrollers buildin hardware. There are multiple ways to measure the frequency. 2 immediately come to my mind:

* You could assign an ExternalInterrupt or a PinChangeInterrupt to the signal pin (limited choice of pins here), which triggers each time you see a rising (or falling) edge on the signal. In the ISR (Interrupt Service Routine) you could count up a variable. That value is the number of rising (or falling) edges, thus periods of the signal. The frequency is this value divided by the duration of the measurement. Every time you calculate the frequency, you reset the counter; reading it again after a defined duration. This should be better than just polling, but its not the best. (Note that a PinChangeInterrupt triggers on every edge, so you have to divide the frequency by 2)
* You could configure an unused Hardware Timer/Counter to use your signal as external clock source. Let it count up until it overflows (or up to a value defined by you) and let it trigger an interrupt. Since the Arduino framework already uses Timer0 for timekeeping, you could divide the max value of the Timer/Counter by the time passed and you will get the frequency. I think this can get you in the MHz range.(As with PinChangeInterrupt, the Counter will increment on every edge, so again a factor of 2 here)

Both ways will calculate the frequency as a mean over a specific time. If you have a changing frequency, you might wanna manipulate measurement frequency. In the first case you can change the interval, in which you read the counter variable. In the second case you can change the max value, to which the Timer/Counter will count.

> what the highest frequency digital signal that I could read?

(I assume you just want to read the frequency of the signal) That depends on many factors. If we use the second case from above (configuring a Hardware Timer as Counter connected to the signal) we have a limit on the maximum frequency, that we can provide. I found the relevant part in the datasheet of Atmega328p (which is the microcontroller on the Nano):

> Each half period of the external clock applied must be longer than one system clock cycle to ensure correct sampling. The external clock must be guaranteed to have less than half the system clock frequency (f ExtClk \< f clk\_I/O /2) given a 50/50% duty cycle. Since the edge detector uses sampling, the maximum frequency of an external clock it can detect is half the sampling frequency (Nyquist sampling theorem). However, due to variation of the system clock frequency and duty cycle caused by Oscillator source (crystal, resonator, and capacitors) tolerances, it is recommended that maximum frequency of an external clock source is less than f clk\_I/O /2.5.

So we should stay below the controllers clock frequency divided by 2.5, which would be `16MHz / 2.5 = 6.4MHz` for the Nano. But before you reach that, your code might introduce further delays, which make the measurement less accurate. That depends on the implementation.
> 5 votes

# Answer
My DaquinOscope https://www.daqarta.com/dw\_rroo.htm can use burst sampling to grab 1024 samples at high sample rates, then send them to a host computer over USB for display and analysis. For digital-only inputs it can acquire over 400,000 samples per second on an UNO, with each sample being a reading of 8 pins to make one byte in the record. It does this by reading a digital port (PIND or PINB) in a tight loop, with an optional delay on each read for slower sampling. DaquinOscope is free, and it uses the open-source DaqPort https://www.daqarta.com/dw\_rraa.htm, both included with Daqarta, complete with code that you can modify as desired.
> 1 votes

---
Tags: frequency, speed
---


# Question
Title: How to reset the count/data after HTTP.POST?
I have a project that records interrupts from a reed switch to nodemcu.

It records like this: 0.3,0.6,0.9,1.2 Then what I want to happen is to go back to zero when it successfully HTTP.POST to a webserver.

How can I do it? Thanks!

```
volatile float rainrate = 0.3;
volatile float total;

void count {
  total += rainrate;
}

```

# Answer
> 3 votes
Try putting your `total` variable to `0`, like this: `total = 0;` It should work like this.

---
Tags: nodemcu, http
---


title: How to put a condition on HTTP.POST?

text:
# Question
Title: How to put a condition on HTTP.POST?
I set my code to if it executes HTTP.POST, the count will reset / back to zero, but I noticed that even it returns other http code than 201 (-1 or 500), the count still resets.

How to put a condition here that `if httpResponseCode = 201 (successful), then reset (total = 0;) else http.end().`

Thanks!

```
void loop () {
  if ((millis() - lastTime) > timerDelay) {
    if (WiFi.status() == WL_CONNECTED) {
      HTTPClient http;
      http.begin(serverName);

      http.addHeader("Content-Type", "application/json");
      char temp[32];
      snprintf(temp, 32, "{\"amount\":\"%.2f\"}", total);
      int httpResponseCode = http.POST(temp);

      Serial.print("HTTP Response code: ");
      Serial.println(httpResponseCode);
      Serial.println(total);
      total = 0;

      http.end();
    }

void count () {
  total += rainrate;
}

```

# Answer
You mean something like this?

```
if( httpResponseCode==201 )
  total = 0;

```

Your entire code would then become:

```
void loop () {

  if ((millis() - lastTime) > timerDelay) {

    if(WiFi.status()== WL_CONNECTED){
      HTTPClient http;

      http.begin(serverName);

      http.addHeader("Content-Type", "application/json");

      char temp[32];
      snprintf(temp, 32, "{\"amount\":\"%.2f\"}", total);
      int httpResponseCode = http.POST(temp);

      Serial.print("HTTP Response code: ");
      Serial.println(httpResponseCode);
      Serial.println(total);

      if( httpResponseCode==201 )
        total = 0;

      http.end();
    }

void count () {
 total += rainrate;
}

```
> 1 votes

---
Tags: programming, http
---


# Question
Title: Why am I only receiving the first address byte? (I2C Protocol)
Expecting the slave to ACKnowledge and return data, but it does not. This is my protocol. This is my Datasheet.

Also FYI I'm on an Arduino Fio but I am not inheriting the Arduino library.

```
#include <avr/io.h>
#include <util/delay.h>
#include <stdlib.h>
#include <uart.h>
#include <i2c_master.h>

#define LED PB5

#define I2C_READ 0x5A

char buffer[1];

//char data[9];
uint16_t val = 0;
uint8_t status = 0;

void getVal()
{
  if(i2c_start(I2C_READ))
    {
        uart_puts("Start ");

        val = ((uint8_t)i2c_read_ack())<<8;
        val |= i2c_read_ack();

    status = ((uint8_t)i2c_read_nack());

      i2c_stop();

    } else
  {
        uart_puts("Error");

        i2c_stop();
    }
}

int main(void)
{
  init_uart(57600);
  i2c_init();

  DDRB = _BV(5);

    for(;;)
    {

      getVal();

            itoa(status, buffer, 10); //convert decimal to string base 10
            uart_puts(buffer);

      PORTB = 0xFF;
      _delay_ms(500);
      PORTB = 0x00;
      _delay_ms(500);
    }
    return 0;   /* never reached */
}

```

# Answer
(Acknowledging this is an old question.) The TI article "Troubleshooting I2C Bus Protocol", suggests several common reasons for no ACK:

```
1. Timing
2. Missing / Unexpected SCL pulses
3. Incomplete 8 bit block
4. Missing Bytes
5. False slave address
6. Unsuccessful address change

```
> 1 votes

---
Tags: i2c, c, avr
---


# Question
Title: How do I transform data for a column to data for a row, for a led matrix
I have a 8x8 led matrix. I'm using LedControl.h library to control the matrix, which has 3 ways to light up the leds: setLed, setRow and setColumn. I've found that setColumn it's really slow, it's using setLed to print columns. With all my code, I can only print 3 times a second with setColumn. The function setRow is way faster, I'm guessing that the design of the matrix is allowing to print the rows directly. I can print more than 10 times a second with setRow, so I have to use it, since speed is crucial to my project. In my code, the data i have to print is stored in an array of 8 bytes. This is how it looks like when I use setColumn

```
for(int i = 7; i >= 0; i--)
    lc.setColumn(0, i, vector[i]);

```

i is the row to be printed, and vector\[i\] is a byte value, indicating which leds to be on or off. Column 0 is the left-most one, while column 7 is the right-most one, so i go from 7 to 0 to print from right to left, because that's what I have to do. My goal is to transform somehow to data in vector\[i\], to data that I can use it using setRow. So that's what I've done so far.

```
byte mask = 128, x;
for (int j = 0; j < 8; j++){
  x = 0;
  for(int p = 0; p < 8; p++){
    x = x | (valueVector[p] & mask);
    if (p != 7)
      x = x >> 1;
  }
  if (j != 7)
  mask = mask >> 1;
  lc.setRow(0, j, x);
}

```

Now i print the rows from row 0 to row 7, from top to bottom. Since I'm printing from top to bottom, this means I have to take the last bit of every column (last bit of every element in vector), and put it in a byte variable. I was thinking to make a byte mask = 128 (b1000000, do a AND logic between to mask and the vector value in order to take the bit I'm looking for, and then making a OR to put the bit in the x byte. After every mask operation, I shift the x variable to the right, in order to make space for the next bit. After i'm done with a row, I shift the mask to the right, in order to take the second bit from the value in the vector. The result I get, is quite odd, I can't explain it, it's not good at all. What I'm i doing wrong with the mask and shifts? I hope I explained well what I'm trying to do. If necessary, I can provide more information. Thanks.

# Answer
> 1 votes
You use a mask `10000000`. With each iteration of the outer loop the `1` in the mask is shifted to the right. `01000000` -\> `00100000` -\> `00010000`. Let's say we are in the 2nd iteration the mask is `01000000`. `x = x | (valueVector[p] & mask);` takes the 2nd bit (counted from left) and sets it at the 2nd position in the x value. But this position contains the bit from the last iteration (as you shifted it to this position).

Possible solution: (I have no compiler at hand. So hopefully it is correct. ;-)

```
byte x;

for ( int j=0; j<8; j++ )
{
   x = 0;

   for ( int p=0; p<8; p++ )
     x = x | ((valueVector[p] & (1 << p)) >> p);

   lc.setRow(0, j, x);
}

```

---
Tags: arduino-mega, led
---


title: End stops for stepper motor

text:
# Question
Title: End stops for stepper motor
I need to add some end stops to this stepper motor code. I'm using one axis of a joystick to control a carriage that goes back and forth on a long screw. I have hall switches for both ends, I just want it to stop going in that direction when it triggers the switch.

I didn't write this code but it would work great if I could just add the end stops. If I have the switches connected to pins 2 and 3.

How could I write something like: if pin 2 goes high, stop motor in that direction, and then the same for pin 3 in the opposite direction?

```
#include <AccelStepper.h> // accelstepper library
AccelStepper stepper(1, 8, 9); // direction Digital 9 (CCW), pulses Digital 8 (CLK)

//Pins
const byte Analog_X_pin = A0; // x-axis readings
const byte enablePin = 7;

//Variables
int Analog_X = 0;             //x-axis value
int Analog_X_AVG = 0;         //x-axis value average
  //----------------------------------------------------------------------------
void setup() {
  Serial.begin(9600);
  //----------------------------------------------------------------------------
  //PINS
  pinMode(Analog_X_pin, INPUT);
  pinMode(enablePin, OUTPUT);
  //----------------------------------------------------------------------------
  InitialValues(); // averaging the values of the 3 analog pins (values from potmeters)
  //----------------------------------------------------------------------------
  // Stepper parameters
  // setting up some default values for maximum speed and maximum acceleration
  stepper.setMaxSpeed(2000);     //SPEED = Steps / second
  stepper.setAcceleration(1000); //ACCELERATION = Steps /(second)^2
  stepper.setSpeed(1000);
  delay(1000);
}

void loop() {
  ReadAnalog();
  stepper.runSpeed(); // step the motor (this will step the motor by 1 step at each loop indefinitely)
}

void ReadAnalog() {
  if (abs(Analog_X-Analog_X_AVG) > 50) {
    digitalWrite(enablePin, HIGH);  // enable the driver
    stepper.setSpeed(5*(Analog_X-Analog_X_AVG));
  } else {
    digitalWrite(enablePin, LOW);   // disable the driver
    stepper.setSpeed(0);
  }
  // Reading the potentiometer in the joystick:
  Analog_X = analogRead(Analog_X_pin);
  // if the value is 25 "value away" from the average (midpoint), we allow the update of the speed
  // This is a sort of a filter for the inaccuracy of the reading
  if (abs(Analog_X-Analog_X_AVG) > 50) {
    stepper.setSpeed(5 * (Analog_X-Analog_X_AVG));
  } else {
    stepper.setSpeed(0);
  }
}

void InitialValues() {
  //Set the values to zero before averaging
  float tempX = 0;
  //----------------------------------------------------------------------------
  // read the analog 50x, then calculate an average.
  // they will be the reference values
  for (int i = 0; i<50; i++) {
    tempX += analogRead(Analog_X_pin);
    delay(10); //allowing a little time between two readings
  }
  //----------------------------------------------------------------------------
  Analog_X_AVG = tempX/50;
  //----------------------------------------------------------------------------
  Serial.print("AVG_X: ");
  Serial.println(Analog_X_AVG);
  Serial.println("Calibration finished");
}

```

# Answer
> 1 votes
This is what I came up with. Note that the ReadLimits function is called after ReadAnalog and before runSpeed. In that order the stepper will not move in the direction of the limit switch, if it is pressed.

PS since you used `setAcceleration`, don't you need to call `run` instead of `runSpeed`?

```
void loop()
{
  ReadAnalog();
  ReadLimits();
  stepper.runSpeed(); //step the motor (this will step the motor by 1 step at each loop indefinitely)
}

void ReadLimits()
{
  if( digitalRead(2)==LOW && stepper.speed()>0 )//read input, assuming they have pull-up resistors.
  {
    stepper.setSpeed(0);
  }

  if( digitalRead(3)==LOW && stepper.speed()<0 )//read input, assuming they have pull-up resistors.
  {
    stepper.setSpeed(0);
  }
}

```

**edit** to avoid some confusion; here is the entire code with my suggestion embedded:

```
#include <AccelStepper.h> // accelstepper library
AccelStepper stepper(1, 8, 9); // direction Digital 9 (CCW), pulses Digital 8 (CLK)

//Pins
const byte Analog_X_pin = A0; // x-axis readings
const byte enablePin = 7;

//Variables
int Analog_X = 0;             //x-axis value
int Analog_X_AVG = 0;         //x-axis value average
  //----------------------------------------------------------------------------
void setup() {
  Serial.begin(9600);
  //----------------------------------------------------------------------------
  //PINS
  pinMode(Analog_X_pin, INPUT);
  pinMode(enablePin, OUTPUT);
  //----------------------------------------------------------------------------
  InitialValues(); // averaging the values of the 3 analog pins (values from potmeters)
  //----------------------------------------------------------------------------
  // Stepper parameters
  // setting up some default values for maximum speed and maximum acceleration
  stepper.setMaxSpeed(2000);     //SPEED = Steps / second
  stepper.setAcceleration(1000); //ACCELERATION = Steps /(second)^2
  stepper.setSpeed(1000);
  delay(1000);
}

void loop()
{
  ReadAnalog();
  ReadLimits();
  stepper.runSpeed(); //step the motor (this will step the motor by 1 step at each loop indefinitely)
}

void ReadLimits()
{
  if( digitalRead(2)==LOW && stepper.speed()>0 )//read input, assuming they have pull-up resistors.
  {
    stepper.setSpeed(0);
  }

  if( digitalRead(3)==LOW && stepper.speed()<0 )//read input, assuming they have pull-up resistors.
  {
    stepper.setSpeed(0);
  }
}

void ReadAnalog() {
  if (abs(Analog_X-Analog_X_AVG) > 50) {
    digitalWrite(enablePin, HIGH);  // enable the driver
    stepper.setSpeed(5*(Analog_X-Analog_X_AVG));
  } else {
    digitalWrite(enablePin, LOW);   // disable the driver
    stepper.setSpeed(0);
  }
  // Reading the potentiometer in the joystick:
  Analog_X = analogRead(Analog_X_pin);
  // if the value is 25 "value away" from the average (midpoint), we allow the update of the speed
  // This is a sort of a filter for the inaccuracy of the reading
  if (abs(Analog_X-Analog_X_AVG) > 50) {
    stepper.setSpeed(5 * (Analog_X-Analog_X_AVG));
  } else {
    stepper.setSpeed(0);
  }
}

void InitialValues() {
  //Set the values to zero before averaging
  float tempX = 0;
  //----------------------------------------------------------------------------
  // read the analog 50x, then calculate an average.
  // they will be the reference values
  for (int i = 0; i<50; i++) {
    tempX += analogRead(Analog_X_pin);
    delay(10); //allowing a little time between two readings
  }
  //----------------------------------------------------------------------------
  Analog_X_AVG = tempX/50;
  //----------------------------------------------------------------------------
  Serial.print("AVG_X: ");
  Serial.println(Analog_X_AVG);
  Serial.println("Calibration finished");
}

```

---
Tags: stepper-motor
---