# Question
Title: Alternative to a delay so it can be interrupted
I have task which includes a 30s delay in the void loop. During this delay I want to be able to press a key on a keypad and have a message displayed on the serial monitor as an emergency stop. Since delays block code until they are done I thought I would be able to break them down into smaller sections so I could still press the emergency stop key in between them but of course that doesn't work. I've read through how to use the milis() function but from what I can gather it seems like it wouldn't work for my system as I need user input for it so the time from the start of the Arduino to me pressing the emergency stop button is different every time. Is there a way that isn't too complicated and would allow me to press the button during that 30s?

The delay is in if (key == '2') and the last part of the sketch is the emergency stop.

```
const int greenLED = 13;  //Declares greenLED as being connected to D13
const int redLED = 12;    //Declares redLED as being connected to D12
//
const int ButtonT1 = 11;    //Declare pin number for ButtonT1 as D11
int ButtonT1State = 0;      //Variable for reading ButtonT1 state
const int ButtonT2 = 10;    //Declare pin number for ButtonT2 as D10
int ButtonT2State = 0;      //Variable for reading ButtonT2 state
//
int count_value1 = 0;       //Variable for storing counter value for turnstile 1
int count_value2 = 0;       //Variable for storing counter value for turnstile 2
//
const byte ROWS = 4;        //Four row matrix
const byte COLS = 4;        //Four columns matrix
char keys [ROWS] [COLS] = { //Defines symbols on buttons of keypad
  {'1','2','3','A'},        //Defines ROW 1
  {'4','5','6','B'},        //Defines ROW 2
  {'7','8','9','C'},        //Defines ROW 3
  {'*','0','#','D'}};       //Defines ROW 4
  byte rowPins[ROWS] = {9, 8, 7, 6};  //Pin numbres of row pinouts of the keypad
  byte colPins[COLS] = {5, 4, 3, 2};  //Pin numbers of column pinouts of the keypad
Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS);
//
void setup() { //Begin void setup, code runs once
 Serial.begin(9600);      //Begin serial transmission
 Wire.begin();            //Begin I2C wire communication protocol
 lcd.begin(16,2);         //Begin LCD with 16 columns and 2 rows
//
 pinMode(greenLED, OUTPUT);  //Set greenLED as an OUTPUT
 pinMode(redLED, OUTPUT);    //Set redLED as an OUTPUT
 pinMode(ButtonT1, INPUT);   //Set ButtonT1 as an INPUT
 pinMode(ButtonT2, INPUT);   //Set ButtonT2 as an INPUT
}
//
void loop() {                               //Begin void loop
   char key = keypad.getKey();              //Get a character key from the keypad
//
   //counter 1
    ButtonT1State = digitalRead(ButtonT1);  //Read the state of ButtonT1 -
    if (ButtonT1State == HIGH){             //Begin IF ButtonT1State is HIGH
      count_value1++;                       //IF buttonT1 pressed, increase count value
      Serial.println(count_value1);         //Print count_value1 on serial monitor
      delay(200);                           //Delay for 200ms, 0.2s
      digitalWrite(greenLED,HIGH);          //Set greenLED to HIGH,ON
      digitalWrite(redLED,LOW);             //Set redLED to LOW, OFF
 //
     if (key == '1'){                         //Wait until key '1' is pressed
    }                                         //End IF key == '1'
    ButtonT2State = digitalRead(ButtonT2);   //Read ButtonT2 state
    if (ButtonT2State == HIGH){              //Check if ButtonT2State is == HIGH
      count_value2++;                        //IF buttonT1 pressed, increase count value
      Serial.println(count_value2);          //Print count_value2 on serial monitor
      delay(500);                            //Delay for 500ms, 0.5s
//
    if(key == '2'){                            //Wait untill key '2' is pressed - confirm ride is ready
      Serial.println("Ride starting - 30s");   //Print message in brackets on serial monitor
//30s delay, broken into smaller delays
      delay(10000);
     Serial.println("20s left");
      delay(10000);
      Serial.println("10s left");
      delay(10000);
      Serial.println("Ride finished");        //Print message in brackets on serial monitor
      delay(100);                             //Delay for 1000ms, 1s
    }                                         //End if key == '2'
//
    if (key == '4'){                        //Wait until key '4' is pressed - emergency stop
      Serial.println("Emergency stop");     //Print message in brackets on serial monitor
      digitalWrite(redLED,HIGH);            //Set redLED to HIGH,ON
      digitalWrite(greenLED,LOW);           //Set greenLED to LOW,OFF
      lcd.clear();                          //Clear i2c LCD
      lcd.setCursor(0,0);                   //Set cursor to column 0, row 0
      lcd.print("Emergency stop");          //Print message in brackets on i2c LCD
      count_value2 = 0;                     //Set count_value2 to 0
      delay(1000);                          //Delay for 1000ms, 1s
    }                                       //End IF key == '4'
}

```

# Answer
Make a statemachine.

Take a piece of paper and draw out the order of operation and each time you are waiting you specify what each button will do.

So for example each time button 1 is pushed you increment the counter and change the display.

When waiting for a timeout you check `if(startTimestamp - millis() > timeout)` for the next step.

Then give each waiting state a number and put a big switch on a global at the start of the `loop()` and update the global each time the state needs to change.
> 1 votes

---
Tags: interrupt, keypad
---


# Question
Title: How to improve the sampling rate of Arduino due ADC?
I am now working on a project, which needs a cheap analog acquisition device with a sampling rate of no less than 5MHz. Before, I only used Arduino, and rarely operated the registers on Arduino. I hope to use Arduino due to complete it. I spent a lot of time researching and querying solutions, but it didn't succeed. I hope someone can help me.

# Answer
I haven't used the Due, but I understand its ADC is rated for 1 MHz sampling. If that's its absolute limit then you can't expect 5 MHz. However, judging by the Unos which I have used, you may be able to push things by limiting the number of bits. This gives a speed boost two ways, by shortening the time the ADC uses to acquire the data, and if you limit to 8 bits you have half as many bytes to move into memory.

Do *not* try to use more than one channel, since then you have multiplexer delays as well.

Also, you may want to skip interrupts and just sample in a tight loop. Using this loop trick doubles the useful ADC rate of the Uno, from 50 kHz to over 100 kHz. (You'll need to figure out the actual sample rate by reading the timer before and after the loop, then divide by the loop size and take the reciprocal.)
> 2 votes

---
Tags: arduino-due
---


title: IR receiver receives only 0

text:
# Question
Title: IR receiver receives only 0
I am trying to decode IR codes of my Samsung tv remote
But the receiver always receiving "0"
Schematics:

Code:

```
#include <IRremote.h>

int RECV_PIN = 11;
IRrecv irrecv(RECV_PIN);
decode_results results;

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

void loop()
{
  if (irrecv.decode(&results))
    {
    int value = results.value;
    Serial.println(" ");
    Serial.print("Code: ");
    Serial.println(results.value);
    Serial.println(" ");
    irrecv.resume();
    Serial.println("*****************");
    }
}

```

Please help me to decode my IR codes

# Answer
Next update with 3.1 of the library, you need to call `irrecv.decodedIRData.decodedRawData` to get the data. This code worked for me:

```
#include <IRremote.h>

int IRpin = 11;
IRrecv irrecv(IRpin);

void setup()
{
  Serial.begin(9600);
  irrecv.enableIRIn(); // Start the receiver
}

void loop()
{
  if (irrecv.decode())
    {
      Serial.println(irrecv.decodedIRData.decodedRawData); // Print the Serial
      irrecv.resume();   // Receive the next value
    }
}

```
> 1 votes

---
Tags: arduino-uno, sensors, ir, remote-control
---


# Question
Title: ESP32 Arduino Bluetooth Serial does not reconnect after disconnecting
The basic ESP32 Arduino Bluetooth Serial example pairs and connects as expected, BUT once I disconnect the Bluetooth terminal it stops responding to new events at all,

once I reset the esp32, it starts working again with the same problem. (it doesn't matter if it keeps being paired or not)

I have tested it with the windows Bluetooth terminal and with the Bluetooth Any terminal. (from the windows store)

I have downloaded the latest esp32-Arduino library from GitHub and I still get the same problem.

I have tested it with several esp32 modules, and they all respond with the same problem.

So it looks like a bug in the library code.

See the simple Arduino example code below:

```
#include "BluetoothSerial.h"

#if !defined(CONFIG_BT_ENABLED) || !defined(CONFIG_BLUEDROID_ENABLED) #error Bluetooth is not enabled! Please run make menuconfig to and enable it #endif

BluetoothSerial SerialBT;

void setup() { Serial.begin(115200); SerialBT.begin("ESP32test"); //Bluetooth device name Serial.println("The device started, now you can pair it with bluetooth!"); }

void loop() { if (Serial.available()) { SerialBT.write(Serial.read()); } if (SerialBT.available()) { Serial.write(SerialBT.read()); } delay(20); }

```

Does anyone know of another Bluetooth serial library that does work?

Thank You!

# Answer
> 1 votes
Nothing wrong with your code, I've the exact same issue as you have. It bothers me whole week long and fortunately, we (along with my colleague) accidentally figured that was caused by Windows 10, weird right? We don't believe it at very beginning either, but after several back-N-forth testing, it just like that. When we upload exact same code from another older computer with Windows 7 OS, it just works no matter how many time we connect/disconnect or even "QUIT" the APP without make it disconnect properly, its been able to be reconnect no problem. But once we use new computer with Windows 10 OS to upload the code, it can only be connected for first time, then stop broadcasting (or advertising). The arduino official website in IDE download page also has a notice message "IMPORTANT: This app performs with core functionality on Windows 10 S but some limited plugins do not work. We are working with Microsoft on a fix.", hope this information helps.

---
Tags: serial, bluetooth, esp32, library, esp
---


# Question
Title: UART between arduino UNO and pc via USB not in sync
I connected my arduino uno to my system and then using serial tried writing and reading data but there is a problem which I found when I tried giving arduino crafted messages. My arduino code is pretty simple.

```
void setup() {
  Serial.begin(115200);

}

void loop() {
  if (Serial.available() > 0) {
    String data = Serial.readStringUntil('\n');
    Serial.print(" You sent me: ");
    Serial.println(data);
  }
}

```

and my python code on my system

```
#!/usr/bin/env python3
import serial
import time

if __name__ == '__main__':
    ser = serial.Serial('/dev/ttyACM0', 115200, timeout=1)
    ser.flush()

    while True:
        string=input("Enter the string: ")
        ser.write(str.encode(string))
        line = ser.readline().decode('utf-8').rstrip()
        print(line)
        time.sleep(0.01)

```

Now this gives me ability to write instructions to my arduino but following sequences of communication occur

```
└──╼ $python3 serial_communication.py
Enter the string: a

Enter the string: v

Enter the string: v
 You sent me: v
Enter the string: s
 You sent me: v
Enter the string: d

Enter the string: r
 You sent me: sd
Enter the string: d
 You sent me: r
Enter the string: s

Enter the string: e
 You sent me: ds
Enter the string: r
 You sent me: e
Enter the string:

```

Looking at them I understand that this might be a problem with my code or I am using the wrong protocol.

# Answer
> 1 votes
There's a number of things going on here that combined give you the results you're seeing.

First off there's the delay at the start:

```
Enter the string: a

Enter the string: v

Enter the string: v
 You sent me: v
Enter the string: s
 You sent me: v

```

This is because when you first open the serial port the Arduino resets and enters the bootloader. Thus the first few things that get sent are discarded, and nothing is sent back from the Arduino - your sketch just isn't running at that point.

Next is the format of what you're sending compared to how you're receiving it.

You input a string and then send that string verbatim. But on the Arduino you are reading all data up until a terminating newline character, *which you are not sending*.

But the reading function also has a timeout in it so it will return whatever it has managed to read in that time even if the terminator hasn't arrived. That timeout is 1 second by default.

So everything that gets sent within a 1 second window gets grouped together, which is what you see here:

```
Enter the string: d
 You sent me: r
Enter the string: s

Enter the string: e
 You sent me: ds

```

The "out of sync" appearance is because of that 1 second timeout - you are seeing what was sent a second ago.

The fix is simple enough: make sure that you send the terminating newline character from Python:

```
ser.write(str.encode(string + "\n"))

```

And wait a few seconds after starting your program and opening the serial port before asking for anything to be sent. Maybe add a `time.sleep(2)` after opening the port to enforce that delay.

---
Tags: arduino-uno, uart
---


# Question
Title: WS2812B Led Digital Panel Matrix Flexible Screen 8*8. Some LEDs that are not supposed to, switch on
My project is composed of an ESP32, a level converter and two WS2812B Led Digital Panel Matrix Flexible Screen 8\*8 (from Aliexpress) interconnected with the provided cable. My objective is to show a score, no scrolling or any other animation.

The main functionality works ok, I can display any decimal number between 00 to 99 (one digit in each 8x8 panel).

My problem is that apart from the digits printed, some not so aleatory LEDs switch on, not necessarily on the same color as the intended number, nor on the selected luminosity. Changing the number changes this undesirable pattern that seems to repeat for the same number on the same 8x8 matrix. Problem patters does not follow a specific 8x8 matrix, the problem does not seem to be in the hardware.

The level converter converts the ESP32 3.3v to 5v required by the Matrix but even before I connected the level converter the problem was the same.

The code I am using is as below:

```
#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
  #include <avr/power.h>
#endif

// Which pin on the Arduino is connected to the NeoPixels?
#define PIN            14

// How many NeoPixels are attached to the Arduino?
#define NUMPIXELS      128

Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);

int delayval = 10; // delay for half a second

void setup() {
  pixels.begin(); // This initializes the NeoPixel library.
}

void loop() {

  // For a set of NeoPixels the first NeoPixel is 0, second is 1, all the way up to the count of pixels minus one.
  pixels.clear();
  pixels.setBrightness(1);

  boolean N0[8][8] PROGMEM = {{0,0,1,1,1,1,0,0},{0,1,1,1,1,1,1,0},{0,1,1,0,0,1,1,0},{0,1,1,0,0,1,1,0},{0,1,1,0,0,1,1,0},{0,1,1,0,0,1,1,0},{0,1,1,1,1,1,1,0},{0,0,1,1,1,1,0,0}};
  boolean N1[8][8] PROGMEM = {{0,0,0,1,1,0,0,0},{0,0,1,1,1,0,0,0},{0,0,0,1,1,0,0,0},{0,0,0,1,1,0,0,0},{0,0,0,1,1,0,0,0},{0,0,0,1,1,0,0,0},{0,1,1,1,1,1,1,0},{0,1,1,1,1,1,1,0}};
  boolean N2[8][8] PROGMEM = {{0,0,1,1,1,1,0,0},{0,1,1,0,0,1,1,0},{0,1,1,0,0,0,0,0},{0,0,1,1,1,1,0,0},{0,0,0,0,0,1,1,0},{0,1,1,0,0,0,1,0},{0,1,1,1,1,1,1,0},{0,1,1,1,1,1,1,0}};
  boolean N3[8][8] PROGMEM = {{0,0,1,1,1,1,0,0},{0,1,1,0,0,1,1,0},{0,1,1,0,0,0,0,0},{0,0,1,1,1,1,0,0},{0,0,1,1,1,1,0,0},{0,0,0,0,0,1,1,0},{0,1,1,0,0,1,1,0},{0,0,1,1,1,1,0,0}};
  boolean N4[8][8] PROGMEM = {{0,0,1,1,1,0,0,0},{0,0,1,1,1,1,0,0},{0,0,1,1,0,1,1,0},{1,1,0,0,1,1,0,0},{0,1,1,1,1,1,1,1},{0,0,0,0,1,1,0,0},{0,1,1,1,1,0,0,0},{0,0,0,1,1,1,1,0}};
  boolean N5[8][8] PROGMEM = {{0,0,1,1,1,1,1,0},{0,1,1,1,1,1,1,0},{0,0,0,0,0,1,1,0},{0,1,1,1,1,1,0,0},{0,1,1,0,0,1,1,0},{0,0,0,0,0,1,1,0},{0,1,1,0,0,1,1,0},{0,0,1,1,1,1,0,0}};
  boolean N6[8][8] PROGMEM = {{0,0,1,1,1,0,0,0},{0,0,1,1,0,0,1,0},{0,0,0,0,0,1,1,0},{0,1,1,1,1,1,0,0},{0,1,1,0,0,1,1,0},{0,1,1,0,0,1,1,0},{0,0,1,1,1,1,0,0},{0,0,0,1,1,0,0,0}};
  boolean N7[8][8] PROGMEM = {{0,1,1,1,1,1,1,0},{0,1,1,0,0,1,1,0},{0,0,1,1,0,0,0,0},{0,0,0,1,1,0,0,0},{0,0,0,0,1,1,0,0},{0,0,1,1,0,0,0,0},{0,0,0,0,1,1,0,0},{0,0,1,1,0,0,0,0}};
  boolean N8[8][8] PROGMEM = {{0,0,1,1,1,1,0,0},{0,1,1,0,0,1,1,0},{0,1,1,0,0,1,1,0},{0,0,1,1,1,1,0,0},{0,1,1,0,0,1,1,0},{0,1,1,0,0,1,1,0},{0,1,1,0,0,1,1,0},{0,0,1,1,1,1,0,0}};
  boolean N9[8][8] PROGMEM = {{0,0,1,1,1,1,0,0},{0,1,1,0,0,1,1,0},{0,1,1,0,0,1,1,0},{0,0,1,1,1,1,1,0},{0,1,1,0,0,0,0,0},{0,0,0,0,0,1,1,0},{0,1,1,1,0,0,1,0},{0,0,1,1,1,1,0,0}};

  int counter = 0;
  for(int line=0;line<8;line++){
    for(int column=0;column<8;column++){
      if(N2[line][column]==1){
        pixels.setPixelColor(counter, pixels.Color(0,255,0));
        pixels.show();
        delay(delayval);
      }

      if(N1[line][column]==1){
        pixels.setPixelColor(counter+64, pixels.Color(255,33,255));
        pixels.show();
        delay(delayval);
      }

      counter++;
    }
  }
  while(1){};
}

```

This is a non optimized code for testing purposes only. What am I doing wrong?

# Answer
> 3 votes
Found the Adafruit NeoPixel is the reason for the problem (or the way it is implemented above is not the best).

Solved with the fastLED library as below:

```
#include "FastLED.h"
#define NUM_LEDS 128
#define DATA_PIN 14
#define BRIGHTNESS 10
CRGB leds[NUM_LEDS];
int delayval = 10; // delay for half a second

boolean N0[8][8] PROGMEM = {{0,0,1,1,1,1,0,0},{0,1,1,1,1,1,1,0},{0,1,1,0,0,1,1,0},{0,1,1,0,0,1,1,0},{0,1,1,0,0,1,1,0},{0,1,1,0,0,1,1,0},{0,1,1,1,1,1,1,0},{0,0,1,1,1,1,0,0}};
boolean N1[8][8] PROGMEM = {{0,0,0,1,1,0,0,0},{0,0,1,1,1,0,0,0},{0,0,0,1,1,0,0,0},{0,0,0,1,1,0,0,0},{0,0,0,1,1,0,0,0},{0,0,0,1,1,0,0,0},{0,1,1,1,1,1,1,0},{0,1,1,1,1,1,1,0}};
boolean N2[8][8] PROGMEM = {{0,0,1,1,1,1,0,0},{0,1,1,0,0,1,1,0},{0,1,1,0,0,0,0,0},{0,0,1,1,1,1,0,0},{0,0,0,0,0,1,1,0},{0,1,1,0,0,0,1,0},{0,1,1,1,1,1,1,0},{0,1,1,1,1,1,1,0}};
boolean N3[8][8] PROGMEM = {{0,0,1,1,1,1,0,0},{0,1,1,0,0,1,1,0},{0,1,1,0,0,0,0,0},{0,0,1,1,1,1,0,0},{0,0,1,1,1,1,0,0},{0,0,0,0,0,1,1,0},{0,1,1,0,0,1,1,0},{0,0,1,1,1,1,0,0}};
boolean N4[8][8] PROGMEM = {{0,0,1,1,1,0,0,0},{0,0,1,1,1,1,0,0},{0,0,1,1,0,1,1,0},{1,1,0,0,1,1,0,0},{0,1,1,1,1,1,1,1},{0,0,0,0,1,1,0,0},{0,1,1,1,1,0,0,0},{0,0,0,1,1,1,1,0}};
boolean N5[8][8] PROGMEM = {{0,0,1,1,1,1,1,0},{0,1,1,1,1,1,1,0},{0,0,0,0,0,1,1,0},{0,1,1,1,1,1,0,0},{0,1,1,0,0,1,1,0},{0,0,0,0,0,1,1,0},{0,1,1,0,0,1,1,0},{0,0,1,1,1,1,0,0}};
boolean N6[8][8] PROGMEM = {{0,0,1,1,1,0,0,0},{0,0,1,1,0,0,1,0},{0,0,0,0,0,1,1,0},{0,1,1,1,1,1,0,0},{0,1,1,0,0,1,1,0},{0,1,1,0,0,1,1,0},{0,0,1,1,1,1,0,0},{0,0,0,1,1,0,0,0}};
boolean N7[8][8] PROGMEM = {{0,1,1,1,1,1,1,0},{0,1,1,0,0,1,1,0},{0,0,1,1,0,0,0,0},{0,0,0,1,1,0,0,0},{0,0,0,0,1,1,0,0},{0,0,1,1,0,0,0,0},{0,0,0,0,1,1,0,0},{0,0,1,1,0,0,0,0}};
boolean N8[8][8] PROGMEM = {{0,0,1,1,1,1,0,0},{0,1,1,0,0,1,1,0},{0,1,1,0,0,1,1,0},{0,0,1,1,1,1,0,0},{0,1,1,0,0,1,1,0},{0,1,1,0,0,1,1,0},{0,1,1,0,0,1,1,0},{0,0,1,1,1,1,0,0}};
boolean N9[8][8] PROGMEM = {{0,0,1,1,1,1,0,0},{0,1,1,0,0,1,1,0},{0,1,1,0,0,1,1,0},{0,0,1,1,1,1,1,0},{0,1,1,0,0,0,0,0},{0,0,0,0,0,1,1,0},{0,1,1,1,0,0,1,0},{0,0,1,1,1,1,0,0}};

void setup() {
  FastLED.setBrightness( BRIGHTNESS );
  FastLED.addLeds<WS2812B, DATA_PIN, RGB>(leds, NUM_LEDS);
}

void loop() {
  int counter = 0;
  for(int line=0;line<8;line++){
    for(int column=0;column<8;column++){
      if(N2[line][column]==1){
        leds[counter] = CRGB::Yellow;
        FastLED.show();
        delay(delayval);
      }

      if(N1[line][column]==1){
        leds[counter+64] = CRGB::Green;
        FastLED.show();
        delay(delayval);
      }

      counter++;
    }
  }
  while(1){};
}

```

---
Tags: led, esp32
---


# Question
Title: Servomotor and Bluetooth module block each other
For a small project, I aim to connect a **digital temperature sensor (KY-028)**, a **Bluetooth module (HC-05)** and a **servomotor (SG90)**. The problem is it seems I can't connect the Bluetooth module and the servomotor together at the same time. The Bluetooth module together with the temperature sensor works fine. The servo with the sensor, again, all fine. But it seems these two don't agree with each other: as soon as I upload the code on the board **(Arduino UNO)**, the servo starts vibrating (not even rotating), altough I made sure no command that asks it to do so is reached. Also while doing this, the Bluetooth module's led is turned off and it is unrecognizable by other devices.

When I upload the program to the board, I disconnect the RX and TX pins of the Bluetooth module from the pins 0 & 1 of the Arduino board, (otherwise I get errors and the program is not uploaded - if needed, I will get the error codes I get and edit the post), but after upload, the servo starts behaving weird, as described before. As I read on another article (if I manage to find the link again I will post it here), it might behave like this because there are unconnected pins in my whole circuit (which is true, but otherwise I can't connect the Bluetooth module). How could I possibly connect both of them on the same board?

I tested the code segments, they act as they should, I tried switching the pins so that I did not miss anything by mistake, as I am a total beginner (for instance I tried putting the signal wire of the servo on both PWM and not PWM supporting pins, tried connecting the Bluetooth module and the servo to different grounds etc.) but no success.

Any help would be much appreciated. If the layout of my circuit is needed, I will try to make one in a simulator. Thank you very much!

**Edit**

Here is the code:

```
#include <Servo.h>
#include <SoftwareSerial.h>

int txPin = 1;
int rxPin = 0;
int digitalPin = 7; // KY-028 digital interface
int analogPin = A2; // KY-028 analog interface
int angle = 0;
int temp;
bool incTemp = false, decTemp = false;

Servo servo;
SoftwareSerial BT(txPin,rxPin);

void setup() {
  pinMode(digitalPin, INPUT);
  pinMode(analogPin, INPUT);

  servo.attach(11);
  delay(100);

  BT.begin(9600);
  Serial.begin(9600);
}

void loop() {
  temp = analogRead(analogPin);
  Serial.println(temp);

  if (BT.available())
  {
    char bytesToSend[2];
    bytesToSend[0] = 101;
    bytesToSend[1] = temp;
    bytesToSend[2] = 110;
    BT.println(bytesToSend);
  }

  if(incTemp)
  {
    servo.write(90);
    delay(100);
    servo.write(135);
    delay(100);
    servo.write(180);
    delay(100);
    servo.write(135);
    delay(100);
  }
  else if(decTemp)
  {
    servo.write(90);
    delay(100);
    servo.write(45);
    delay(100);
    servo.write(0);
    delay(100);
    servo.write(45);
    delay(100);
  }

  delay(2000);
}

```

For the incTemp and decTemp variables I will use an interrupt to detect when the Bluetooth paired device is sending a command to activate the servomotor. But for now, as it can be seen, the blocks that ask the servo to rotate cannot be reached. For the layout I will try to find a simulator that provides the components I use and I will come back with the design.

**Later edit**, after following ***Majenko***'s advice

Here is the currently working code. An answer with the full implementation will come when the project is complete.

```
#include <Servo.h>

int txPin = 1;
int rxPin = 0;
int digitalPin = 7; // KY-028 digital interface
int analogPin = A2; // KY-028 analog interface
int angle = 0;
int temp;
bool incTemp = false, decTemp = false;

Servo servo;

void setup() {
  pinMode(digitalPin, INPUT);
  pinMode(analogPin, INPUT);

  Serial.begin(9600);
}

void loop() {
  temp = analogRead(analogPin);
  Serial.print("T");
  Serial.print(temp);
  Serial.println();

  if(incTemp)
  {
    servo.attach(11);
    delay(100);

    servo.write(90);
    delay(100);
    servo.write(135);
    delay(100);
    servo.write(180);
    delay(100);
    servo.write(135);
    delay(100);

    servo.detach();
    delay(100);
  }
  else if(decTemp)
  {
    servo.attach(11);
    delay(100);

    servo.write(90);
    delay(100);
    servo.write(45);
    delay(100);
    servo.write(0);
    delay(100);
    servo.write(45);
    delay(100);

    servo.detach();
    delay(100);
  }

  delay(2000);
}

```

# Answer
So, I got carried away with my exams and I forgot to come back with an update and a solution. To take it short, I added a new source of power to the circuit and I am only turning the servo on when needed to rotate, then turn it off again. The code can be seen below:

```
#include <Servo.h>
#include <SoftwareSerial.h>

int rxPin = 2;
int txPin = 3;
int digitalPin = 7; // KY-028 digital interface
int analogPin = A2; // KY-028 analog interface
int servoPin = 11;

int angle = 0;
int temp;

const int minTemp = 150;
const int maxTemp = 350;
const int minAngle = 0;
const int maxAngle = 180;
const char sendDataPackageStartByte = 'T';
const int receiveDataPackageStartByteVal = 83; //"S"
const int receiveDataPackageEndByteVal = 13;
const int communicationDelay = 1000;
const int servoDelay = 100;

SoftwareSerial BT(rxPin,txPin);

Servo servo;
void setup() {
  pinMode(digitalPin, INPUT);
  pinMode(analogPin, INPUT);

  Serial.begin(9600);
  BT.begin(9600);
}

void loop() {
  if(BT.available() <= 0)
  {
    temp = analogRead(analogPin);
    BT.print(sendDataPackageStartByte);
    BT.print(temp/100);
    BT.print(temp/10%10);
    BT.print(temp%10);
    BT.println();
    delay(communicationDelay);
  }
  else
  {
    readData();
  }
}

void readData()
{
  if (BT.available())
  {
    char temp[3];
    while(BT.available() > 0)
    {
      char crtByte = BT.read();
      if (crtByte == receiveDataPackageStartByteVal)
      {
        temp[0] = BT.read();
        temp[1] = BT.read();
        temp[2] = BT.read();

        if(BT.read() != receiveDataPackageEndByteVal)
        {
          return;
        }

        break;
      }
    }

    int desiredTemp = atoi(temp);
    int desiredAngle = map(desiredTemp, minTemp, maxTemp, minAngle, maxAngle);
    printDataToSerial(desiredTemp, desiredAngle);

    turnServo(desiredAngle); //attach servo, write value, dettach
  }
}

void printDataToSerial(int desiredTemp, int desiredAngle)
{
  Serial.println("Desired Temperature:");
  Serial.println(desiredTemp);

  Serial.println("Desired Angle:");
  Serial.println(desiredAngle);
}

void turnServo(int angle)
{
  servo.attach(servoPin);
  delay(servoDelay);
  servo.write(angle);
  delay(servoDelay);
  servo.detach();
  delay(servoDelay);
}

```

Also, here would be the layout of my final circuit:

Basically what I wanted to achieve was sending and displaying the current temperature from an Arduino device to an Android one, then allow the user to adjust the temperature, simulating this with a servo commanded over Bluetooth. For those interested in the Android part as well (and the whole project actually), here is the link to the project repository on GitHub. The Android part is written with C# in the Xamarin Android framework. I hope this helps anyone landing here, good luck! :D
> 1 votes

---
Tags: arduino-uno, bluetooth, servo, temperature-sensor
---


# Question
Title: Arduino SD card cannot write (writes crap files and then I get error)
I am developing a very simple project to measure some temperatures and store them in an SD card. I have a problem trying to write. No matter what I do the SD card always ends up with content like this:

And in read only mode. I have formatted it in FAT16, FAT32, in Windows an Ubuntu and always the same. I have changed between two different Arduino UNO boards, two different SD modules connected like this:

and extremly simple codes like this example and I always get the same.

**Detailed example of what I do and what I get**

I have wrote this simple code to test:

```
#include <SD.h>
#define CHIP_SELECT_PIN 10
/* CIRCUITO ----------------
* SD card attached to SPI bus as follows:
* MOSI - pin 11
* MISO - pin 12
* CLK - pin 13
* CS - pin 10. */
File archivo;
char cadena[20];
char c;
void setup(void) {
Serial.begin(9600);
while (!Serial) {;} // Esperar a que se inicialice la comunicacion serial
      while (Serial.read() >= 0) {;} // Limpiar el buffer
// INICIALIZAR LA MEMORIA ----------------------------------------
Serial.print("Initializing SD card... ");
pinMode(CHIP_SELECT_PIN, OUTPUT);
if (!SD.begin(CHIP_SELECT_PIN)) {
  Serial.println("Unable to initialize. Remove the card.");
  while (1);
}
Serial.println("OK!");
// ABRIR UN ARCHIVO PARA ESCRIBIR --------------------------------
if (SD.exists("ARCHIVO.TXT")) {
  Serial.println("Deleting existing file with the same name. ");
  SD.remove("ARCHIVO.TXT");
}
Serial.print("Creating new file... ");
if (!(archivo = SD.open("ARCHIVO.TXT", FILE_WRITE))) {
  Serial.println("Unable to create the file. Remove the card.");
  while (1);
}
Serial.println("File successfully created. ");
Serial.print("Send a string to store in the card... ");
while (Serial.available() == 0); // Nos quedamos esperando a que nos manden el numero
leerCadena('\n', cadena, 19);
Serial.print("The following string was received: \" ");
Serial.print(cadena);
Serial.println("\"");
archivo.print(cadena);
archivo.close();
Serial.println("The string was successfully stored in the card. ");
// Lectura de los datos guardados en la memoria ------------
Serial.print("Preparing to read data in card... ");
if (!(archivo = SD.open("ARCHIVO.TXT", FILE_READ))) {
  Serial.println("Cannot open file to read. Remove the card. ");
  while(1);
}
Serial.print("The string stored in memory is: \"");
while ((c = archivo.read()) >= 0) {
  Serial.print(c);
}
Serial.println("\"");
archivo.close();
Serial.println("Remove the card.");
while(1);
}
void loop(void) {}
void leerCadena (char corte, char* cadena, byte n_bytes) {
  byte n_leidos;
  n_leidos = Serial.readBytesUntil(corte, cadena, n_bytes);
  cadena[n_leidos] = '\0';
  delay(100);
  while (Serial.read() >= 0) {;}
}

```

and what I am doing and getting is:

1. First I format my SD card in FAT32 using Gparted (the same happens if I format it in FAT16 or 32 both in Ubuntu and Windows).
2. I test the SD card in my computer.  It works perfectly. I can remove it and plug it again and the data is there. Everything OK.
3. I put the card in the SD slot connected to Arduino and run the above program. What I get through the serial monitor is
4. Now I remove the card from Arduino and insert it into my computer. This is its content:  The file "readme.txt" contains the same text as before. The file "ARCHIVO.TXT" is empty. The binary files vary in size, e.g. the second one is 3 GB and fourth one is 774 MB.
5. Now I try to modify the content in "readme.txt" and I get this:  I cannot delete files either.
6. I remove the SD card from my computer and insert it again into Ardino. Reset the board and through the serial port I get:
7. Now the content of the card seen in the computer is different:  and the file "ARCHIVO.TXT" is not present.
8. If I put the card again in Arduino and reset the board everything repeats from step number 3. I mean, it creates the file "ARCHIVO.TXT" among with the other strange files, in the next time I put it into Arduino it deletes the file "ARCHIVO.txt", and so on.

If after all this I format the SD card in my computer, we are back in step number 1.

I am about giving up with Arduino and the SD module and go to a Raspberry. But it is much more expensive for this extremly simple task I need to do...

# Answer
> 1 votes
The problem was magically solved. I think the cables were the causing this issue. I was using cables of about 15 cm, now changed them to 5 cm and is working perfectly.

# Answer
> 1 votes
-Did you change the CS pin in the code to 10? -It can be a problem with the SD card, try another and tell us. -After the "dataFile.close();" put: "if(dataFile)Serial.println("not closed");" and watch the serial monitor window.

# Answer
> 1 votes
You have to guarantee that the file.txt is not opened before you shutdown the power or take the SD card off. I recomend you firstly, to do a "for" loop to stop in "X" iterations. If it works, you can put then a push-button in your project to stop any time.

# Answer
> 1 votes
I had the same problem (using a UNO with the MH-SD module directly connected to the arduino). The module apparently correctly initialised and I could list the files that were already there but when I attempted to create a single blank file ready for reading, a whole bunch of random named files were created many of which were enormous (according to my PC, although it said they all corrupted and couldn't open any of them). And then the card wasn't recognised when I tried using it again and had to be reformatted. I eventually found that one of the wires I was using, specifically the one to GND adjacent to MISO, was faulty. I suspect the length of the cables is irrelevant, I think that user171780 had a faulty cable in the same position.

# Answer
> 1 votes
I change voltage from 5V to 3.3V and move GND to the GND pin near the 3.3V. Now I can write and read a text file on a SD card.

# Answer
> 0 votes
I think maybe the problem comes from the SD module you use. I have used the SD module just like you.And I can not write or read data successfully. More seriousely, my card broken and the damage is permanent.This connect is the new SD module I use, and I use successfully. You can dry by yourself. https://www.qutaojiao.com/8515.html?fbclid=IwAR0T9dFoAOyJhTCSOHeDWQTE\_Iuq8l5eGN9ByYth2uPmIyzC2bHLdt0\_cKk

---
Tags: arduino-uno, sd-card
---


title: ESP32 millis not working properly

text:
# Question
Title: ESP32 millis not working properly
I have a program which measures temperatures every 30 minutes and sends them to a database. Immediately after running the program the first measurement is sent, however, the second (which should be sent after 30 min), is sent only after 1 hour. From then on the code works fine. The time is measured in millis. However, if I set the time difference to 28 minutes everything works fine from the beginning. What could be the reason for this? Is there a possibility that it goes to sleep mode? I don't understand why it works fine with 28 minutes and it stops working with 29 minutes?

Thanks in advance!

My code:

```
if (millis() - sendDataPrevMillis > 1740000)
  {
    sendDataPrevMillis = millis();

//other code

}

```

The only part I change, so it works is setting millis from 1740000 (29 minutes) to 1680000 (28 minutes).

# Answer
1. Although not strictly required, maybe use parentheses around `millis() - sendDataPrevMillis` for readability;
2. I guess you will have initialised `sendDataPrevMillis` to 0 but the first time you assign `sendDataPrevMillis` to `millis()` some time will have elapsed since you evaluated. So calling `millis()` twice will give different results. That makes it less easy to see what is going on.

Suggestion to try:

```
long HALFHOUR = 30 * 60 * 1000L;

if ( (millis() % HALFHOUR ) == 0L ) {
    //measure and send
    //....
}

```

Hope this helps.

NB: `%` is what is called the 'modulo operator' see: https://www.geeksforgeeks.org/modulo-operator-in-c-cpp-with-examples/
> -1 votes

---
Tags: esp8266, arduino-ide, esp32, millis
---


# Question
Title: How does one wire OV7670 camera with Arduino Due?
The parts that I want to interface together are:

* Arduino Due
* OV7670 Camera Module
* 3.5" TFT Touchscreen LCD (uses MCUFRIEND\_kbv library)

My goal is to get the video feed from the camera to the LCD screen. Any help will be appreciated.

# Answer
> 1 votes
I am working with small project same in little bit like what you trying to do..

starting with.. 1- Arduino UNO + OV7670 + 2.4" TFT LCD (I got not clear live Image)..

so I made some changes.. 2- Arduino DUE + OV7670 Live Image (still working with, having problem in reading Image) want to compile the result Image (convert it to text) then sending the result to (3) by serial Port 3- Arduino UNO + 3.5" TFT LCD (it works)..

by the way Arduino UNO + OV7670 Live Image (worked perfectly), but I am trying to get same project using DUE.. (faster speed & maybe could deal with Image too..)

here link of how OV7670 work with Arduino DUE.. https://www.instructables.com/How-to-Connect-OV7670-to-Arduino-Due/ .....

---
Tags: arduino-due
---


title: How to build and run AUnit tests

text:
# Question
Title: How to build and run AUnit tests
I found this example on how to create a project with AUnit tests: https://www.thecoderscorner.com/electronics/microcontrollers/embedded-testing/getting-started-unittesting-arduino/

According to it and projects I have found on github my project structure should look like this:

```
Application
    src
        SomeComponent.cpp
        SomeComponent.h
    tests
        TestSomeComponent
            TestSomeComponent.ino
    Application.ino

```

But when I try to run TestSomeComponent.ino with Arduino IDE or VSC with Arduino plugin it does not see contents of src folder. I am assuming that it is treated as a separate sketch. What is a proper way to build and run tests?

\[edit\] Some context (not sure what matters):

* Our target board is ESP32 DevKit v1
* Optimally if our developers could run tests on Windows and Linux machines
* I have not gotten yet to continuous integration. I will start automating once I have any test building and running

\[edit 2\] I have tried command line tools. Got AUniter running and tried like this (hoping for some automagic done by tools):

```
me@mypc:~/workspace/Application/Application/tests$ auniter.sh test esp32:/dev/ttyUSB0 TestSomeComponent/

```

I have tried any sane path combination in include path directive, for example:

```
#include "SomeComponent.h"
#include "app/SomeComponent.h"
#include "../../src/app/SomeComponent.h"
#include <SomeComponent.h>
#include <app/SomeComponent.h>
#include <../../src/app/SomeComponent.h>

```

But I keep getting this:

```
TestSomeComponent:4:42: fatal error: ../../src/app/SomeComponent.h: No such file or directory

```

# Answer
I eventually switched to PlatformIO. It took me less than half an hour to rearrange sources, fix some compiler issues, build and flash my device. Tests work really well. You just need to keep tested sources in lib folder. I even got GoogleTest package so I can use gmock in my tests.
> 1 votes

---
Tags: testing
---


# Question
Title: MCU Recommendations for Audio Pitch Shifting
I'm looking to use a MCU for audio sampling. I want to sample incoming audio and pitch shift it (without speeding it up/slowing it down). A bit about the build. I'm planning to make a circuit board that can take in a single audio source and output three or four different pitch-shifted sounds in real time, with each output being its own pitch-shifted sound. If possible, I would like to have a potentiometer for each output that could in effect change how pitch shifted each output is, sort've of like a tuning knob. These outputs will eventually get summed together to produce a chord-like sound.

I'm not quite sure what exact requirements are needed for this, just that the sampling rate should be around 44KHz (standard audio sampling rate). Of course, I would like the outputs to replicate the original sound as much as possible, just pitch-shifted. I am assuming as well that the way I pitch-shift and sample could affect the requirements. Also, I would like to avoid SMT if I can.

Given these requirements, what do you suggest the best MCU to use is? I would like to use Arduino to program the MCU. I really only need the chip itself (I think?), as I plan to create a separate circuit board for this (although would I need an Arduino board to initially program the chip?)

I'm fairly new to the Arduino world, so apologies in advance if I miss something obvious or mess up terminology. I do come from a background in analog circuitry and programming though. Just looking for as much help as I can get from people who know more than me but am eager to learn about this all.

Thanks!

# Answer
> 0 votes
I get the impression that you haven't done this sort of thing before, on any scale. Pitch shifting is a totally non-trivial process. I suggest you start out on a regular computer and try to get a single channel working to your satisfaction. Then, if you are still determined to do this on a smaller system, you will at least know what you are up against and will be able to decide what systems are appropriate. Sorry if it sounds like I'm trying to throw cold water on your idea, because I'm sure it would be a fun instrument to play. But I think you would be getting in way over your head if this isn't already your field of expertise.

---
Tags: audio, analog-sampling
---


# Question
Title: Error: "invalid use of non-static member function" while calling a function from my own class-method
I'm having a bad time trying to call a correctly-working expression (`ultra[currentSensor].ping_timer(echoCheck)`) from an own class method (`myclass::run`) instead of from `void loop()`.

I'm getting the following compiler error: **"invalid use of non-static member function"**.

If I call `ultra[currentSensor].ping_timer(echoCheck)` directly from `void loop()` it gives me no error, so I may be missing something.

Here's the (shortened) piece of code which is generating the error:

```
#include <NewPing.h>

#define ULTRA_NUM      3
#define MAX_DISTANCE 200

class myclass {
  public:

    void run();
    void echoCheck();

    unsigned int distance[ULTRA_NUM];
    uint8_t currentSensor = 0;
};

NewPing ultra[ULTRA_NUM] = {
  NewPing(4, 5, MAX_DISTANCE),
  NewPing(6, 7, MAX_DISTANCE),
  NewPing(8, 9, MAX_DISTANCE)
};

void myclass::run() {
// ....
      ultra[currentSensor].ping_timer(echoCheck);  // Compiler error
  }

void myclass::echoCheck() {
  if (ultra[currentSensor].check_timer())
    distance[currentSensor] = ultra[currentSensor].ping_result
}

```

`ping_timer()` is defined as it follows:

```
void NewPing::ping_timer(void (*userFunc)(void), unsigned int max_cm_distance) {
    if (max_cm_distance > 0) set_max_distance(max_cm_distance);

    if (!ping_trigger()) return;
    timer_us(ECHO_TIMER_FREQ, userFunc);
}

```

I hope any of you can help me!

Thanks in advance,

Eduardo

---

**Edit**: What I am trying to do is to adapt this example (from NewPing Arduino Library) so that the sonar ping (`sonar[currentSensor].ping_timer(echoCheck)`) is done from a class method, and not from `void loop()`.

# Answer
The problem is that `echo_check` isn't `void echo_check()` but `void echo_check(myclass *this)` because it's a member function of a class.

You can make the whole thing static (along with `run()`) by:

```
class myclass {
    public:
        static void run();
        static void echo_check();
};

static void myclass::run() {
    ....
}

void myclass::echo_check() {
    ....
}

```

And then you call:

```
myclass::run();

```

instead of instantiating an object.
> 1 votes

# Answer
Solved:

I moved the event handler out of the class, and made it static void.

Then the code compiled properly

D
> 1 votes

---
Tags: library, class
---


# Question
Title: Get a specific item from comma separated text
I use bluetooth (works like serial monitor). Let me say i send a text to my hc-05 (same as sending to serial monitor) My current code is displaying text from serial monitor/HC-05 TO LCD

```
#include <LiquidCrystal.h>

LiquidCrystal lcd(4, 6, 10, 11, 12, 13);
String readString;

void setup() {
  Serial.begin(9600);
  lcd.begin(16, 2);
}

void loop() {
  while(Serial.available()){
    delay(50);
    char c=Serial.read();
    readString+=c;
  }
  if(readString.length()>0){
    Serial.println(readString);
      lcd.clear();
      lcd.print(readString);
    readString="";
  }
}

```

```
from serial monitor i type `a,b,c,d`

```

> now my goal is to just get the a and display in lcd

or

> in other words i want to get the value of a b c d in the text that is CSV to list or array and get value for index 1,2,3,4

OR

> ***split string by delimiter***

so how can i do it

details-ARUINO UNO

# Answer
> 1 votes
i searched in stack exchange Arduino but i dint get answer so i posted but when i searched in stack over flow i got link this is my final code

```
String part01;
String getValue(String data, char separator, int index)
{
  int found = 0;
  int strIndex[] = {0, -1};
  int maxIndex = data.length()-1;

  for(int i=0; i<=maxIndex && found<=index; i++){
    if(data.charAt(i)==separator || i==maxIndex){
        found++;
        strIndex[0] = strIndex[1]+1;
        strIndex[1] = (i == maxIndex) ? i+1 : i;
    }
  }

  return found>index ? data.substring(strIndex[0], strIndex[1]) : "";
}

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

void loop()
{
  String part01 = getValue("523;524;525",';',1);
  Serial.println(part01);

}

```

# Answer
> 2 votes
Use the `strtok` function.

From Geeks for geeks (https://www.geeksforgeeks.org/strtok-strtok\_r-functions-c-examples/):

arguments:

* str: The string which is to be split
* delim: The character on the basis of which the split will be done Return value

The function performs one split and returns a pointer to the token split up. A null pointer is returned if the string cannot be split.

---
Tags: arduino-uno, string
---


# Question
Title: Why is my liquid crystal display not showing any output?
UPDATE: The LCD will light up only when the all my components are located in the bottom right of the breadboard. Why am I not able to use the entire breadboard for my circuit?

I am trying to display data from a temperature and humidity sensor on the serial monitor and the liquid crystal display.

I am using :

* Arduino Uno R3
* I2C 16x2 LCD Module
* 3 pin DHT11 sensor

Here is my code :

```
#include <dht.h>                // initialize the digital temperature and humidity sensor library ("DHTlib")
#include <LiquidCrystal_I2C.h>  // initialize the liquid crystal display library ("LiquidCrystal I2C")
#include <Wire.h>               // intialize the wire library

/*   the first parameter is the I2C address
 *   the second parameter is how many columns are on your screen
 *   the third parameter is how many rows are on your screen
*/
LiquidCrystal_I2C lcd(0x27, 16, 2);

dht DHT;              // create a handle to call functions from the sensor library
#define DHT11_PIN 7   // assign a digital pin number to the sensor
float TempC;          // create a variable to store temperature in celsius
float TempF;          // create a variable to store temperature in fahrenheit
float Humi;           // create a variable to store humidity

void setup()
{
  lcd.init();                // initialize liquid crystal display
  lcd.backlight();           // turn on the backlight of the lcd
  pinMode(DHT11_PIN,INPUT);  // configure the pin for the sensor as an input for reading the data
  Serial.begin(9600);        // set data rate in bits per second for serial data transmission
}

void loop()
{
  // collect sensor data
  int chk = DHT.read11(DHT11_PIN);  // store sensor data in a variable
  TempC = DHT.temperature;          // store temperature in Celsius
  TempF = 9 / 5 * TempC + 32;       // store temperature in Fahrenheit
  Humi = DHT.humidity;              // store relative humidity as a percentage

  // display sensor data on LCD
  lcd.setCursor(0,0);    //tell the screen to write on the top row
  lcd.print("T: ");
  lcd.print(TempC);    // print the temperature in Celsius
//  lcd.print(TempF);    // print the temperature in Fahrenheit
  lcd.print((char)223);  // print the degree symbol
  lcd.print(" C");
//  lcd.print(" F");
  lcd.setCursor(0,1);    // tell the screen to write on the bottom row
  lcd.print("H: ");
  lcd.print(Humi);       // print the humidity
  lcd.print(" %");

  // display sensor data on the serial monitor
  Serial.print("Temperature = ");
  Serial.print(TempC);     // print the temperature in Celsius
//  Serial.print(TempF);     // print the temperature in Fahrenheit
  Serial.print("\xc2\xb0");  // print the degree symbol
  Serial.println(" C");
//  Serial.println(" F");
  Serial.print("Humidity = ");
  Serial.print(Humi);        // print the humidity
  Serial.println(" %");

  delay(2000);  //delay fetching the next sensor values for 2 seconds
}

```

My jumper wires are connected as follows:

* DHT plus → red plus row
* DHT middle → digital pin 7
* DHT minus → blue minus row
* LCD GND → blue minus row
* LCD VCC → red plus row
* LCD SDA → analog pin A4
* LCD SCL → analog pin A5
* Red plus row → 5V pin
* Blue minus row → GND pin

# Answer
> 4 votes
Your breadboard is one of those which have the power/GND lines interrupted between columns 31 and 33. I also once fell into this trap. If you look closely, you see that the blue and red lines are interrupted in the middle of the board. Just put wires between these pins to bridge the gap.

---
Tags: sensors, c++, lcd
---


# Question
Title: Is there an Arduino Simulator or Emulator that runs on OS X?
Is there an Arduino Simulator or Emulator or cross-compiler to native Mac executable that runs directly under Mac OS X, and does **NOT** require a Windows or Linux VM or an active internet connection for running in the cloud?

There **are** previous questions here on similar topics, but they do not seem to address exactly this particular use case subset.

# Answer
I am using the Wokwi Arduino simulator for a long time. It runs on all three platforms. Mobile, Windows OS, and macOS. I have checked the working of the simulator in both Android and iPhone. Both give a good performance as well.
> 3 votes

# Answer
Arduino CodeBlocks plug-in has an Arduino simulator. Be carefull when setting it up and use full paths, it's easy to mess up, but works beautifully once done.
> 1 votes

---
Tags: emulation, simulator, osx
---


# Question
Title: Can UNO log more PCB 353b33 accelerometer data points compared to TDS3014B oscilloscope?
I'm currently recording data points from an analog accelerometer(PCB 353b33) using a TDS3014B oscilloscope which has Record Length of 10,000 points at a Sample Rate 1.25 Ga/s. I'm want to record more data points, would it be possible to use UNO as a data acquisition device and record much higher data points than the oscilloscope(\>\> 10,000)

# Answer
> 1 votes
No way. The UNO has only 2.5kb of RAM, so you can't cache the data points and you would need a very quick link to get the data out. And sampling at 1.25 GigaSamples/s is orders of magnitude beyond an UNO, as its maximum clock frequency is only 16 MHz. An Uno is about $20, while your TDS3014B is around $1500. Sometimes, there's a reason for a different price tag.

# Answer
> 1 votes
For 10 minutes of sampling at 1.25Gsps using 32-bit floats you would need about 3 terabytes of memory. You're not going to even get close to that with a very very powerful desktop. An Arduino...? Dream on. It's never going to happen.

An Arduino has a couple of kB of memory. Plus a slow, crude, ADC. You may get a fraction of a second at its highest sample rate. To stretch it out over 10 minutes you'd be looking at no more than about 800 samples (16 bit values from a 10 bit ADC), so maybe one sample every 1 1/2 seconds.

---
Tags: accelerometer, datalogging
---


# Question
Title: What's the difference between analogWrite and digitalWrite?
As the title states. What's the difference between the two?

`analogWrite(pin,0-255)` vs `digitalWrite(pin,LOW-HIGH)`

# Answer
> 18 votes
digitalWrite will set the specified pin to one of two states - HIGH/LOW, which equate to 5v (3.3v on some boards) and ground respectively.

analogWrite can vary by the type of output used.

If applied to a PWM pin - it will set the pin to a periodic high/low signal, where the percentage of the signal spent high is proportional to the value written. for example -

```
    analogWrite(PWMpin,255)

```

Will be HIGH 100% of the time, while

```
    analogWrite(PWMpin,127)

```

Will be HIGH 50% of the time, and LOW 50% of the time

When applying analogWrite to a DAC pin (available on some boards, like the DUE ~~or MEGA~~) analogWrite will actually cause the specified pin to output a voltage level proportinal to the specified analog value

For example, on the Due, with maximal voltage of 3.3v and a default analog resolution of 8 bits -\[0:255\]

```
    analogWrite(DACpin,255)

```

Will cause the specified pin to output 3.3v, and-

```
    analogWrite(DACpin,127)

```

Will cause the specified pin to output 1.35v

# Answer
> 9 votes
**analogWrite():** The analogWrite() method sets the value of a PWM output pin. The analogWrite() is on a scale of 0 - 255, such that analogWrite(255) requests a 100% duty cycle (always on), and analogWrite(127) is a 50% duty cycle (on half the time).

**Syntax**: analogWrite(pin, val)

Where,

pin: the PWM output pin number.

val: int value of duty cycle between from 0(always off) to 255(always on)

**Example Code:**

```
int outLed = 10;  //LED connected to digital pin 10
int value = 0;    //variable to store the read value
int analogIN = 3; //input pin

void setup()
{
  pinMode(outLed, OUTPUT); // set the PWM pin as OUTPUT
}

void loop()
{
  value = analogRead(analogIN); // read the value of analogIN (values between from 0 to 1023)
  analogWrite(outLed, value/4); // sets the read value on outLed (values between from 0 to 255)
}

```

**digitalWrite:** The digitalWrite() method sets the value of a digital pin as HIGH or LOW. Here, 5V (or 3.3V on 3.3V boards) for HIGH, 0V (ground) for LOW.

**Syntax:** digitalWrite(pin, val)

Where,

pin: the pin number

val: HIGH or LOW

**Example Code:**

```
int ledPin = 13;                // LED connected to digital pin 13

void setup()
{
  pinMode(ledPin, OUTPUT);      // sets the digital pin as output
}

void loop()
{
  digitalWrite(ledPin, HIGH);   // sets the LED on
  delay(1000);                  // waits for a second
  digitalWrite(ledPin, LOW);    // sets the LED off
  delay(1000);                  // waits for a second
}

```

# Answer
> 7 votes
`digitalWrite` sets the output pin to either LOW or HIGH (where those voltages depend on the Vcc of the processor. For a Uno or Mega that would be 0V or 5V (or close to it).

Here's a screenshot of digitalWrite (LOW):

That is, the output pin is at 0V.

---

Now for digitalWrite (HIGH):

The output voltage is 5V.

---

`analogWrite` really should have been named PWMwrite since it configures the processor timers to output PWM (pulse-width modulation).

Let's try analogWrite(1):

You can see that the voltage level is 0V most of the time, and going to 5V for short periods. You also see that the frequency is 490 Hz which is what the reference page for analogWrite says it will be.

---

Zooming in:

The output is high for 8 µs, which is exactly 1/256 of 2048 µs which is the period of the timer. So, we have a duty cycle of 1/256 (0.39%).

---

Let's try analogWrite(127) - half-way from 0 to 255:

Now you can see that the output is HIGH exactly half the time, and LOW the rest of the time.

---

Let's try analogWrite(254):

This is the opposite of analogWrite (1). The output is HIGH all the time except for a brief period. Zooming in:

Now the output is *off* for 8 µs - compared to the earlier image where it was on for 8 µs.

---

`analogWrite (0)` is the same as `digitalWrite (LOW)`.

`analogWrite (255)` is the same as `digitalWrite (HIGH)`.

This is proven by the relevant code in wiring\_analog.c:

```
if (val == 0)
{
    digitalWrite(pin, LOW);
}
else if (val == 255)
{
    digitalWrite(pin, HIGH);
}

```

---

## Summary

`analogWrite` basically configures the hardware timers to output PWM. Once you do that the timer hardware outputs the requested duty cycle (from 0 to 255) where 0 is always off, 255 is always on, and some value inbetween gives you PWM (pulsed output).

---

For more information about the timers see my page about timers.

# Answer
> 3 votes
digitalWrite sets the pin to an high or low value that remains at exactly that value until digitalWrite is called for that pin again.

analogWrite sets the pin to have an oscillating value which has a pulse length based of the duty cycle specified as the second parameter.

So:

```
digitalWrite (5, HIGH);    // Pin 5 goes high
analogWrite (6, 127);      // Pin 6 oscillates regularly between 0v and 5v (or 3.3v) at about 250Hz.

```

# Answer
> 2 votes
**analogWrite():** Writes an analog value (PWM wave) to a pin. Can be used to light a LED at varying brightnesses or drive a motor at various speeds. After a call to `analogWrite()`, the pin will generate a steady square wave of the specified duty cycle until the next call to `analogWrite()` (or a call to `digitalRead()` or `digitalWrite()` on the same pin). The frequency of the PWM signal on most pins is approximately 490 Hz. On the Uno and similar boards, pins 5 and 6 have a frequency of approximately 980 Hz. Pins 3 and 11 on the Leonardo also run at 980 Hz.

For details visit: https://www.arduino.cc/en/Reference/analogWrite

**analogRead():** Reads the value from the specified analog pin. The Arduino board contains a 6 channel (8 channels on the Mini and Nano, 16 on the Mega), 10-bit analog to digital converter. This means that it will map input voltages between 0 and 5 volts into integer values between 0 and 1023. This yields a resolution between readings of: 5 volts / 1024 units or, .0049 volts (4.9 mV) per unit. The input range and resolution can be changed using `analogReference()`.

For details visit: https://www.arduino.cc/en/Reference/analogRead

# Answer
> 2 votes
**digitalWrite** set the specified pin to one of two states - HIGH/LOW

Where, HIGH = 5 V and LOW = 0 V

**analogWrite** Set the PWM value of PWM pin

(In Arduino UNO, PWM pins are 3, 5, 6, 9, 10, 11)

It will set the pin to a periodic high/low signal.

```
analogWrite(PWMpin,255)

```

Will be HIGH 100% of the time, while

```
analogWrite(PWMpin,127)

```

Will be HIGH 50% of the time, and LOW 50% of the time

# Answer
> 0 votes
So what's the difference between analogWrite(X, 255) and digitalWrite(X, HIGH)? Probably nothing, except perhaps the processor has to do some extra stuff to work out that it doesn't need to use PWM, and also style.

# Answer
> 0 votes
Another subtle difference between `analogWrite(pin, 255)` and `digitalWrite(pin, HIGH)` is that `digitalWrite` requires you to set the pin to output using `pinMode`. `analogWrite` sets the pin to output on each call, which makes it slower and might ruin the code which uses the same pin alternatively as input and output, and relies on the fact that writing to the input pin using `digitalWrite` doesn't switch it to output.

---
Tags: digital, analogwrite
---


# Question
Title: Arduino FFT results of "beautiful" signal seem inconsistent
I have a BEAUTIFUL doppler radar signal here from a 24.050-24.250 GHZ sensor measuring a very small object at 143 fps speed (speed from another 10 GHZ radar) in a measuring area of about 300mm-500mm in front of the sensor(s). The signal was limited to around 3V with a zener diode.

I took several measurements (at this speed and object size and distance from the sensors) and there were about 8-20 wave peaks on the average above the trigger threshold level (2.58V) until the end of the trigger threshold level box where the peaks start falling off.

Looking at the graph, one can discard the first 3 peaks and the last 2-3 peaks above the trigger threshold which leaves a decent area (orange box) for sampling of the peaks for frequency/period. So in this case we have about 17 "good" peaks inside the orange box to be measured. In this case the orange box (measuring sample area) is 5 x 500 us = 2500 us in length.

I know that an FFT would be the best way to measure, but the one FFT program I used with Arduino gave me inconsistent results. Not sure how to set the sample size (must be in power of 2 increment from 2 to 256). And the maximum sampling frequency is 10kHz (hardware limitations).

I set sample sizes to 4 and 16 and 128 at 10Khz frequency, but get inconsistent results. I suspect logarithmic results, but even those do not add up. At times I get within 2-3% but at times it's off by 30% with no apparent correlation.

What I know:

* with this 24 GHZ radar (no angles) the **speed = frequency / 44** to arrive to km/h (km/h x 1.097 = fps)
* in this case the o-scope measured 6613 Hz with a 151.2 us period, but that was for the entire area above the 2.58V trigger threshold. But it also had some much more varying readings as noticeable in the first 2-3 peaks after the trigger and the last 2-3 peaks that are falling off to below the trigger threshold. I excluded these from the orange box.

How do I set up this FFT, or another FFT, or similar method, that would determine the dominant frequency from data inside the orange box? The orange box sample size will always seems to be between the 8-20 number of peaks range. I measured frequency and periods from "positive rising edge to positive rising edge".

I tried with an Adafruit nRF52840 Express (16 Mhz clock) and an Adafruit 32u4 Bluefruit (8 Mhz clock).

I am using this Arduino FFT library: https://github.com/kosme/arduinoFFT

Some broad info about this FFT itself: https://www.norwegiancreations.com/2017/08/what-is-fft-and-how-can-you-implement-it-on-an-arduino/

Thank you.

```
    #include "arduinoFFT.h"

#define SAMPLES 4         //Must be a power of 2     128, 256?
#define SAMPLING_FREQUENCY 10000 //Hz, must be less than 10000 due to ADC

arduinoFFT FFT = arduinoFFT();

unsigned int sampling_period_us;
unsigned long microseconds;

double vReal[SAMPLES];
double vImag[SAMPLES];

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

    sampling_period_us = round(1000000*(1.0/SAMPLING_FREQUENCY));
}

void loop() {

  if (analogRead(A0) >600) {

    /*SAMPLING*/
    for(int i=0; i<SAMPLES; i++)
    {
        microseconds = micros();    //Overflows after around 70 minutes!

        vReal[i] = analogRead(A0);
        vImag[i] = 0;

        while(micros() < (microseconds + sampling_period_us)){
        }
    }

    /*FFT*/
    FFT.Windowing(vReal, SAMPLES, FFT_WIN_TYP_HAMMING, FFT_FORWARD);
    FFT.Compute(vReal, vImag, SAMPLES, FFT_FORWARD);
    FFT.ComplexToMagnitude(vReal, vImag, SAMPLES);
    double peak = FFT.MajorPeak(vReal, SAMPLES, SAMPLING_FREQUENCY);

    /*PRINT RESULTS*/
    Serial.println(peak);     //Print out what frequency is the most dominant.

  //  for(int i=0; i<(SAMPLES/2); i++)
   // {
        /*View all these three lines in serial terminal to see which frequencies has which amplitudes*/

        //Serial.print((i * 1.0 * SAMPLING_FREQUENCY) / SAMPLES, 1);
        //Serial.print(" ");
      // Serial.println(vReal[i], 1);    //View only this line in serial plotter to visualize the bins
  //  }

 }

    //delay(1000);  //Repeat the process every second OR:
   // while(1);       //Run code once
}

```

**EDIT:** @Dorian After several days of tribulations and frustrations, I read and re-read your additional info and helped me clarify things better. I think I have some hardware limitations. By the way...yes I do have a 27pf capacitor to the GND with a 3.3K resistor and a 3V zener in parallel at the OP AMP's outlet.

But let me explain first: I decided to add a comparator after the sensor and OP AMP. Now I have a baseline voltage at HIGH (3.1V). Previously, as I posted, the OP AMP had baseline of 1.65V and when motion is detected the voltage bounces between HIGHs (2.5V-3.1V) and LOWs (1V-0V) for about 10-20 times until it settles at the 1.65V baseline again. I suspected that the HIGH and LOW thresholds were not that clear. In order to get a clear HIGH or LOW I added the comparator. These readings go to an MCU's digital Capture pin capable of 62.5ns ticks (16 MHZ). The Arduino program that counts the pulses is verified to work. In the specs the MCU at 3.3V has 1V and below as LOW and 2.5V and above as HIGH.

See the new oscope reading (attached). I get accurate pulse captures (matching the oscope), but I only get about 3 or 4 pulse readings instead of the 10-20 showing on the scope. I used LOW capture (below 1V). But even if I switch to TOGGLE capture (double) I seems to be getting only the last 3-4 complete waves (1/3rd) and seem to be missing the first 2/3rds. Or may getting every 2nd or 3rd?

My OP AMP is fast at 50 MHZ and I used to measure 100us-800us pulses with it accurately. And my comparator (after the OP AMP) is a MAX 9052 with a 400ns propagation delay. 40-80ns rise/fall time. So I should not be missing any pulses. The Arduino program cannot be that slow either.

EDIT #2:

```
//the best resolution you can achieve is 1/16us.

#include <Arduino.h>

#define FREQ_MEASURE_PIN 8  // actual 6 is PIN D11 and 8 is PIN D12 on Adafruit Feather Express nRF52840 LE, pin 11 is D12 itsybitsy 52840
#define PPI_CHANNEL 1u
#define GPIOTE_CHANNEL 1   //just picked channel #1

volatile int pulseCount = 0;
volatile unsigned long duration; //Pulse2 - Pulse1 = count of time ticks at 62.5 ns each tick (16 Mhz clock scaled at 0)     (expected value example: 792.5620  => 7925620)
volatile unsigned long pulseTime;   // first signal reading
volatile unsigned long lastTime;   //  most current signal reading

void setup() {

    Serial.begin(115200);

  initCounter();
}

void loop()
{

  if  ((pulseCount == 2) && (duration>0))  {

    Serial.println(duration);   //

   }

}

//must use extern "C" because IRQ will not compile since it's "C" coded
extern "C"
{
void GPIOTE_IRQHandler(void)
{

  lastTime = pulseTime;

  if (NRF_GPIOTE->EVENTS_IN[GPIOTE_CHANNEL] == 1)    //if an input pulse is detected on pin 6 then...
  {
    NRF_GPIOTE->EVENTS_IN[GPIOTE_CHANNEL] = 0;     //  reset event detection to zero to ready for next event detection?
    pulseTime = NRF_TIMER2->CC[0];                     // save Timer value at same time when signal was read on pin 6

    //pulseCounter
    pulseCount++;
    duration =(((pulseTime*10000) - (lastTime*10000))/16); //multiply by 10000 to avoid float, and divide by 16 for 16 Mhz clock tick = 62.5 ns per tick

   // goes from here to Loop if pulse = 2 (complete PULSE) so a reading can be sent
    }
  }
}

void initCounter()
{
  NRF_P0->PIN_CNF[FREQ_MEASURE_PIN] = GPIO_PIN_CNF_DIR_Input << GPIO_PIN_CNF_DIR_Pos |        //sets up PIN 6 for event read
                                      GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos |  //pos going signal
                                    //  GPIO_PIN_CNF_PULL_Pulldown << GPIO_PIN_CNF_PULL_Pos |   //pulldown LOW so no floating of pin voltage
                                   //   GPIO_PIN_CNF_SENSE_High << GPIO_PIN_CNF_SENSE_Pos;      //a HIGH POS signal is the trigger

                                      GPIO_PIN_CNF_PULL_Pullup << GPIO_PIN_CNF_PULL_Pos |   //Pullup or Pulldown LOW so no floating of pin voltage
                                      GPIO_PIN_CNF_SENSE_Low << GPIO_PIN_CNF_SENSE_Pos;      //a HIGH POS signal is the trigger .... or a LOW POS

  NRF_PPI->CHEN |= 1 << PPI_CHANNEL;
  NRF_PPI->CH[PPI_CHANNEL].EEP = (uint32_t)&NRF_GPIOTE->EVENTS_IN[GPIOTE_CHANNEL];
  NRF_PPI->CH[PPI_CHANNEL].TEP = (uint32_t)&NRF_TIMER2->TASKS_CAPTURE[0];   //sets up Timer channel

  NRF_GPIOTE->CONFIG[GPIOTE_CHANNEL] = GPIOTE_CONFIG_MODE_Event << GPIOTE_CONFIG_MODE_Pos |         //sets up pin for event capture
                                    FREQ_MEASURE_PIN << GPIOTE_CONFIG_PSEL_Pos |                   //sets up event capture on pin 6
                                    GPIOTE_CONFIG_POLARITY_HiToLo << GPIOTE_CONFIG_POLARITY_Pos;   //sets event capture signal trigger type:  LoToHi   or HiToLo or  Toggle
  NRF_GPIOTE->INTENSET = (1 << GPIOTE_CHANNEL);    //  Interrupt routine setup on a pin
  NVIC_EnableIRQ(GPIOTE_IRQn);                     //  Interrupt routine setup if signal detected on pin 6

  NRF_TIMER2->TASKS_STOP = 1;    //stops timer
  NRF_TIMER2->TASKS_CLEAR = 1;    //clear timer to zero
  NRF_TIMER2->MODE = TIMER_MODE_MODE_Timer << TIMER_MODE_MODE_Pos;   //sets up TIMEr mode as "Timer"
  NRF_TIMER2->BITMODE = TIMER_BITMODE_BITMODE_32Bit << TIMER_BITMODE_BITMODE_Pos;    // sets values for Timer input
  NRF_TIMER2->PRESCALER = 0;       //read at max resolution (at MCU speed)
  NRF_TIMER2->TASKS_START = 1;      // starts the Timer
}

```

**EDIT #3: ================================================**

I added the OP AMP circuit below. This circuit worked fine with an inductive sensor using eddy-currents. I measured @ 700-800us single-shot pulses very accurately, but did not have the R1 (22k) resistor. Added the R1 resistor and the GND immediately after it when replaced the inductive sensor with the 24 GHZ radar sensor because I was not getting readings. This circuit provides the first graph I posted, centered at around 1.6V. I took the comparator after the OP AMP off as not to complicate the circuit, and also it had some artifacts.

In summary: the suspicion is that the Arduino program I posted for the nRF52 is not fast enough to capture 100us pulses in fast succession. I tried to use BLE only and uncommented the SerialPrint and SerialBegin, etc....but even with BLE I got the same limited pulse readings. For example: there were 10-20 pulses, I was only able to capture the last 1/3 of the pulses (3-4). I tried HIGH and LOW (HiToLo/LoToHi/Toggle) as well.

The radar sensor is: 3.3V supply. IF out (signal read) is between 60mV-250mV. 60mv being the zero signal state.

```
Here are some sample period (wave pulse) readings in micro seconds:

97.0000
53.2500
45.2500
42.0625
40.8125
**40.9375**

And the actual period that it should read based on reference measurement:  **38.4435**us

==========================
Another set of period (wave pulse) readings in micro seconds:

95.6875
55.0000
46.7500
41.7500
**40.2500**

And the actual period that it should read based on reference measurement: **39.1703**us

```

So the last reading is quite close, but not proportionally close where I can "estimate" the actual value reliably. So it's not for example off by 5.13% every time, but it's off by 3-6%.

Graph of example wave pulses (smaller means shorter pulse):

The ZENER at the output is there to clip the waves from going over 3.3V which can damage the MCU's input capture pin.

Thank you for your assistance!

For information only: THESE WERE THE OSCOPE READINGS WITH THE COMPARATOR CIRCUIT ADDED ON TO THE OP AMP'S OUTPUT BUT I SINCE REMOVED THE COMPARATOR CIRCUIT:

**EDIT #4:** It's been quite a delay as I needed to do something else after not getting anywhere with this project. Then today as I was struggling again I think I arrived to the solution. It requires more work, but at least I have a cobbled together version that seems to work well.

The problem seem to have been with the signal itself being a sine-wave or a quasi-square wave. Using an Arduino AVR sketch for the internal comparator that is being assisted by the comparator's ISR to "square" the incoming signal with timers and interrupts by toggling another pin into the Ref pin of the comparator, I was able to get reliable readings. I actually ended up using an external comparator with the AVR and an nRF52 to count to periods. This is the program and looks another person also went through hell: https://electronics.stackexchange.com/questions/357131/random-and-unpredictable-analog-comparator-behaviour/566974#566974

I prefer to use the nRF52 because of the BLE integration, but I think I can make the AVR work first stand-alone by figuring out how to edit the library to reverse the interrupt from Low to High to High to Low...since the output of the comparator is opposite of my signal input.

Of course I still need to process the readings to sort out the dominant frequency, but manually I was able to calculate 5 out of 5 events within 2-5% of the valid value.

However, it seems that the key in the input signal being read reliably is the additional pin that is used to "convert" the sine wave into a square as part of the comparator's interrupt routine.

I still need to wrap my head around how the AVR program's additional pin toggled LOW/HIGH connected to VREF of the comparator "shapes" the sine wave and acts as a feedback for hysteresis. I believe that which ever way I arrive to a "nice" square wave for the AVR's or nRF52's input counter to read will be a winner. But I will open an new topic if I get stuck. Thank you for your help and any inputs suggestions are welcomed.

**EDIT #5:** Based on a suggestion in another post I decided to use a 74xx14 Schmitt Trigger at the output of the op amp and it worked really well. The square pulses were well defined (4ns rise time in specs) that I was able to identify every one of the pulses (usually between 5-20) in the software. Manual calculations lead to accurate frequencies too.

Now I need to figure a way to identify the dominant frequency that has to be done on software. I tried several FFT/FHT and ADC averaging programs, but none of them worked right. Will bring this up in a separate question. Thank you all for your help. Seems like the root problem was signal conditioning on my part.

# Answer
> 1 votes
To have a meaningful result from the Fourier transform the input signal must filtered to a bandwidth at most half of the sample rate.

Your 10khz maximum sample rate which I suppose is given by the maximum sample rate of the ADC is less than double of 6.61 kHz , the base frequency of your signal.

Even more, you limit the signal adding high frequency components to the signal that already doesn't fit into the required bandwidth.

You better stick to zero cross detection using both rising and falling edges to have more data to average.

You might also check which part of the signal has the correct speed data against the real speed or to check for a pattern, I see the middle period is lower then at the beginning and the end of the signal.

**Later edit. Some things you should check and explanation on why is pointless to use FFT on this.**

First, I see you have a clean middle centered signal between -0.7 and 3V. Maybe there is an output capacitor on the sensor that auto limits itself between Zener voltage and the lower clamp diode. The middle is somewhere at 1.5V. But the middle of the logic voltage is somewhere at half VDD, 2.5V.

Maybe that's why you have variations of pulse length from the beginning to the end of the train pulse because the decision line is above the middle line.

Of course setting the decision around the middle line might give a lot of noise but you can either use an envelope detector to see when the pulse begins or a Schmidt trigger so only signal above the hysteresis will pass.

I think that truly detecting the passes around the middle point will give you more reliable and consistent results.

About using discrete Fourier transform (fast or not) for finding the base frequency of the signal, there is no way to obtain a reasonable resolution using such a short signal.

The DFT is discreete not only in time but in frequency to. Anybody who has some basic knowledge about DFT knows that the maximum resolution in frequency that you can obtain in a *t* timeframe is 1/*t*, here for 2.5ms the frequency will be in steps of 400Hz, if you have maximum 8kHz signal you will have 20 fixed frequency values from 0 to 8kHz no matter how many samples you take, no matter on what software you make the processing or platform. It's a dead end.

# Answer
> 1 votes
I cannot really understand why you can't catch pulses at 6613 Hz. That is not that fast, even for an Uno.

I did the following experiment with an Uno: I use Timer 2 to generate a short burst of pulses on pin 11 (PB3 = OC2A). This pin is connected to pin 8 (ICP1), where I use Timer 1 to capture the falling edges. In the input capture ISR I count the number of edges received, and I also record the timestamps of the first and the last edge. This way I can compute the received frequency.

The result of the experiment is that this way I can reliably measure frequencies up to 125 kHz. This is about 19 times the frequency of your burst. The measurement becomes unreliable if I keep increasing the frequency.

Here is my test code:

```
// CPU cycles per half-period of the pulse burst.
const uint16_t half_period = 64;

// Statistics recorded by the input capture ISR.
volatile uint16_t capture_count;
volatile uint16_t timer_start;
volatile uint16_t timer_end;

// Input capture ISR.
ISR(TIMER1_CAPT_vect) {
    uint16_t now = ICR1;
    uint16_t count = capture_count;
    if (count == 0)
        timer_start = now;
    else
        timer_end = now;
    capture_count = count+1;
}

void setup() {
    Serial.begin(9600);
    Serial.print("Expected frequency: ");
    Serial.print((float) F_CPU / (2*half_period));
    Serial.println(" Hz");
    Serial.println("Measured frequency:");
    Serial.flush();

    // Configure Timer 2 for fast PWM.
    DDRB  |= _BV(PB3);    // digital 11 = PB3 = OC2A as output
    TCCR2A = _BV(COM2A0)  // toggle OC2A on compare match
           | _BV(WGM21);  // mode 2 = CTC, TOP = OCR2A
    TCCR2B = 0;           // keep timer stopped
    OCR2A  = half_period - 1;

    // Configure Timer 1 for input capture.
    TCCR1A = 0;           // normal mode
    TCCR1B = _BV(CS10);   // clock @ F_CPU
    TIFR1  = _BV(ICF1);   // clear input capture flag
    TIMSK1 = _BV(ICIE1);  // enable input capture interrupt
}

void loop() {
    // Reset the counter.
    capture_count = 0;

    // Send a burst of pulses.
    TCCR2B = _BV(CS20);   // clock Timer 2 @ F_CPU
    delayMicroseconds(1000);
    TCCR2B = 0;           // stop Timer 2

    // Report results.
    uint16_t timer_cycles = timer_end - timer_start;
    uint16_t pulse_count = capture_count - 1;
    Serial.print(pulse_count);
    Serial.print(" pulses in ");
    Serial.print(timer_cycles);
    Serial.print(" timer cycles -> ");
    Serial.print((float) pulse_count / timer_cycles * F_CPU);
    Serial.println(" Hz");
    delay(500);
}

```

And here is the output:

```
Expected frequency: 125000.00 Hz
Measured frequency:
255 pulses in 32640 timer cycles -> 125000.00 Hz
255 pulses in 32640 timer cycles -> 125000.00 Hz
256 pulses in 32768 timer cycles -> 125000.00 Hz
256 pulses in 32768 timer cycles -> 125000.00 Hz
255 pulses in 32640 timer cycles -> 125000.00 Hz
256 pulses in 32768 timer cycles -> 125000.00 Hz
256 pulses in 32768 timer cycles -> 125000.00 Hz
256 pulses in 32768 timer cycles -> 125000.00 Hz
255 pulses in 32640 timer cycles -> 125000.00 Hz
256 pulses in 32768 timer cycles -> 125000.00 Hz
256 pulses in 32768 timer cycles -> 125000.00 Hz

```

---
Tags: signal-processing, analog-sampling, mathematics
---


# Question
Title: How to work with WS2812B 16x16 matrix panel from aliexpress
I'm completely new to Arduino, and I want to build the project using an LED 16x16 matrix, but I don't know where to start. On the internet, I keep finding these custom matrix panels and they aren't similar to mine. So I'm asking here. Does anyone have experience with this Arduino-compatible RGB LED matrix panel? This is the link to the Aliexpress product.    Will I need an additional power supply? What will I need to install to make it work? Where do i plug what wire into my arduino? Thanks for any answer!

# Answer
It's just a string of WS2812B LEDs that have been "bent" into a grid. You treat it exactly like any other WS2812B strip of LEDs.

You have 256 LEDs, and as far as the Arduino is concerned, they are just in a line numbered 0-255.

The "grid" arrangement is solely down to you to you to calculate. Fortunately 256, or 16x16, is very easy to work with: you have a byte which can represent any one of the LEDs, and each half of the byte (a nibble) is one coordinate.

The traditional calculation to convert X and Y into a linear number is:

```
num = x + y * width

```

where `width` is the number of LEDs in the X direction (16). However since we're working with a width of 16 that can be optimized to use bit-shifting and bitwise operations:

```
num = x | (y << 4)

```

That is assuming LED 0 is on the left (either top or bottom) and LED 1 is one place to the right.

Will you need an external power supply for it? Yes, most certainly (and they even provide you with a dedicated power connection for it). 256 LEDs, if all are turned on full brightness at once, could consume up to about 15 amps (20mA per channel, three channels per LED, 256 LEDs).
> 2 votes

---
Tags: power, led
---


# Question
Title: L298 Motor Driver not showing Red light when connecting power supply
I recently bought an L298 motor driver module for controlling 2 motors(5v each).

When i connect the power supply(which is a normal RC car battery holder(3)) the red light doesn't light up.

Instead if i connect the +ve to the 5v on the motor driver, the red light is glowing, but the motors don't work.

# Answer
You need to do math on the power consumption as arduino uno takes takes 5 V 500 mA at least for it to work. That is why it can be powered by USB cables too. Now if you try calculating power consumption on the motors you would understand that the power you are giving is nowhere enough for the arrangement to work or you could have been able to run the motors without the motor driver. Try upgrading the power you are giving.
> 1 votes

---
Tags: motor
---


title: Arduino RTC SD Card problem

text:
# Question
Title: Arduino RTC SD Card problem
I am using a script on an Arduino to record BME280 data onto an SD card and to display it on a lcd display. To have a valid time stamp I am also using a DS3231 RTC module. I set the time succesfully and can manually read it and write it to the serial monitor. Writing the sensor data to the SD card works fine as well. But as soon as I try to include the time from the RTC into the file onto the SD card the script jumps back to the else statement in the setup() where I try to open the file for writing the header line.

Without using the RTC time it works fine, as soon as I put it in using the corresponding function, it fails.

Here is the script I am using:

```
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <SPI.h>
#include <SD.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BME280.h>

#define BME_SCK 8
#define BME_MISO 6
#define BME_MOSI 7
#define BME_CS 5

#define SEALEVELPRESSURE_HPA (1013.25)
#define RTC_I2C_ADDRESS 0x68 // I2C Adresse des RTC  DS3231

Adafruit_BME280 bme(BME_CS, BME_MOSI, BME_MISO, BME_SCK); // software SPI

unsigned long lastReadRTC = -1;
boolean sd_ok = 0, sensor_ok = 0;
File dataLog;
String dat_time;

LiquidCrystal_I2C lcd(0x27, 20, 4);  //Hier wird das Display benannt (Adresse/Zeichen pro Zeile/Anzahl Zeilen)

void setup()
{
  Wire.begin(); //Kommunikation über die Wire.h bibliothek beginnen.
  Serial.begin(9600); // open serial communications and wait for port to open
  // SD Card Initialization
  if (SD.begin())
  {
    Serial.println("SD card is ready.");
    sd_ok = true;
  } else
  {
    Serial.println("SD card initialization failed");
    return;
  }
  //if( SD.exists("test.txt") == 1 ){
  dataLog = SD.open("test.txt", FILE_WRITE);
  if(dataLog) {                               // if the file opened okay, write to it:
     Serial.println("OK, writing header");
     // write some texts to 'test.txt' file
     dataLog.println("DATE | TEMPERATURE | HUMIDITY | PRESSURE");
     dataLog.close();   // close the file
  }
  else {
    Serial.println("error opening testfile.txt");
  }
  unsigned status;
  status = bme.begin();
  if (!status) {
    Serial.println("Could not find a valid BME280 sensor, check wiring, address, sensor ID!");
    Serial.print("SensorID was: 0x");
    Serial.println(bme.sensorID(),16);
    Serial.print("        ID of 0xFF probably means a bad address, a BMP 180 or BMP 085\n");
    Serial.print("   ID of 0x56-0x58 represents a BMP 280,\n");
    Serial.print("        ID of 0x60 represents a BME 280.\n");
    Serial.print("        ID of 0x61 represents a BME 680.\n");
    while (1) delay(10);
  }else{
    sensor_ok = true;
    Serial.println("OK, sensor recognized");
  }
  lcd.init();
  lcd.backlight();
  lcd.setCursor(0,0);
  lcd.print("Temp. = ");
  lcd.print(bme.readTemperature());
  lcd.print(" *C");
  lcd.setCursor(0,1);
  lcd.print("Press. = ");
  lcd.print(bme.readPressure() / 100.0F);
  lcd.print(" hPa");
  lcd.setCursor(0,2);
  lcd.print("Alti. = ");
  lcd.print(bme.readAltitude(SEALEVELPRESSURE_HPA));
  lcd.print(" m");
  lcd.setCursor(0,3);
  lcd.print("Hum. = ");
  lcd.print(bme.readHumidity());
  lcd.print(" %");

  delay(1000);
}

//Reads the current datetime from rtc module
String rtcReadTime(){
  Wire.beginTransmission(RTC_I2C_ADDRESS); //Connect to address 0x68
  Wire.write(0);
  Wire.endTransmission();
  Wire.requestFrom(RTC_I2C_ADDRESS, 7);
  int sekunde    = bcdToDec(Wire.read() & 0x7f);
  int minute     = bcdToDec(Wire.read());
  int stunde     = bcdToDec(Wire.read() & 0x3f);
  //weekday not included
  /* wochentag  =*/ bcdToDec(Wire.read());
  int tag        = bcdToDec(Wire.read());
  int monat      = bcdToDec(Wire.read());
  int jahr       = bcdToDec(Wire.read())+2000;

  char timestamp[30];
  sprintf(timestamp,"%02d.%02d.%4d %02d:%02d:%02d",tag,monat,jahr,stunde,minute,sekunde);
  return timestamp;
}

//Converts binary to numeric
byte bcdToDec(byte val){
  return ( (val/16*10) + (val%16) );
}

void loop()
{
  unsigned long currentMilliseconds = millis();
  if((lastReadRTC + 1000) < currentMilliseconds){
    lastReadRTC = currentMilliseconds;
    lcd.setCursor(0,0);
    lcd.print("Temp. = ");
    lcd.print(bme.readTemperature());
    lcd.print(" *C");
    lcd.setCursor(0,1);
    lcd.print("Press. = ");
    lcd.print(bme.readPressure() / 100.0F);
    lcd.print(" hPa");
    lcd.setCursor(0,2);
    lcd.print("Alti. = ");
    lcd.print(bme.readAltitude(SEALEVELPRESSURE_HPA));
    lcd.print(" m");
    lcd.setCursor(0,3);
    lcd.print("Hum. = ");
    lcd.print(bme.readHumidity());
    lcd.print(" %");
    //Serial.println(rtcReadTime());
    if(sd_ok){
      dataLog = SD.open("test.txt", FILE_WRITE);
      //dataLog.print(rtcReadTime());
      dataLog.print(" |  ");
      if(sensor_ok) {
        dataLog.print(bme.readTemperature());
        dataLog.print("°C   |  ");
        dataLog.print(bme.readHumidity());
        dataLog.print("  | ");
        dataLog.println(bme.readPressure() / 100.0F);
        dataLog.close();
      }
      else{
        dataLog.println("  Error    |  Error   |  Error");
        dataLog.close();
      }
    }
  }
  delay(1000);
}

```

So when I run the script without the RTC time included it gives me the output:

> SD card is ready.

> OK, writing header

If I include the line `dataLog.print(rtcReadTime());` towards the end (in the script commented out) it jumps to the beginning of the setup section into the else statement giving me:

> error opening testfile.txt

and nothing is written into the file on the SD card.

I tried to find the mistake for multiple hours yesterday and was hoping to find it today after a good night of sleep, but nope. It is probably an easy fix that i can't see. The code is probably far from perfect or good. I am a beginner in c++, so keep that in mind. :)

**EDIT:** As I was not able to find a solution using `rtcReadTime()`, I used the `RTClib.h` directly and created the time manually in the writing process for the SD card:

```
void loop()
{
  unsigned long currentMilliseconds = millis();
  if((lastReadRTC + 1000) < currentMilliseconds){
    lastReadRTC = currentMilliseconds;
    lcd.setCursor(0,0);
    lcd.print("Temp. = ");
    lcd.print(bme.readTemperature());
    lcd.print(" *C");
    lcd.setCursor(0,1);
    lcd.print("Press. = ");
    lcd.print(bme.readPressure() / 100.0F);
    lcd.print(" hPa");
    lcd.setCursor(0,2);
    lcd.print("Alti. = ");
    lcd.print(bme.readAltitude(SEALEVELPRESSURE_HPA));
    lcd.print(" m");
    lcd.setCursor(0,3);
    lcd.print("Hum. = ");
    lcd.print(bme.readHumidity());
    lcd.print(" %");
    if(sd_ok){
      dataLog = SD.open("test.txt", FILE_WRITE);
      DateTime now = rtc.now();
      dataLog.print(now.day(), DEC);
      dataLog.print(' ');
      dataLog.print(now.month(), DEC);
      dataLog.print(' ');
      dataLog.print(now.year(), DEC);
      dataLog.print(" ");
      dataLog.print(now.hour(), DEC);
      dataLog.print(':');
      dataLog.print(now.minute(), DEC);
      dataLog.print(':');
      dataLog.print(now.second(), DEC);
      dataLog.print(" |  ");
      if(sensor_ok) {
        dataLog.print(bme.readTemperature());
        dataLog.print("°C   |  ");
        dataLog.print(bme.readHumidity());
        dataLog.print("  | ");
        dataLog.println(bme.readPressure() / 100.0F);
        dataLog.close();
      }
      else{
        dataLog.println("  Error    |  Error   |  Error");
        dataLog.close();
      }
    }
  }
}

```

Probably far from ideal, but enough for me.

# Answer
`timestamp` in `rtcReadTime()` is a local variable. When you return from that function it ceases to exist - so what you have returned is nothing. You can't print nothing, so the Arduino crashes.

You either need to make the `timestamp` variable `static` so that it's not lost when you leave the function, make it a *global* variable, which has a similar effect, or pass a buffer variable to `rtcReadTime()` which is then filled instead of returning a pointer to a char.

The simplest of these is just to make `timestamp` static. Also you should use `snprintf` instead of `sprintf` to avoid the possibility of buffer overflows:

```
String rtcReadTime(){
  Wire.beginTransmission(RTC_I2C_ADDRESS); //Connect to address 0x68
  Wire.write(0);
  Wire.endTransmission();
  Wire.requestFrom(RTC_I2C_ADDRESS, 7);
  int sekunde    = bcdToDec(Wire.read() & 0x7f);
  int minute     = bcdToDec(Wire.read());
  int stunde     = bcdToDec(Wire.read() & 0x3f);
  //weekday not included
  /* wochentag  =*/ bcdToDec(Wire.read());
  int tag        = bcdToDec(Wire.read());
  int monat      = bcdToDec(Wire.read());
  int jahr       = bcdToDec(Wire.read())+2000;

  static char timestamp[30];
  snprintf(timestamp, 30, "%02d.%02d.%4d %02d:%02d:%02d",tag,monat,jahr,stunde,minute,sekunde);
  return timestamp;
}

```
> 1 votes

---
Tags: arduino-nano, c++, sd-card, rtc
---


title: Nrf24l01 smd pcb placement tips

text:
# Question
Title: Nrf24l01 smd pcb placement tips
I am working on pcb design with nrf24l01 smd. I have read somewhere that nrf24l01 module has problem while communication when it is placed with its antenna within the pcb. I want my module to be within the pcb as much as possible to save some space. I will be making the pcb at home and will be placing atmega 328p smd on the opposite layer. Should I fill the opposite layer with ground pad?

# Answer
> 4 votes
You need to keep the ground plane away from the antenna. The rest of the module doesn't care (and having a ground plane under it can help with unwanted EMI).

Here's a design I did recently for a customer with the same module in it. It's placed near the edge of the PCB with the ground plane cut out around the antenna:

That layout is actually set up for either the small SMD, the SMD with PA+LNB or the thorugh-hole version. The important thing is that there is a nice big exclusion zone in the ground plane where the antenna is.

---
Tags: atmega328, nrf24l01+, pcb-design
---


# Question
Title: Programming ATtiny85 with Arduino-IDE and an 8MHz external oscillator
I have a *digispark* ATtiny85 development board and I am using the Arduino IDE to program it along with the Arduino UNO as my hardware programmer.

I have successfully burned the fuses for both the internal 1 and 8 MHz RC oscillators using the *original* Arduino as ISP sketch (you'll understand why I said *original* in a moment), but as my application needs precise timing, I would like to use an external oscillator, however, every time I tried to burn/program the bootloader/fuses using the Arduino IDE and using the *original* Arduino as ISP, the avrdude spits the infamous (Yikes). I searched online and found an *updated* version of the Arduino as ISP sketch, which is supposed to an updated version, it has only one downside, which is, it can't do anything other than burn/program the bootloader/fuses, meaning that it can't be used to program the ATtiny85 like the *original* Arduino as ISP could do.

So without hesitating, I tested it to burn/program the bootloader/fuses for the internal 1 and 8 MHz RC oscillators, and it worked perfectly, and as expected, it fails to upload the code. But the *original* Arduino as ISP successfully uploaded the code. When I tried to burn/program the bootloader/fuses for the *external* 8MHz crystal oscillator using the *updated* Arduino as ISP, it worked flawlessly... until I noticed that the ordinary Arduino as ISP can not upload the code anymore and I am presented with the infamous (Yikes!) error.

Let me elaborate the difference in the *connections* between the two sketches. The updated Arduino as ISP generates a clock signal on pin #9, which connects to the CLKI of the ATtiny85 (AKA Pin #2 "PB3"), while the *original* Arduino as ISP does not utilize this pin at all.

I found the updated Arduino as ISP on the *electronics stack exchange* forum, but unfortunately I lost the link to the question which contained why is this updated Arduino as ISP is better. I can provide both codes though if someone needs them.

I have my crystal connected in both cases, burning/programming the bootloader/fuses and while trying to upload my code.

This is the infamous (Yikes!) error which I was talking about.

This is my current wiring.  Please note that I connect pin #9 to the CLKI of the ATtiny85 (AKA Pin #2 "PB3"), only when I am using the *updated* Arduino as ISP.

This is the *actual* wiring.

My two questions are:

1. How could I burn/program the bootloader/fuses of the ATtiny85 to use an external oscillator of 8MHz or 16 MHz?
2. How could I upload my application code after burning/programming the bootloader/fuses?

I hope the answers elaborate how the connections would differ, if it would.

Thank a lot in advance.

# Answer
If you look at the Digispark Schematic you'll see resistors and Zener diodes attached to XTAL1 and XTAL2:

These are for the USB D+ and D- signals that the Digispark bit-bangs. I deeply suspect that the crystal is just not going to resonate with these parts connected.

To get back to a working Digispark you'll probably have to inject signal onto XTAL1 again and reprogram the fuses to internal OSC.
> 3 votes

---
Tags: arduino-uno, arduino-ide, attiny85, arduino-as-isp
---


# Question
Title: How to split 12V power suply to arduino and led matrix panel
I'm trying to build my Arduino project with Arduino mega and led matrix panel. I'm wondering what power supply should I buy, my first thought was to power the matrix panel from a 5v Arduino pin, but I read here that it's not really a good idea. So now I'm wondering if I can buy a 12V power supply and somehow split it to 6V and 6V (or something like it). To connect one end to Arduino and the other to the matrix panel. If it's possible, how do I do that? Thanks for any help!

# Answer
> 3 votes
No,you cannot split the voltage and expect the devices (Arduino and LED strip) to work correctly together (would lead to different ground levels beside other problems). For getting a different voltage you would need a voltage regulator. A switching "buck" regulator is the better choice here than a linear regulator (lile the one on the Arduino), since it is way more efficient (To get from 12V to 5V a linear voltage regulator would burn up the excessive 7V as heat).

But since both Arduino and LED strip use 5V, why not just buying a 5V power supply, which can provide enough current. Then you can connect it to the Arduino and the LED strip in parallel. No need for voltage regulation in that case.

# Answer
> 1 votes
Figure out the amp draw of each component, i.e. Arduino and LED strip. Buy a voltage regulator that supplies the voltage needed but, more importantly, can supply the Arduino amp draw plus the LED strip amp draw.

---
Tags: arduino-mega, power
---


title: Scheduler comparison for Arduino Uno

text:
# Question
Title: Scheduler comparison for Arduino Uno
I understand that the official Arduino Scheduler doesn't support Uno, and there are several third-party schedulers to fill the gap, notably, Scheduler, Arduino-Scheduler and TaskScheduler. There are probably many more, though I see that many so-called "task schedulers" are actually just periodic function callers which don't handle context (i.e. they don't support `yield()`).

I need to make a choice of a scheduler to use in a project (a real one, with `yield`, not a periodic function caller). Is there any comparison of Arduino task schedulers? I'm specifically interested in the following aspects:

* context switching time (the most important one)
* RAM/ROM consumption estimation
* list of supported boards

# Answer
I have just tested `vbextreme/Scheduler` and `Arduino-Scheduler` using the following code:

```
#include <Scheduler.h>

void setup() {
  pinMode(3, OUTPUT);
  Scheduler.startLoop(loop2);
}

void loop() {
  digitalWrite(3, LOW);
  yield();
  digitalWrite(3, HIGH);
  yield();
}

void loop2() {
  yield();
}

```

Without any `Scheduler` lines, the code occupies 734 bytes of ROM, 9 bytes of RAM, and the pin toggles with a period of 8.5 us (117 kHz). The numbers below represent the additional ROM/RAM/execution time:

* `vbextreme/Scheduler` occupies additional 1676 bytes of ROM, 70 bytes of RAM, and the context switch takes 15.5 us (toggle frequency 14.18 kHz). It seems to only support AVR/SAMD boards.
* `vbextreme/Scheduler` with `CONFIG_AVR_OPTIMIZE_COOPERATIVE` set to 1 occupies additional 1568 bytes of ROM, 70 bytes of RAM, and the context switch takes 11 us (toggle frequency 19.07 kHz).
* `Arduino-Scheduler` occupies additional 578 bytes of ROM, 44 bytes of RAM, and the context switch takes 10.6 us (toggle frequency 19.59 kHz). It supports AVR/SAMD and some of the Teensy/STM32 boards. It seems that this scheduler is not compatible with tasks which use `malloc()`.
* `CopyThreads` occupies an additional 2148 bytes of ROM, 41 bytes of RAM, and the context switch takes 54.5 us (toggle frequency 4.417 kHz). This scheduler claims to have the advantage of using a single stack, so as long as tasks do not `yield` during peak stack usage, each task has essentially the complete stack at its disposal.

I couldn't get the equivalent code for `TaskScheduler` to run, I'll be grateful if someone posts an answer featuring schedulers I didn't test.
> 1 votes

---
Tags: arduino-uno, task
---


# Question
Title: Are there any Arduino libraries that allow you to upload data directly to PostgreSQL?
Are there any Arduino libraries that allow you to upload data directly to PostgreSQL?

I have been turning the internet upside down to answer this question but most of the information is several years old.

# Answer
> 2 votes
The only solution to this question that I could find is a GitHub repository that hasn't been touched in several years called, SimplePgSQL. Feel free to add a better answer if you are able to find something more current. More current information would be useful!

https://github.com/ethanak/SimplePgSQL

---
Tags: arduino-ide
---