# Question
Title: 100 hz Square Wave of 50% duty cycle in digital pin 3 and verifying with pin 4
I am stuck on this for a while, I am trying to generate a 100 hz square wave with 50% duty cycle in pin 3 and trying to verify it with wire at pin 4; I am getting 64000 but not 100 in serial monitor.

```

#define LEDPIN 3

uint16_t val2= pulseIn(4, HIGH);

ISR(TIMER1_COMPA_vect) { digitalWrite(LEDPIN, !digitalRead(LEDPIN)); }
void setup() {
Serial.begin(9600);
pinMode(LEDPIN, OUTPUT);
// initialize Timer1 (the 16-bit timer) using channel A output compare
noInterrupts(); // disable global interrupts
// TIMER 1 for interrupt frequency 100 Hz:
cli(); // stop interrupts
TCCR1A = 0; // set entire TCCR1A register to 0
TCCR1B = 0; // same for TCCR1B
TCNT1 = 0; // initialize counter value to 0
// set compare match register for 100 Hz increments
OCR1A = 19999; // = 16000000 / (8 * 100) - 1 (must be <65536)
// turn on CTC mode
TCCR1B |= (1 << WGM12);
// Set CS12, CS11 and CS10 bits for 8 prescaler
TCCR1B |= (0 << CS12) | (1 << CS11) | (0 << CS10);
// enable timer compare interrupt
TIMSK1 |= (1 << OCIE1A);
sei(); // allow interrupts
//TCCR1A = 0; // Timer/Counter Control Register 1A
//TCCR1B = 0; // (both control registers need to be configured)
//// set compare match register to desired timer count:
//OCR1A = 15624; // Output Compare Register 1A (i.e., for channel A)
//TCCR1B |= (1 << WGM12); // CTC (Clear Timer on Compare Match) mode
//TCCR1B |= (1 << CS10); // for 1,024 prescaler; UNO has a 16 MHz clock
//TCCR1B |= (1 << CS12);
//TIMSK1 |= (1 << OCIE1A); // enable timer compare interrupt
interrupts(); // enable global interrupts:
}
void loop() {
uint16_t val = OCR1A/8;

ICR1 = val -1;
OCR1A = val/2 - 1 ; // 50% duty cycle for pin 3
//OCR1B = val/2 - 1 ; // 50% duty cycle for pin 4
//uint16_t val2= pulseIn(4, HIGH);
Serial.print(val2);
delay(1000);
Serial.print("\n");

}

```

# Answer
> 2 votes
You wrote:

```
uint16_t val2 = pulseIn(4, HIGH);

```

It makes no sense to call this here, as the timer has not been initialized. You probably cannot expect anything but a timeout in this context.

```
noInterrupts();
cli();

```

These two are synonyms. No need to repeat yourself. Actually, no need to block interrupts at all.

```
sei();
interrupts();

```

Ditto.

```
OCR1A = 19999; // = 16000000 / (8 * 100) - 1

```

This is supposed to fire interrupts at 100 Hz. But if you want a 100 Hz output signal, you should fire the interrupts at 200 Hz (two interrupts per cycle). Thus:

```
OCR1A = 9999; // = (16 MHz / 8) / (2 * 100 Hz) - 1

```

Then,

```
// Set CS12, CS11 and CS10 bits for 8 prescaler
TCCR1B |= (0 << CS12) | (1 << CS11) | (0 << CS10);

```

This is configuring Timer 1 for an external clock source. If you want ÷8 prescaler, you should only set bit `CS11`. Check the datasheet.

```
uint16_t val = OCR1A/8;
ICR1 = val -1;
OCR1A = val/2 - 1 ; // 50% duty cycle for pin 3

```

This doesn't make any sense to me. Why are you setting `ICR1`? Why are you changing `OCR1A` although it was already configured in `setup()`? You can remove all this. Here is the `loop()` I used for testing:

```
void loop() {
    Serial.println(pulseIn(3, HIGH));
    delay(1000);
}

```

And it repeatedly printed `4955`, which is quite close to the expected value (namely 5000).

---
Tags: arduino-uno
---


# Question
Title: How do I set up communication between the "Seeeduino Xiao" and the "Adafruit Bluefruit LE UART Friend - Bluetooth Low Energy (BLE)"?
I've seen normal Arduino boards connecting to it no problem (Uno, Nano, etc.). I'm trying to connect it to my Seeeduino Xiao. It has UART compatible pins, so I'm fairly certain wiring isn't an issue. I think I'm having a hard time with the coding.

# Answer
> 1 votes
Nevermind, I figured it out. For anyone that has this problem to:

First, use the "blueart\_cmdmode" example file. Then, follow these steps:

HOW TO GET THE SEEEDUINO XIAO TO WORK WITH THIS

1. Make sure the "Adafruit\_BluefruitLE\_UART ble(Serial1, BLUEFRUIT\_UART\_MODE\_PIN);" line of text above the "void error" line is UNCOMMENTED. Everything else in that block is to still be commented.
2. Define the pins in "BluefruitConfig.h" as such: #define BLUEFRUIT\_SWUART\_RXD\_PIN 6 // Required for software serial! #define BLUEFRUIT\_SWUART\_TXD\_PIN 7 // Required for software serial! #define BLUEFRUIT\_UART\_CTS\_PIN 0 // Required for software serial! #define BLUEFRUIT\_UART\_RTS\_PIN -1 // Optional, set to -1 if unused
3. Wire the pins as defined above.
4. Make sure the Bluefruit is switched to "CMD" mode.

---
Tags: bluetooth, adafruit
---


title: Any explanation for this behavior?

text:
# Question
Title: Any explanation for this behavior?
For the below code snippet

```
const char* fr_fbdb(char tag[30]) // fn for retrieving data
{
  char full_path[120];
  const char *_dt ;
  strcpy(full_path , base_path);
  strcat(full_path , tag);
  Serial.print( "retrieving from " );
  Serial.println(full_path) ;
  Firebase.get(firebaseData, full_path);
  _dt = firebaseData.cstrData();
//  Serial.print("while ext: ");
//  Serial.println(_dt);
  return _dt ;
}

void retreive_sch()
{
  int no_tag = strlen(*tag) ;
  //Serial.print("no. of tags in the DB: ");
  //Serial.println(no_tag);
  const char *_data[no_tag];

  Firebase.get(firebaseData, "/SCHEDULE DETAILS/SELECTED");
  sch_no = firebaseData.cstrData();

  Serial.print("extracting schedule");
  Serial.println(sch_no);

  strcat(base_path , sch_no); // base path w/ sch no.

  for (int i = 0 ; i < 6 ; i++)
  {
    _data[i] = fr_fbdb(tag[i]);
    Serial.print("while ext: ");
    Serial.println(_data[i]);

  }

  for(int i=0 ; i<6 ; i++)
  {
    Serial.print("after extraction:");
    Serial.println(_data[i]) ;
  }
}

```

This is the output:

```
retrieving  schedule changes -- setup
extracting schedule3
retrieving from /SCHEDULE DETAILS/SCHEDULE3/DATE
while ext: [1609612200000,\"inf\"]
retrieving from /SCHEDULE DETAILS/SCHEDULE3/FREQ FR
while ext: \"-2\"
retrieving from /SCHEDULE DETAILS/SCHEDULE3/FREQ TO
while ext: \"-2\"
retrieving from /SCHEDULE DETAILS/SCHEDULE3/WEIGHT
while ext: 29
retrieving from /SCHEDULE DETAILS/SCHEDULE3/TIME
while ext: \"6:30\"
retrieving from /SCHEDULE DETAILS/SCHEDULE3/frequency
while ext: \"-1\"
after extraction:"root":[]
after extraction:\"-1\"
after extraction:keep-alive
after extraction:\"-1\"
after extraction:"root":[]
after extraction:\"-1\"

```

As you can see, the output of the same variable `_data[]` inside that particular function changes. Any idea why?

# Answer
The problem is these lines of code in your function `fr_fddb()`:

```
  Firebase.get(firebaseData, full_path);
  _dt = firebaseData.cstrData();

```

You didn't share enough code to make this clear, but `firebaseData` appears to be a global which you reuse. When you call its `.cstrData()` method you're getting a pointer to the same buffer each time, and that buffer is overwritten each time you call `Firebase.get()`.

You can verify this by printing the pointer value each time through, like so in your `retrieve_sch()` function:

```
  for (int i = 0 ; i < 6 ; i++)
  {
    _data[i] = fr_fbdb(tag[i]);
    Serial.print("while ext: ");
    Serial.println(_data[i]);
    Serial.printf("_data[i] pointer %p\n", _data[i]);
  }

```

You'll likely see that the 6 pointers are identical. The value is changing because you keep reusing the same string.

The easy fix is:

```
  Firebase.get(firebaseData, full_path);
  _dt = strdup(firebaseData.cstrData());

```

This allocates memory and stores in it a duplicate of the string that was fetched from Firebase. Your function will now return that and `firebaseData` can safely be reused.

This solution will require you to free that memory at some point when you're doing using it by calling `free(_dt);` or whatever you're holding the pointer in when you're done. I leave that as an exercise for you.
> 1 votes

---
Tags: esp8266, string, iot, c-string
---


# Question
Title: Calculate battery (18650 Li-ion) voltage using ESP8266-12E
i am trying to calculate the battery voltage using ESP-12E module. I am using a voltage divider circuit to calculate the same. Here is how my circuit looks like:

And here is how my code looks like:

```
float volt =0.0;
float temp=0.0;
float r1=320000.0;
float r2=100000.0;

void setup(){
    Serial.begin(115200);
    Serial.println(String(VoltageCalculator()).c_str());
}

float VoltageCalculator(){
  for (int thisReading = 0; thisReading < numReadings; thisReading++) {
    readings[thisReading] = 0;
  }
  Serial.println(analogRead(A0));
  for(int i = 0;i<=10; i++){
    total = total - readings[readIndex];
    // read from the sensor:
    readings[readIndex] = analogRead(A0);
    // add the reading to the total:
    total = total + readings[readIndex];
    // advance to the next position in the array:
    readIndex = readIndex + 1;

    // if we're at the end of the array...
    if (readIndex >= numReadings) {
      // ...wrap around to the beginning:
      readIndex = 0;
    }

    // calculate the average:
    float analogvalue = total / numReadings;

    //  int analogvalue = analogRead(A0);
    temp = (analogvalue * 3.3) / 1024.0;
    volt = temp / (r2/(r1+r2));
  }

  if(DEBUG_ENABLE){
    Serial.println();
    Serial.print("Actual Voltage : ");
    Serial.print(volt);
    Serial.println();
  }

  float volt_percent;

  if(volt == 3.1){
    volt_percent = 0;
  } else{
    float volt_diff = volt - 3.1;
    volt_percent = (volt_diff/1.1)*100;
    if(DEBUG_ENABLE){
      Serial.println();
      Serial.print("Voltage percentage : ");
      Serial.print(volt_percent);
      Serial.println();
    }
  }
  return volt_percent;
}

```

When i use this circuit with NodeMCU it works very fine, but when it comes to ESP-12E module it do not show the proper voltage. on `Serial.println(analogRead(A0));` always shows 1024.

Any suggestions why this is happening and how can i do this to achieve the most accurate value?

# Answer
Everything was correct and my circuit is also good. The only difference i found is to this below line:

`temp = (analogvalue * 3.3) / 1024.0;`

Which should be

`temp = (analogvalue * 1.0) / 1024.0;`

We are multiplying because we are referencing the voltage from voltage divider circuit as 1 volt.

After doing this, i am getting the exact values battery voltage which then i convert to percentage.

Thank you!
> 1 votes

---
Tags: esp8266, voltage-level, battery, espressif, esp
---


# Question
Title: Forcing bootloader startup through program
I am trying to find out if it is possible to trigger programmatically the *double-tap on reset button* function, implemented in modified version of Atmel's SAM-BA bootloader. The board of interest is Arduino Zero. In case this is not possible using the stock board setup, if this can be achieved by hardware or bootloader modifications.

# Answer
Theoretically it is quiet easy to fake that double-tap with software, but there might be some obstacles in practice.

The bootloader uses an unsigned long value in RAM memory to indicate if the double tap happend. The actual bootloader for the zero uses the following definitions.

```
// zero specific; but other boards use the same values AFAIK
// (in board_definitions_arduino_zero.h)
#define BOOT_DOUBLE_TAP_ADDRESS  (0x20007FFCul)
#define BOOT_DOUBLE_TAP_DATA  (*((volatile uint32_t *) BOOT_DOUBLE_TAP_ADDRESS))

// for all bootloader (in main.c)
#define DOUBLE_TAP_MAGIC 0x07738135

```

When the bootloader is started after a reset, it checks, if that was a power on reset (POR) or not. If it has been a POR, it sets the indicator value to 0 `BOOT_DOUBLE_TAP_DATA = 0;`.

If it does not detect a POR, the bootloader continues with checking the indicator value whether it is set to the tap magic.

If the magic can be found the indicator value is set back to 0 and the bootloader is started. Otherwise the value is set to the "double tap magic": `BOOT_DOUBLE_TAP_DATA = DOUBLE_TAP_MAGIC`. The bootloader waits for 500 ms to let the user reset the zero a second time (double tap) and resets the indicator value after that time interval.

---

**How to:**

To simulate a double tap, you just need to set the indicator variable with the magic value from within you program. Use the definitions above. Then perform a software reset.

---

**The caveats:**

* If the bootloader was changed, that could make you code useless.
* I have not the time to test my ideas, so this is just an unverified method. It might fail for some reasons, I do not see actually.
* You have to find a method to reset the zero with the program. Iknow some methods but I've not tried any of them so far.

---

**Reset Methods:** (as a starting point for your search)

I've read somewhere that the zero supports the CMSIS method `NVIC_SystemReset`.

This is a method often used for M0 ARM controllers (like SAMD11).

```
SCB_AIRCR = SCB_AIRCR_VECTKEY(0x5FA) | SCB_AIRCR_SYSRESETREQ_MASK;

```

---

Here is my code "idea" (untested):

```
#define BOOT_DOUBLE_TAP_ADDRESS  (0x20007FFCul)
#define BOOT_DOUBLE_TAP_DATA  (*((volatile uint32_t *) BOOT_DOUBLE_TAP_ADDRESS))
#define DOUBLE_TAP_MAGIC 0x07738135

// lots of code ....

void resetWithDoubleTap()
{
   BOOT_DOUBLE_TAP_DATA = DOUBLE_TAP_MAGIC;
   NVIC_SystemReset();
}

```

---

I would be lucky, if you succeed with this. Please let us know your outcomes, either write your own answer or tell me what you've done and I will correct my answer if necessary. Good luck.
> 3 votes

---
Tags: bootloader, arduino-zero
---


title: Receiver sleep mode RDA5807M

text:
# Question
Title: Receiver sleep mode RDA5807M
Good afternoon guys! I have a radio receiver connected to an arduino and I want it not to work all the time, but to turn on by the arduino timer for a certain time, and the rest of the time the receiver must be turned off by software. I have a working sketch that allows you to tune this receiver, and it also allows you to re-tune the receiver (set the volume and frequency) by calling a function.

```
#include <Wire.h>

#define RDA5807M_RANDOM_ACCESS_ADDRESS 0x11
// registers
#define RDA5807M_REG_CONFIG 0x02
#define RDA5807M_REG_TUNING 0x03
#define RDA5807M_REG_VOLUME 0x05
// flags
#define RDA5807M_FLG_DHIZ 0x8000
#define RDA5807M_FLG_DMUTE 0x4000
#define RDA5807M_FLG_BASS 0x1000
#define RDA5807M_FLG_ENABLE word(0x0001)
#define RDA5807M_FLG_TUNE word(0x0010)
//masks
#define RDA5807M_CHAN_MASK 0xFFC0
#define RDA5807M_CHAN_SHIFT 6
#define RDA5807M_VOLUME_MASK word(0x000F)
#define RDA5807M_VOLUME_SHIFT 0
#define RDA5807M_RSSI_MASK 0xFE00
#define RDA5807M_RSSI_SHIFT 9

//uint8_t volume; // 0..15
//uint16_t freq = 1077; // 107.3FM
uint16_t reg02h, reg03h, reg05h, reg0Bh;

void setup() {
  Serial.begin(9600);
  Nastroika(1, 4, 1077); // Receiver setting: incl. or off (on, off), volume (0 ... 15), frequency MHz * 10 (107.7 = 1077)
}

void loop() {
  Nastroika(1, 4, 1077);
  delay(5000);
  Nastroika(0, 4, 1077); // Nastroika(0)
  delay(5000);
}

void setRegister(uint8_t reg, const uint16_t value) {
  Wire.beginTransmission(0x11);
  Wire.write(reg);
  Wire.write(highByte(value));
  Wire.write(lowByte(value));
  Wire.endTransmission(true);
}

uint16_t getRegister(uint8_t reg) {
  uint16_t result;
  Wire.beginTransmission(RDA5807M_RANDOM_ACCESS_ADDRESS);
  Wire.write(reg);
  Wire.endTransmission(false);
  Wire.requestFrom(0x11, 2, true);
  result = (uint16_t)Wire.read() << 8;
  result |= Wire.read();
  return result;
}

void Nastroika(byte Key, uint8_t volume, uint16_t freq) // Receiver configuration after power failure
{
  Wire.begin();
  // Регистр 02h - inclusion, settings
  if (Key == 1)
  {
    reg02h = reg02h | RDA5807M_FLG_ENABLE | RDA5807M_FLG_DHIZ | RDA5807M_FLG_DMUTE;
  }
  else if (Key == 0)
  {
    reg02h = reg02h & ~RDA5807M_FLG_ENABLE | RDA5807M_FLG_DHIZ | RDA5807M_FLG_DMUTE;

  }
  setRegister(RDA5807M_REG_CONFIG, reg02h);
  // Регистр 03h - radio station selection
  // After reset in register 03h, the default value is 0
  // Thus BAND = 00 (87..108MHz), STEP = 00 (100kHz). Let's leave them as they are
  reg03h = (freq - 870) << RDA5807M_CHAN_SHIFT; // chan = (freq - band) / space
  setRegister(RDA5807M_REG_TUNING, reg03h | RDA5807M_FLG_TUNE);

  //Register 05h. Set the volume, do not change the rest of the beats
  reg05h = getRegister(RDA5807M_REG_VOLUME); // Reading the current value
  reg05h &= ~RDA5807M_VOLUME_MASK; // Resetting the bits VOLUME
  reg05h |= volume << RDA5807M_VOLUME_SHIFT; // Setting a new volume
  setRegister(RDA5807M_REG_VOLUME, reg05h);
}

```

I need to modify this sketch and add the ability to wake up the receiver and put it into sleep mode. There is "RDA5807M\_FLG\_ENABLE" here. As I understand it, you need to change it?

*Added later:*

The method of turning off the receiver for a while, suggested in the comments, works. However, for everything to be correct, when calling the function when the receiver is disconnected, we will send **Nastroika(0, 4, 1077);** that is, when turning off, we still specify the volume and frequency, although these parameters are superfluous here. It would be correct to write simply **Nastroika(0);** , But this cannot be done just like that, because there should be exactly three input arguments for the function, and not one.

# Answer
> 2 votes
Switch off:

```
reg02h = reg02h & ~RDA5807M_FLG_ENABLE;
setRegister(RDA5807M_REG_CONFIG, reg02h);

```

Switch on:

```
reg02h = reg02h | RDA5807M_FLG_ENABLE;
setRegister(RDA5807M_REG_CONFIG, reg02h);

```

**EDIT:** (to answer a comment of Антон)

Nastroika (настройка) means "tuning". Is that right? Then I would use this method only for tuning. Create two methods one for switching off and one for switching on.

```
void switchOff()
{
   reg02h = reg02h & ~RDA5807M_FLG_ENABLE;
   setRegister(RDA5807M_REG_CONFIG, reg02h);
}

void switchOn()
{
   reg02h = reg02h | RDA5807M_FLG_ENABLE;
   setRegister(RDA5807M_REG_CONFIG, reg02h);
}

```

In the `Nastroika` Method you should only perform the tuning and let the module of. If you insist to switch on at the same time you could use your old version.

Example:

```
void Nastroika(uint8_t volume, uint16_t freq)
{
   // !!!!! This is the wrong place for Wire begin
   // move it to the setup method.
   // Wire.begin();
   reg02h = reg02h | RDA5807M_FLG_DHIZ | RDA5807M_FLG_DMUTE;
   // or if you insist / you want to keep the module be started here
   // reg02h = reg02h | RDA5807M_FLG_ENABLE | RDA5807M_FLG_DHIZ | RDA5807M_FLG_DMUTE;
   setRegister(RDA5807M_REG_CONFIG, reg02h);
   reg03h = (freq - 870) << RDA5807M_CHAN_SHIFT;
   setRegister(RDA5807M_REG_TUNING, reg03h | RDA5807M_FLG_TUNE);

   reg05h = getRegister(RDA5807M_REG_VOLUME);
   reg05h &= ~RDA5807M_VOLUME_MASK;
   reg05h |= volume << RDA5807M_VOLUME_SHIFT;
   setRegister(RDA5807M_REG_VOLUME, reg05h);
}

```

Usage:

```
void setup()
{
   Serial.begin(9600);
   Wire.begin();
   Nastroika(4, 1077);
}

void loop()
{
  switchOff();
  delay(5000);
  switchOn();
  delay(5000);
}

```

---
Tags: sleep, functions
---


# Question
Title: Any way to use DMA to transfer data to SD Card in ESP8266
I'm using ESP8266 at speed of 160 MHz to record ADC results into SD card, I need to do this at rate of 8 KHz. Means that i should save it on the SD Card or i'll run out of memory before 4 Sec passes. I used timer1 to trigger sampling, but my problem is that surprisingly ESP8266 can not do this fast enough and the maximum sampling rate i get is about 7 KHz. I also tried to write data in ESP8266 Flash using littleFS in hope of acceleration but there was no luck. Here is my code:

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

File dataFile;

int flag = 0;
int count = 0, level = 0, se_count = 0;

void inline analogReader() // Sampling and Recording processed which is done sequentially :(
{
  uint16_t dataByte = (uint16_t) analogRead(A0);
  dataFile.write((uint8_t*) &adcBuf, 2);

}

void ICACHE_RAM_ATTR onTimerISR() { // Timer sets the flag every 0.125 MS
  flag = 1;
}

void setup() {
  pinMode(A0, INPUT);
  pinMode(D0, OUTPUT);

  Serial.begin(115200);

  if (!SD.begin(D0)) {
    Serial.println("Card failed, or not present");
    // don't do anything more:
    return;
  }
  Serial.println("card initialized.");

  File root = SD.open("/");

  if (SD.exists("real_test.bin"))
  {
    SD.remove("real_test.bin");
  }

  dataFile = SD.open("real_test.bin", FILE_WRITE);

  if (dataFile) {
    Serial.println("File created!");
  }
  else
  {
    Serial.println("Failed to create file!");
    return;
  }

  // Setting the timer so that timer interrupt fires every 0.125 MS
  timer1_attachInterrupt(onTimerISR);
  timer1_enable(TIM_DIV1/*from 80 Mhz*/, TIM_EDGE/*TIM_LEVEL*/, TIM_LOOP/*TIM_SINGLE*/);
  timer1_write(10000); /* ( 80 / 1 ) * 125 */
}

void loop() {
  if (flag) // To check whether its time to sampling or not, because of the low speed of the process
  {         // The flag is set again before one iteration ends.
    flag = 0;

    if (se_count < 10)
      analogReader();

    count++;
    if (count == 8000) // When 8000 sample & write process done notify using serial monitor. (it is
                          always more that 1 Sec. for example 1.3 Sec.)
    {
      count = 0;
      level = !level;
      Serial.println(level);

      se_count++;
      if (se_count == 10) // When we done 8000 * 10 sample & write we close the file. it supposed to
                          // be done in almost 10 sec. but it takes more time in practice. for
                          // example 13 Sec.
      {
        dataFile.close();
        Serial.println("Write ended");
      }
    }

  }
}

```

I even used a faster method system\_adc\_read\_fast(buf, num, clk\_div) that is available in ESP-SDK, So i'm desperately seeking for one or two of approaches bellow if possible:

1. To use a non-blocking approach: If there is any possibility to hand SD writing to DMA so that i only fill the ADC buffer for DMA, or an interrupt for ADC complete so that i write to SD and when interrupt fired put the result in the buffer and return back to SD writing.
2. Yet faster approach for both ADC sampling and writing: Can i increase the SD write speed of SD library? for example by configuring SPI for maximum speed rate.

I also tried SDFat library but it does not recognize my SD Card. The whole process is odd to me that even by using a 160 MHz CPU and hardware i can not record ADC data at rate of 8000 Sample/S. I have TIME limitation so please help me.

Any suggestion is appreciated. Thanks in advance.

# Answer
So, sorry for late response, i figured it out. Because it took lots of time for me and it might be a prevalent issue, i think it worth to contribute my experience for further similar issues.

As mentioned buffering can do the job, here are some constraints that should be satisfied to have right buffering mechanism;

* Writing to SD card SHOULD NOT be handled in the Timer ISR, but store ADC data into a buffer, aka int\[\] which is normally kept in SRAM (Your Timer ISR should be as short and fast as needed)
* Handle reading from buffer to SD outside of Timer ISR in, for example in loop().
* priority of ISR should be more than loop(), and it is so by default.
* It's a good practice to divide your buffer into chunk of 512 or 1024. for example 2 chunks of 1024 Bytes making your buffer. you check for "filled" flag to be set in the loop() and when this happens call SDFile.write(..) for corresponding filled chunk and then reset the flag.

By conforming to these constraints you enjoy these benefits:

* you can be sure that no ADC on time sampling missed because of sluggish SD write process.
* by buffering and pilling data and then storing, you have chance to avoid byte wise write to SD, which is really inefficient. and instead handle write in chunks of 512 or 1024 bytes. which is equal to sector size of SDs. so you have faster SD write process too.

This way you can easily handle voice recording up to 16 ksps even without using DMA.

I have added the code to my github, in this repository; https://github.com/A-R-S-D/WAVRecorder
> 3 votes

---
Tags: esp8266, sd-card, adc, spiffs, littlefs
---


# Question
Title: What is the purpose of putting a data type in brackets before a calculation?
sorry for the nooby question but I can't seem to find the answer to this anywhere, probably because I'm unsure what to search for with this problem!

I'm just wondering what the reason is for including a data type in brackets before a calculation takes place? In the code below, all the variables have already been declared at the top of the program, so I'm unsure what the reason / effect of including the (float) has. acc\_y and angle\_pitch\_acc have been declared as floats and acc\_total\_vector has been declared as long

```
angle_pitch_acc = asin((float)acc_y/acc_total_vector)* 57.296;

```

Thanks!

# Answer
It's called *casting*. It changes the data type temporarily. In this instance it's being used to change an integer type into a floating point type, which means that the whole calculation is done using floating point mathematics. However `acc_y` is supposedly already a float, but maybe it wasn't at the time the author wrote that line. Maybe things, as they often do in a program, evolved. Only the author knows.
> 2 votes

---
Tags: data-type
---


# Question
Title: What is the pinout of the Arduino MKR motor carrier when using external power supply, not the Li-Po battery
I see there is a blue terminal connector an the tags below the PCB Vin, 5V, 3,3V and GND, but I am unsure where should I supply voltage to power up the board. Also, in the product page it says the power can range from 6.5 to 11v, so what is those 5V and 3.3V all about? Thanks

# Answer
`Vin` means "Voltage Input". That's where you provide your power. That is the input to the voltage regulator.

5V and 3.3V are what the board uses internally and are provided for you to also use should you want to. These are outputs from the voltage regulators.

It's exactly the same (though more efficient and higher current) as almost every other Arduino.
> 0 votes

---
Tags: pins
---


# Question
Title: I am trying to up the frequency everytime button is press by 100 Hz, I am using the Input pull registor
The frequency should be increased by 100 Hz whenever an external push-button on UNO digital pin 5 is depressed and then released. I think I might missing something critical.

```
#define LEDPIN 3
float highTime;
float lowTime;
int freq;
float period;

//uint16_t val2= pulseIn(4, HIGH);

ISR(TIMER1_COMPA_vect) { digitalWrite(LEDPIN, !digitalRead(LEDPIN)); }
void setup() {
Serial.begin(9600);
pinMode(LEDPIN, OUTPUT);
// initialize Timer1 (the 16-bit timer) using channel A output compare

TCCR1A = 0; // set entire TCCR1A register to 0
TCCR1B = 0; // same for TCCR1B
TCNT1 = 0; // initialize counter value to 0
// set compare match register for 100 Hz increments
OCR1A = 9999; // = 16000000 / (8 * 100) - 1 (must be <65536)
// turn on CTC mode
TCCR1B |= (1 << WGM12);
// Set CS12, CS11 and CS10 bits for 8 prescaler
 TCCR1B |= (0 << CS12) | (1 << CS11) | (0 << CS10);

// enable timer compare interrupt
TIMSK1 |= (1 << OCIE1A);
sei(); // allow interrupts
interrupts(); // enable global interrupts:
}
void loop() {

highTime =(pulseIn(4, HIGH));
lowTime=(pulseIn(4, LOW));
period = highTime+lowTime;
freq=1000000/period;       //getting frequency with totalTime is in Micro seconds
Serial.print(freq);
delay(1000);

Serial.print("\n");

```

Basically I want to turn the above code which display "100" in serial monitor with raises the frequency by 100 by a button press.

```
#define LEDPIN 3
const int buttonPin = 5;    // the number of the pushbutton pin

//uint16_t val2= pulseIn(4, HIGH);
// Variables will change:
int ledState = HIGH;         // the current state of the output pin
int buttonState;             // the current reading from the input pin
int lastButtonState = LOW;   // the previous reading from the input pin

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

ISR(TIMER1_COMPA_vect) { digitalWrite(LEDPIN, !digitalRead(LEDPIN)); }
void setup() {
  Serial.begin(9600);
  pinMode(LEDPIN, OUTPUT);
  pinMode(buttonPin, INPUT_PULLUP);
  // initialize Timer1 (the 16-bit timer) using channel A output compare

  TCCR1B = 0; // same for TCCR1B
  TCNT1 = 0; // initialize counter value to 0
  // set compare match register for 100 Hz increments
  OCR1A = 9999; // = 16000000 / (8 * 100) - 1 (must be <65536)
  // turn on CTC mode
  TCCR1B |= (1 << WGM12);
  // Set CS12, CS11 and CS10 bits for 8 prescaler
  TCCR1B |= (0 << CS12) | (1 << CS11) | (0 << CS10);

  // enable timer compare interrupt
  TIMSK1 |= (1 << OCIE1A);
  sei(); // allow interrupts
  interrupts(); // enable global interrupts:

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

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

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

      // only toggle the LED if the new button state is HIGH
      if (buttonState == HIGH) {
        ledState = !ledState;
      }
    }
    lastButtonState = reading;

    Serial.print(reading);
    delay(1000);
    Serial.print("\n");

  }
}

```

# Answer
> 0 votes
Your button input pin is set to INPUT\_PULLUP mode so that pin will always read HIGH unless you ground it. Your button should connect the pin to ground when it is pressed.

If you do that, then the pin will read HIGH when the button is not pressed, and LOW when the button is pressed. Near the bottom of your loop() function, you test the button and toggle the LED with:

```
  if (buttonState == HIGH) {
      ledState = !ledState;
  }

```

But this toggles the LED when the button is released. Is that really what you meant?

---
Tags: arduino-uno
---


title: Extracting .hex from Arduino Due

text:
# Question
Title: Extracting .hex from Arduino Due
I have an Arduino Due that was programmed by the Arduino IDE, to cut things short I lost access to the original sketch (.ino) file, there is no way of recovering it no matter what.

I know that in the 8-bit MCUs I can read the .hex file from the flash memory, I already did that with PIC and AVR MCUs with their software programmer utilities.

My question is: Can I use a software programmer utility on Windows PC to extract the hex file to reprogram other Arduino Due with it? If yes, please help me. I've read about the Bossac utility, it looks promising, but I have no experience in the ARM MCUs field at all.

again: I am NOT interested in C or Assembly code, I just want the .hex file.

# Answer
> 1 votes
You can use JTAG and probably should. But, it can also be done with bossac *if* you are **very** careful. If you're not, you'll end up erasing your flash on your source board.

# Using bossac

This would maybe not be preferred over JTAG because it is probably easier to screw up (see warnings below), but it can be done. I may add some on JTAG programming later, and if I do it may be above this section for that reason. The main advantage here is just that you don't need a JTAG programmer. The one caveat is that your existing sketch, or rather the image of the sketch that has been burned onto what I'm calling the "source board" has to be functioning well enough that it can cooperate in being placed back into the ROM bootloader. I fully expect this is not a problem for you, or for pretty much any normal Arduino sketch that has been burned to a board.

## WARNINGS

* Under **NO circumstances** do you want to connect to the **PROGRAMMING port** of your **source board** at **1200** baud.
Doing so **will erase your board**, and then that's the end of it.
* In the below you *will* be connecting to the *Native USB* port at 1200, **NOT** the programming port.
**Connect only one port** at a time to your computer so there is no possibility of selecting the wrong one.
* **Practice** this whole procedure with a board you don't care about **first**.

## Locate your BOSSAC command.

On my Windows machine, it was in:

```
C:\Users\username\AppData\Local\Arduino15\packages\arduino\tools\bossac\1.6.1-ardunio\bossac.exe

```

It may be under a different version number. It's possible that it will be in a completely different location.

```
cd %USERPROFILE%
dir bossac.exe /s/b/p/a

```

Should locate it it, eventually, in any case.

On Linux it will be under ~/.arduino15 somewhere:

```
find ~/.arduino15 -name bossac

```

On a Mac it will probably be under a /Library/ directory under the user account somewhere. You get the idea, locate it, make sure you can run it.

NOTE: There's a bossa program that is the GUI version where bossa**c** is a command-line program. Unfortunately the IDE board support files don't ship the GUI program. If you're having trouble with the command-line and want to try that instead, go for it. But test it on a board you don't care about beforehand. I have not tried it.

## Connect to the Native Header

Connect your native USB port on the source board and only to that port.

## Enable boot to ROM

Open a terminal emulator of your choice at a rate of 1200 baud to the native USB port, wait a couple seconds and then close the port. You can use the Serial Monitor from the IDE to do this if you want:

* Select the correct port from Tools/Port.
* Open the Serial Monitor
* Switch the baud rate to 1200 baud.
* You're not going to type anything and you're not going to see anything once you're connected at 1200 baud.
* Close the Serial Monitor
* You probably should:

+ See if the port has changed COM#, if so select the new one.
    + Re-open the serial monitor
    + Change the baud rate again to anything-but-1200-baud
    + Close the serial monitor again.
    This is not strictly necessary but the IDE remember the last chosen baud rate, and for what we're doing this is a slightly dangerous thing.
* Close the IDE as well.

What connecting at 1200 baud does is activate the code inside the core part of the programmed sketch that changes the board to boot from the internal ROM bootloader. It doesn't need traffic. It just needs to see a request for 1200 baud. More specifically, it needs to see the DTR "signal" go inactive, which happens when the port is closed, when the effective rate was 1200 baud.

NOTE: if you **screw up** here and connect to the programming port at 1200 baud instead, you'll wind up causing the ATMega16U2 to **erase** **your source board**. The IDE remembers your last chosen baud rate, which makes this easy to screw up as well. Hence the weird little dance in the above instructions regarding reopening the serial monitor and changing to something other than 1200 baud. It's just putting an extra barrier up to accidentally doing this.

Once you've connected to the native USB port at 1200 baud and closed the port, your board will not run your sketch any more. It's still there, it's just not running it. The board has been told to sit in the ROM based bootloader, waiting for bootloader commands.

## Saving your existing sketch's image

What we're going to do is run the bossac command you found earlier like so:

```
bossac --read saved-sketch-image.bin --boot --reset

```

I'm assuming you either changed directory to where bossac.exe is, or alternately you're going to specify the necessary path to it found earlier. I've found this command locates the correct COM port automatically.

This command:

* Downloads all of flash, 512 kbyte, and takes while, 128 seconds in one test. Weirdly the same version under Linux takes closer to 10 seconds; I haven't looked into why the difference, but I'm also unconcerned.
So **you now should have a 512 kbyte raw binary file containing your sketch image.**
* It re-enables the boot-from-FLASH so that on the next reset it will go back to running your sketch
* It resets your board, so it will begin running your old sketch. If you don't want it to do that until you power cycle it, you could just as easily leave off the `--reset` part.

*As said, this is a raw binary file. But you mentioned a HEX. I'm assuming you didn't mean that literally, so I'm not going to detail how to convert the .bin file to a HEX format. Though, if you want to do that, you should know that it needs to be offset to 0x80000, because that's where flash starts on the Due.*

Disconnect your source board from USB.

## Making your clone (target) board

Connect to your target board via the programming port.

* Hold the erase button for a few seconds to make sure the target board is erased. Usually this would be done by the IDE connecting to the port for a while at 1200 baud. But since we're using bossac at the command line, we need to do that step manually; it's just easier to use the button this time.
* Reset the board with the reset button. Your target board is now sitting in its ROM bootloader awaiting commands.
* Put your image on the new board with:

```
bossac --write saved-sketch-image.bin --boot --reset

```
* Again, it's programming the whole 512 kbytes. In one test on Windows it took about 100 seconds; no difference between Windows and Linux. We're using the USART (programming port) which is slower than USB and we're flashing rather than reading which is slower; I haven't bothered to figure out which thing is the bottleneck.
* Like before `--boot` sets the board to boot from flash (your sketch) on next reset.
* And again `--reset` just resets the board.

Your target board should now be be behaving identically to the original source board.

---
Tags: arduino-due
---


title: How to make car turn 90 degrees?

text:
# Question
Title: How to make car turn 90 degrees?
I have an elegoo car model and am trying to make it turn 90 degrees whenever it gets to a 90 degree turn. This model has line tracing and it works fine on curved surfaces but doesn't work so on 90 degree turns.

```
    /Line Tracking IO define
#define LT_R !digitalRead(10)//connected to pin 10. Value is inverted
#define LT_M !digitalRead(4)
#define LT_L !digitalRead(2)

#define ENA 5//input to enable motor A. Controls speed
#define ENB 6//input to enable motor B
#define IN1 7//Control spinning direction of motor A. If one of them is high motor spin(an OR gate)
#define IN2 8//Same motor A
#define IN3 9//3 and 4 are for motor B
#define IN4 11

#define carSpeed 100

void forward(){ //car goes forward
  analogWrite(ENA, carSpeed);
  analogWrite(ENB, carSpeed);
  digitalWrite(IN1, HIGH);
  digitalWrite(IN2, LOW);
  digitalWrite(IN3, LOW);
  digitalWrite(IN4, HIGH);
  Serial.println("go forward!");
}

void back(){ //car goes backwards
  analogWrite(ENA, carSpeed);
  analogWrite(ENB, carSpeed);
  digitalWrite(IN1, LOW);
  digitalWrite(IN2, HIGH);
  digitalWrite(IN3, HIGH);
  digitalWrite(IN4, LOW);
  Serial.println("go back!");
}

void left(){ //goes left
  analogWrite(ENA, carSpeed);
  analogWrite(ENB, carSpeed);
  digitalWrite(IN1, LOW);
  digitalWrite(IN2, HIGH);
  digitalWrite(IN3, LOW);
  digitalWrite(IN4, HIGH);
  Serial.println("go left!");
}

void right(){ //goes right
  analogWrite(ENA, carSpeed);
  analogWrite(ENB, carSpeed);
  digitalWrite(IN1, HIGH);
  digitalWrite(IN2, LOW);
  digitalWrite(IN3, HIGH);
  digitalWrite(IN4, LOW);
  Serial.println("go right!");
}

void stop(){ //power is shut off
   digitalWrite(ENA, LOW);
   digitalWrite(ENB, LOW);
   Serial.println("Stop!");
}

void setup(){
  Serial.begin(9600);
  pinMode(LT_R,INPUT);//takes input from all the sensors
  pinMode(LT_M,INPUT);
  pinMode(LT_L,INPUT);
}

void loop() {

  if(LT_M){
    forward();
    while(LT_M);
  }
  else if(LT_R) {
    right();
    while(LT_R);
  }
  else if(LT_L) {
    left();
    while(LT_L);
  }

  else if (LT_M && LT_R && !LT_L) {
  delay(500);
  right();
  }

  else if (LT_L && LT_R && !LT_R) {
   delay(500);
   left();
    }

```

# Answer
> 1 votes
First: Your code as 2 problems:

* As stated in the comments by PeterPaulKiefer, when you use

```
  pinMode(LT_R,INPUT);

```

That is not working as intended by you. `LT_R` is defined at the top as

```
  #define LT_R !digitalRead(10)

```

Thus the compiler will see

```
  pinMode(!digitalRead(10), INPUT);

```

`digitalRead()` will return zero or one, thus you are configuring pin 0 or pin 1 here (depending on the state of the sensor at startup). Instead you need to directly use the pin number (10) or use another define for the pin number itself. Your code only works, because all the pins are configured as INPUT (tristate) at startup of the microcontroller, so that they don't break something with a wrong signal. You got lucky there.
* The last two else if statements are never executed:

```
  else if (LT_M && LT_R && !LT_L) {
      delay(500);
      right();
  }
  else if (LT_L && LT_R && !LT_R) {
      delay(500);
      left();
  }

```

The conditions here will first evaluate `LT_M` (in the first statement) and `LT_L` (in the second statement) respectively. Only if these are true, the rest of the expression will be evaluated. But you already checked for both of them being true above. When they are, the following else if statements don't get executed (thats the logic of if else statements). And if they are false, the code will also not be executed.

When you get to a 90° right corner, the middle and right sensor will trigger. Currently this will lead to the robot just keeping going forward.

So you need to change your code to actually check every every possible combination of the sensor states.

Also keep in mind, that a sharp corner needs way more turning, than a curve. Depending on the width of the line are the distance between your sensors, you might or might not be able to distinguish between those two cases. You should analyze, which sensor states you would have in which situations, write that down and then write code for every state. You could also put all sensor states into one single number, so that it is easier to check for it in the code. Something like this:

```
byte all_states = digitalRead(2) + 2*digitalRead(4) + 4*digitalRead(10);

```

Each combination will give you a unique number to work with. Effectively this stores the states of the sensors in one bit of the number each. Bit 0 is for pin 2, bit 1 is for pin 4 and bit 2 is for pin 10. You can also write this with bitwise operators:

```
byte all_states = digitalRead(2) | (digitalRead(4)<<1) | (digitalRead(10)<<2);

```

For example: If the right sensor is triggered, but not the others, you would get a binary number `0b00000100`, which is decimal `4`. If the left and the middle sensor are triggered, but not the right one, this results in `0b00000011`, which is decimal `3`. Then you could check with a switch statement:

```
switch(all_states){
    case 0: //No sensors triggered
        break;
    case 1: // Left sensor triggered
        break;
    case 2: // middle sensor triggerd
        break;
    case 3: // middle and left sensor triggered
        break;
    ...
}

```

You see how it works. The code for each case then goes inbetween of each case and break line.

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


title: Memory for inputs?

text:
# Question
Title: Memory for inputs?
When a button is pressed, the Arduino might be busy with something (like drawing the screen). When the Arduino has finally time to check the button input, the uses might have release it already.

Is there a way that can store the input until the Arduino has time to check it? It would be awesome if there was ic that could take care of this.

Thanks for the help!

# Answer
The answer to your direct question, is there an IC to store an input, is yes. It's called a Set-Reset (or SR) Flip-Flop. I don't know if they're packaged standalone in an IC but they're really simple to make with a pair of cross-connected NAND gates.

But that's not really the right solution to your problem. Your code should not be so "busy" that it misses a slow input like a push-button. I quoted "busy" because it is usually delay() calls, not computations, that occupy the processor for any large amounts of time, and delay()s are to be avoided if your code has any more than 1 thing to do.

Look up the Blink Without Delay example-sketch in the Arduino IDE for the unvarnished, basic approach to doing this. Then there are libraries that can help with the low-level details of doing it - SimpleTimer, is one such. Or, if your code is stuck waiting for slow external events, don't wait for them but check for them frequently and move on immediately to something else, if they haven't taken place yet.
> 0 votes

# Answer
The basic guidance when writing Arduino applications is to do a small amount of work on every pass through the loop function, then do a little bit more on the next pass. Check all your inputs, execute logic in response to those inputs, set up `unsigned long` variables with future `millis()` values, check those values to see if a future time has arrived, and repeat.

Do **not** use `delay()`. It is the death of a cooperative system like an Arduino. When your Arduino executes a call to `delay()`, everything stops until the delay time has passed.
> 0 votes

# Answer
> Is there a way that can store the input until the Arduino has time to check it?

No, there is no way to remember/buffer input changes within the Arduino (You could use a flipfop IC like JRobert wrote. That can give you that functionality). But there are interrupts, that you can use with pins. A triggered interrupt will really interrupt the main code from running and execute its corresponding ISR (Interrupt Service Routine), to handle the interrupt cause, and then returning to execute the main code. A microcontoller has many different interrupts, each one connected to its special hardware. There are interrupts for the Serial interface, for SPI, I2C, and also some connected to the External Interrupt pins or the PinChange Interrupt (these last two could be used with your button). So this would not "store" the input change, but it will interrupt the main code to immediately act upon the input change. So that's a different principle.

If you want to bind your button to an interrupt, you could just stay in the Arduino Framework and use the `attachInterrupt()` function. There are many tutorials online for that. Keep in mind, that you should never do long things inside an ISR, and functions like `delay()` won't work there.

---

That said, most likely it is not really needed to use interrupts with buttons. Humans are rather slow, thus each button press will last in the ballpark of 100ms or longer.

You could now say, that your code is doing things longer than 100ms. But here the rabbit is buried (literal translation of a german saying, meaning "there is the problem"). When starting with Arduino, one is doing many blocking things, like `delay()` or blocking while loops. These are often very easy to implement, but nothing else will be running during these things.

Instead you should divide up your actions into small parts. When it is time to do something, you are doing that small part and exit fast. This enables other code to run in between. A good example is the `BlinkWithoutDelay` example. The normal blink example uses `delay()`, which blocks everything else. Instead you can use the `millis()` function as a clock and only take action, when it is time to do so, otherwise to further fast. Much like you would bake a pizza in your oven. You won't sit in front of the oven, waiting for the pizza to be ready. You would do something else and regularly look at your clock, if it is time to take the pizza out.

You didn't show your code, so we cannot advice you more in that direction. But you can find many tutorials about it, if you search for terms like `Arduino blink without delay` or `Arduino millis tutorial`.
> 0 votes

---
Tags: arduino-uno, hardware, input
---


title: 2 stepper cnc inaccurate

text:
# Question
Title: 2 stepper cnc inaccurate
I'm building a simple cnc machine that just writes letters. It uses 2 steppers for x and y axis.

Here is how it works

1. generate letters in c# and convert them to list of lines
2. send to arduino mov\_xy line.x line.y as string for each line
3. on arduino convert to int, multiply by steps per mm and run with speedy stepper

It eventually builds up to accuracy problems. If it's writing "ZWX", letter "X" would be slightly to the side.

Things i tried:

* 500000 baud rate
* accumulate remainder of float number of steps
* different usb cables
* different cnc machines

It is serial communication error?

Do i need to implement CRC?

Can UNO handle this?

Does SERIAL\_8E1 do parity check automatically or do i need do something?

I went trough everything many times. What am i missing here?

This image is generated directly from letter lines in c#, so i doubt the problem is on c# side.

# Answer
I forgot to take care of negative steps in remainder accumulation. This solved it.

```
// x accum
float resX = mmX * (float)X_STEPS_PER_MM;
float lresX = (long)resX;
_x_acum += resX - lresX;

long extraStepsX = 0;
while(_x_acum > 1.0f){
     _x_acum -= 1.0f;
     ++extraStepsX;
}

while(_x_acum < -1.0f){
     _x_acum += 1.0f;
    --extraStepsX;
}
// move stepper for lresX + extraSteps

```
> 1 votes

---
Tags: arduino-uno, stepper
---


title: RF sniffer with Arduino

text:
# Question
Title: RF sniffer with Arduino
Hello programmers out in the world. I am doing a capstone project for an RF sniffer to capture RF signals from Key fobs within an OEM manufacturing plant. I want to be able to decode this RF signal to show me what the battery state of the key fob is. I have the protocol, so I know what data I should be receiving. However, I have tried many libraries on the Arduino UNO and none have worked. This Key fob specs are FSK modulation. Frequency of 433 Mhz, Bit rate -\> 9.6Kbit/s, baud rate of 19.2Kbaud/s and coding is manchester.

Any help would be greatly appreciated.

# Answer
I actaully found this this week that I was suing ASK RF receiver module, when I needed FSK. I have used RC Switch, and no luck, along with Radio head. However as mentioned the key fob will not work with ASK. I am trying to find a library for FSK but no luck as of now.

-Pete
> 1 votes

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


# Question
Title: How to use 3 digital input pins on Arduino Uno for frequency inputs and total the output?
I am working on a Arduino tachometer that reads the RPM of a BLDC motor. The motor circuit does not use the hall sensors so I would like to use them for RPM sensors. I have already hooked up an Uno board using one pin as an input with the internal pull up enabled and it works fine.The reason I want to use all 3 hall sensors is to increase the pulse count per revolution to steady the reading on my LCD display at lower speeds. I have been searching for information on how to read 3 inputs, and totalize the pulses for this purpose but have not been able to find the information.

# Answer
Assuming that only one sensor will trigger each time then (as jsotola suggested) tie them together and connect the common output to an interrupt pin. Arduino UNO has interrupt functionality on pins 2, 3.

As an example for counting the pulses using pin2 on falling edge (modified from https://www.arduino.cc/reference/en/language/functions/external-interrupts/attachinterrupt/):

```
const byte interruptPin = 2;
volatile int numPulses = 0; // change type of variable according your needs

void setup() {
    pinMode(interruptPin, INPUT_PULLUP);
    attachInterrupt(digitalPinToInterrupt(interruptPin), sumPulses, FALLING);
    Serial.begin(9600);
}

void loop() {
    Serial.println(numPulses);
    delay(500);
}

 void sumPulses { // keep the ISR as short as possible
    numPulses++;
 }

```
> 1 votes

# Answer
An alternative method of frequency determination is to measure period and take the reciprocal. It can be extremely accurate and responsive at very low frequencies, so you don't need to combine multiple sensors just to increase the rate.

Note that you are not limited to measuring a single period; you can count the microseconds in N periods to increase resolution at high frequencies.
> 0 votes

---
Tags: arduino-uno
---


# Question
Title: Doing several things at the same time with functions, objects or interrupts?
First of all, thank you for taking the time to read this. I am a newbie, so apologies (done examples on arduino website, basic C++).

I'm trying to get an idea of what the best way to structure a sketch is, which needs to do several things at the same time. For example, reading an IMU sensor and using it to control the mouse, reading a button for on/off and let's say flashing an LED. I have repetitive injury so this is the project I'm trying to complete, but the principle should be scalable for more complex projects.

I've come across some great resources and my understanding is you can use:

1. functions (e.g. blink without delay)
2. objects (cooperative multitasking)
3. interrupts
4. something like a RTOS

Where my limits lie is understanding the benefits/limitations of these options and picking which one to focus on for my project. For example, if using functions is sufficient, why do people bother with interrupts and installing a RTOS?

I would appreciate any guidance for what an effective approach should look like.

Thanks again.

# Answer
> 2 votes
An RTOS may be a good option for running a complex application on a quite powerful Arduino. Many Arduinos (the AVR-based ones), however, are too limited to run complex applications, and the overhead of an RTOS is quite significant for them. In this case you end up with two options:

* non-blocking programming
* interrupts

Whichever is best depends on the specific tasks you are managing.

### Non-blocking programming

This is best exemplified by the Blink Without Delay Arduino tutorial. The general principle is to break down you code into small non-blocking tasks, and perform each one only when it is the right time to do so. Breaking down the program logic into a set of non-blocking tasks is not always completely trivial, but you can use a Finite state machine, which is a very powerful and general concept for doing so in a systematic way.

Once all task are non-blocking, the main program loop then looks like this pseudo-code:

```
void loop() {
    if (task_1_should_be_performed_now()) {
        perform_task_1();
    }
    if (task_2_should_be_performed_now()) {
        perform_task_2();
    }
    // etc...
}

```

Most of the time, all conditions are false, and the program swifts through the tests completing the loop in a very short time. Occasionally, it performs one of the tasks, which makes the loop longer but, since the tasks never block, not very long anyway. Typical loop time is highly dependent on the specifics of your code, but I would expect it to be no more than one millisecond most of the time.

This is probably the most common pattern for multitasking on the Arduino. You can encapsulate this logic in functions, objects, libraries, etc. This is the approach I would recommend provided none of your tasks is so urgent that it cannot wait for one loop iteration.

### Interrupts

Occasionally, you may have a task that is so urgent that it cannot wait for the next loop iteration. It has to be performed right now. Or maybe the loop takes a very long time because of a blocking call in a library you have no control over. In those situations, an interrupt may be the best option.

Interrupts come with some tricky programming issues, which require some precautions on the part of the programmer:

* they block other interrupts, increasing their latency → interrupt service routines should be as short as possible
* they can cause problems with non-reentrant library functions → those functions should be avoided in interrupt context
* they can interact badly with the optimizer → variables used in both interrupt context and normal context should be qualified as `volatile`
* they can cause synchronization issues with the data shared with the main code → access to that data in normal context should be protected in critical sections.

For all these reasons, it is best to use interrupts only when needed, i.e. only when a task cannot wait for the next iteration of `loop()`.

---
Tags: interrupt, timers, class, functions
---


# Question
Title: Can I use the microchip of Arduino Uno as a standalone microcontroller
I want use the `ATmega328P` chip of the `Arduino Uno` board as a **standalone** device.

* Is that possible?
* Which pins are which on the Arduino board and the `ATmega328P`?
* Do I need any external components?

# Answer
Yes it's possible. To use the ATmega328P to "emulate" an Arduino Uno board (without the USB part) you just need 3 ou 4 additional components: the oscillator, two capacitors and a resistor. Please take a look at: https://www.arduino.cc/en/Tutorial/BuiltInExamples/ArduinoToBreadboard for a schematic/breadboard. The Atmega328P features itself the memory, cpu and flash so those components are already inside the chip. You can find the relation of the pins in this image:
> 1 votes

# Answer
You can check the UNO's schematic. You can use this as a starting position. You can leave out the things you don't need. You might for example have no need for a voltage regulator on your board.

You may also have a look at the schematic of the Pro Mini, which are a lot more bare-bones.
> 0 votes

---
Tags: arduino-uno, atmega328
---


# Question
Title: Understanding the compilation/linking/upload process (so I don't have to use the IDE)
I have started to play with and arduino UNO quite recently (without any prior experience with micro-controllers). I would like to use emacs instead of the IDE, and I'd also like to know what the IDE does under the hood, in order to be able to write my own makefile. The tutorials I've found are either outdated, or are presented as a series of steps without any explanation. I'd appreciate it if someone could explain to me how the whole compliation/linking/upload process works using gcc-avr and avr-dude, and how it is used by the IDE.

# Answer
If you want an *exact* duplication of what the IDE does but want it driven from the command line, that's what Ino is for. The full Arduino build process involves copying a lot of files from a lot of places, and is generally not trivial to duplicate.

If you're ready to let go of .ino files and the Arduino libraries, you get a much simpler toolset. avr-gcc compiles, avrdude uploads, and you're done. Here's one of my makefiles from a simple project:

```
CC=avr-gcc
CXX=avr-c++
CXXFLAGS=-Wall -Wextra -mmcu=atmega1284p -Os
CFLAGS=$(CXXFLAGS)
BINARY=ledmatrix
OBJECTS=

all: $(BINARY)
↹@avr-size $<

$(BINARY): $(OBJECTS)

clean:
↹@rm -f $(BINARY) $(BINARY).hex $(OBJECTS)

upload: $(BINARY).hex
↹@avrdude -c usbasp -p m1284p -U flash:w:$<:i

%.hex: %
↹@avr-objcopy -j .text -j .data -O ihex $< $@

.PHONY: all clean upload

```

If copying-and-pasting, be sure to replace all "↹" with tab characters.

**EDIT:**

I have created a repository with my buildsystem on Github.
> 13 votes

# Answer
Here is a high-level overview of Arduino's compilation process, for folks like me who found this post while hunting for one:

**The compilation process**

The arduino code is actually just plain old c without all the header part (the includes and all). when you press the 'compile' button, the IDE saves the current file as arduino.c in the 'lib/build' directory then it calls a makefile contained in the 'lib' directory.

This makefile copies arduino.c as prog.c into 'lib/tmp' adding 'wiringlite.inc' as the beginning of it. this operation makes the arduino/wiring code into a proper c file (called prog.c).

After this, it copies all the files in the 'core' directory into 'lib/tmp'. these files are the implementation of the various arduino/wiring commands adding to these files adds commands to the language

The core files are supported by pascal stang's procyon avr-lib that is contained in the 'lib/avrlib' directory

At this point the code contained in lib/tmp is ready to be compiled with the c compiler contained in 'tools'. If the make operation is succesfull then you'll have prog.hex ready to be downloaded into the processor.

https://www.arduino.cc/en/Main/Documentation
> 0 votes

---
Tags: arduino-uno, avrdude, ide, avr-gcc
---


# Question
Title: ESP8266 WiFi Not Connecting to Internet Without Static IP
I am seeing some very strange behavior with my ESP8266. When I connect it to the WiFi for the first couple of times I am not seeing any issues and the ESP8266 connects just fine.

But after an arbitrary amount of times (like when I restart the unit) it tries to connect for AGES (like multiple minutes). Eventually it says "Connected" but the IP is completely wrong and it is not connected to the internet (GET request fails).

Here are the odd things:

* If I assign a static IP then it ALWAYS works and connects within seconds
* If I factory reset my router then it works again for a few times
* I have not seen this with any other device (like laptops or cellphones)

It is almost as if the DHCP is failing to assign an IP and then returns some random default.

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

// Replace these with your WiFi network settings
const char* ssid = "MYSSID"; //replace this with your WiFi network name
const char* password = "MYPASSWORD"; //replace this with your WiFi network password

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

  IPAddress ip(192,168,1,77);
  IPAddress gateway(192,168,1,1);
  IPAddress subnet(255,255,255,0);

// If I uncomment this line then it works fine
//  WiFi.config(ip, gateway, subnet);

  WiFi.begin(ssid, password);

  Serial.println();
  Serial.print("Connecting");

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }

  Serial.println("success!");
  Serial.print("IP Address is: ");
  Serial.println(WiFi.localIP());
}

void loop() {
  HTTPClient http;

  String serverPath = "http://www.google.com";
  http.begin(serverPath.c_str());

  // Send HTTP GET request
  int httpResponseCode = http.GET();
  Serial.print("HTTP Response code: ");
  Serial.println(httpResponseCode);
  String payload = http.getString();
  Serial.println(payload);
  // Free resources
  http.end();

  delay(1000);
}

```

When DHCP magically works it assigns: `192.168.1.159`

When DHCP does not work I get: `169.254.104.241`

When I use a static IP then the static IP is assigned.

**So the question is:** Has anyone seen this behavior and maybe give some hints about how I can get the internet connection to be consistent without needing a static IP?

**Update:** If I run a ping to `169.254.104.241` I get a reply. But if I try to get anything from the internet I get HTTP Response Code = -1.

# Answer
Finally I figured out a solution. I downgraded the ESP8266 board version in Arduino Studio to 2.5.2 and it worked.
> 1 votes

# Answer
This is normal behavior. well not really, that address is called a **apipa address**.

It's normal behavior for alot of O.S's to give itself an address in the 169.254.x.x range **when they fail to get DHCP responses**.

My guess is your library is doing this for you.

It's kind of like the ad-hoc of addressing, if all devices fail to get a dhcp response they will all be assigned to the same subnet, and can communicate with those **apipa addresses**.

My suspicion is that it may be your router. You can verify this by downloading a free DHCP server application for your OS. Plug in via Ethernet for the PC that's running the DHCP App, Turn off DHCP in the router. If it stops happening you know it's the router.

Edit: Also, this may be a firmware caveat in the router. Check the router manufacturers website and see if any firmware updates are available. if it hangs with DHCP, most likely every customer with that firmware revision has had this problem. This sort of thing usually gets patched very quickly.
> 4 votes

# Answer
Thanks for posting the question and the solution. I spent hours on google and reading message boards before coming across this. I am not sure if my root cause was the same, but to me the "strange" IP for my ESP8266 (nodemcu) came from them connecting through the Guest Network of my Asus router. This resulted in an identical problem to OP with complete random connecting and long duration of no connections to WiFi, Internet and Blynk

Reverting back to ESP8266 2.5.2 in Arduino Studio seems to have magically solved the issue. Someone should alert the makers of the library.
> 1 votes

---
Tags: esp8266, wifi
---


# Question
Title: Why all unset pins of my Arduino Uno are outputting 2 volts?
I am new to Arduino and physical computing When I measure the wire coming from any **UNSET** Arduino uno pin, the result is approximately 2 volts **even the "ANALOG IN" pins**. Considering that the pins which been set to HIGH and LOW are giving 5 and 0 volts "which is cool". Is that the nature of Arduino or is that a failure caused by short or anything else?

# Answer
After a microcontroller reset, AVR IO pins default to input. In this state they have high impedance. For example, according to the Atmel ATmega328 spec sheet doc8271 Table 29-15, analog input impedance typically can be taken as 100 MΩ for design purposes. (Input pin impedance may in fact be orders of magnitude more, effectively an open circuit except for leakage currents of a few nanoamps.) Each pin has a few pF (5-10?) of capacitance \[,,,\] which in general is small compared to stray capacitances of attached wiring.

When stray electromagnetic fields charge the pin and stray capacitances, a small voltage develops on the pin. You could connect a 1 to 10 MΩ resistor between the pin and ground, to avoid the 2 V you are seeing.
> 1 votes

# Answer
The electric shocks being felt is due to leakage current from the laptop's switchmode power supply. All unearthed mains powered switchmode plug pack power supplies leak a few micro amps and voltages in excess of 80 volts AC as measured from the plug packs output socket to ground will be observed when measuring with multimeters having 10 meg ohm input impedance.

The solution is to have the GND pin of the arduino board connected to earth. Here in Australia all computer power supplies are grounded via the 3 pin power plug.
> 2 votes

# Answer
The pin is default to Tri-State or High-impedance(Hi-Z) which means they do not either sink or source current. Just as others say it's a matter about electromagnetic or some such. A voltmeter can measure its voltage because the current it takes is small enough(close to or smaller than the leakage current). The real value is undefined when you are not measuring it. Instead of reading analog pin values, You can try reading digital pins to take a better look at "floating".

A Hi-Z pin can absolutely power nothing from LED to other big stuffs. If all you want is just stable readings, well, this is where pull-up or pull-down resistors come in place. Typically these resistors can be from 10KΩ to 10MΩ, ensuring that when the pin is not connected they will provide the pins with stable values while when connected the influence of pulls can be safely ignored.
> 0 votes

---
Tags: arduino-uno, pins
---


# Question
Title: Firmata.SendString doesn't work with specific `char` variables
I have a Firmata sketch, that accepts string messages, partitions them and sends its' parts back to a Firmata client program. My problem is certainly at the sketch's side. The problem is that `Firmata.sendString(argument1)` and `Firmata.sendString(argument2)` methods don't send anything. More information is found in the sketch's code. How can I get the `sendString` methods to work?

```
/*
 * This sketch accepts strings in the following form:
 * CMDn(arg1,arg2)
 * CMDn — command name,
 * arg1 и arg2 — unnecessary arguments.
 * Each argument's length can be from 1 to 4 characters,
 * They're saved to separate variables.
 *
 * This sketch sends back the parsed commands partially:
 * the command name, argument #1 (if present), argument #2 (if present)
 */

#include <Firmata.h>

void stringCallback(char *received) {
  //CMDn(arg1,arg2)
  //CMDn(arg1)
  //CMDn(1)
  //CMDn()
  //012345678901234
  //          11111

  //This scheme up there is just for
  //understanding the indexes of the chars in the string
  //in its various possible variations

  //Let's declare all the necessary variables
  char methodName[5];
  char argument1[5];
  char argument2[5];
  byte commaLocation = 0;

  //If the received string doesn't match the strings' syntax,
  //send an error message
  if (!(received[4] == '(' && strlen(received) <= 15)) {
    Firmata.sendString("ERR;");
    return;
  }

  //Let's take the 0-3 chars in the string and send it back.
  //It's probably the command name
  for (int i = 0; i < 4; i++) {
    methodName[i] = received[i];
  }
  methodName[4] = '\0'; //does or doesn't the compiler add the terminator automatically?
  Firmata.sendString(methodName); //send it
  //This string is being sent without problems.

  //If there is some arguments in the string,
  //it is detectable if the string char 5 is not ')'/
  if (received[5] != ')') {
    //Lent's find out if the input string has a `comma`
    //inside the parentheses. If it does, it means that
    //there are two arguments in the string.

    Firmata.sendString("46 passed");
    for (int i = 6; i < (strlen(received) - 1); i++) {
      //If there is a comma, save its' index and break the loop
      if (received[i] == ',') {
        commaLocation = i;
        break;
      }
    }

    //If a comma is not present, its location variable equals 0,
    //sincerely we just collect all the chars between the parentheses
    //to the 'argument1' variable and send it.
    if (commaLocation == 0) {
      Firmata.sendString("61 passed");
      for (int i = 5; i < ; i++) {
        argument1[(i - 5)] = received[i];
      }

      argument1[strlen(argument1)] = '\0'; //Either this is executed or not, the outcome doesn't change

      Firmata.sendString(argument1); //This very command doesn't work. It just does not send anything.
                                     //Looks like 'argument1' is empty, but I'm awfully sure that it must
                                     //not be empty. Anyway, the 'argument1' does not show up in the client
    }

    //If there is a comma present, then write chars before the comma
    //to 'argument1', and after the comma - to 'argument2'
    if (commaLocation != 0) {
      Firmata.sendString("77 passed");
      //let's write what is before the comma:
      for (int i = 5; i < commaLocation; i++) {
        argument1[i - 5] = received[i];
        Firmata.sendString("81 iterator");
      }

      //let's write what's after the comma;
      char argument2[5];
      for (int i = (commaLocation + 1); i < (strlen(received)); i++) {
        argument2[(i - (commaLocation + 1))] = received[i];
        Firmata.sendString("87 iterator");
      }

      argument1[strlen(argument1)] = '\0'; //Either this is executed or not, the outcome doesn't change
      argument2[strlen(argument2)] = '\0';

      Firmata.sendString(argument1); //Not working
      Firmata.sendString(argument2); //Not working
    }
  }
}

void sysexCallback(byte command, byte argc, byte *argv) {
  Firmata.sendSysex(command, argc, argv);
}

void setup() {
  Firmata.setFirmwareVersion(FIRMATA_FIRMWARE_MAJOR_VERSION, FIRMATA_FIRMWARE_MINOR_VERSION);
  Firmata.attach(STRING_DATA, stringCallback);
  Firmata.attach(START_SYSEX, sysexCallback);
  Firmata.begin(57600);
}

void loop() {
  while (Firmata.available()) {
    Firmata.processInput();
  }
}

```

Expected output:

| What I send | What I receive (excluding the debug messages, `;` stands for newline) |
| --- | --- |
| `DHTt()` | `DHTt` |
| `DHTt(1)` | `DHTt`; `1` |
| `DHTt(1,2)` | `DHTt`; `1`; `2` |

Real output:

| What I send | What I receive (excluding the debug messages) |
| --- | --- |
| `DHTt()` | `DHTt` *as long as there are no arguments, there are no problems. But the arguments are necessary for my task* |
| `DHTt(1)` | `DHTt` *the argument are not sent* |
| `DHTt(1,2)` | `DHTt` *two arguments are not sent neither* |

# Answer
`Firmata.sendString` does not send anything to the client in two cases:

* If the message is empty;
* **If the message does not contain the `\0` terminator in it**.

In this case, while you're sending `methodName`, you're manually assigning the terminator to the string; and the sender works:

```
methodName[4] = '\0';

```

The only thing necessary to do to solve this argument problem is making each `char` variable end with a null terminator. Here you can see the solved code:

```
#include <Firmata.h>

//setup() and loop() won't be here, there are no changes in them

unsigned long charIndex(const char * findIn, unsigned int symbol) {
  //Find 'symbol' in char array 'findIn'. Unlike
  //strchr(), returns unsigned long or 0 if 'symbol' not found

  char * pointer = strchr(findIn, symbol);
  if (pointer != NULL) return (pointer - findIn);
  if (pointer == NULL) return 0;
}

void stringCallback(char *received) {
  //Let's declare all the necessary variables
  char methodName[5];
  char argument1[5];
  char argument2[5];
  int commaLocation = 0;
  int lasti;

  byte nullTerminatorIndex = strlen(received); //For understanding

  //If the received string doesn't match the strings' syntax,
  //send an error message
  if (!(received[4] == '(' && strlen(received) <= 15)) {
    Firmata.sendString("ERR;");
    return;
  }

  //Let's take the 0-3 chars in the string and send it back.
  //It's probably the command name
  for (int i = 0; i < 4; i++) {
    methodName[i] = received[i];
  }
  methodName[4] = '\0'; //**The compiler doesn't add terminators automatically**.
  Firmata.sendString(methodName); //send it
  //This string is being sent without problems.

  //If there is some arguments in the string,
  //it is detectable if the string char 5 is not ')'/
  if (received[5] != ')') {
    //Lent's find out if the input string has a `comma`
    //inside the parentheses. If it does, it means that
    //there are two arguments in the string.

    Firmata.sendString("46 passed");
    if (charIndex(received, ',') != 0) commaLocation = charIndex(received, ',');

    //If a comma is not present, its location variable equals 0,
    //sincerely we just collect all the chars between the parentheses
    //to the 'argument1' variable and send it.
    if (commaLocation == 0) {
      Firmata.sendString("61 passed");
      for (int i = 5; i < (nullTerminatorIndex - 1); i++) {
        argument1[(i - 5)] = received[i];
        lasti = (i - 5);
      }

      argument1[(lasti + 1)] = '\0';
      lasti = 0;

      Firmata.sendString(argument1);
    }

    //If there is a comma present, then write chars before the comma
    //to 'argument1', and after the comma - to 'argument2'
    if (commaLocation != 0) {
      Firmata.sendString("77 passed");
      //let's write what is before the comma:
      for (int i = 5; i < commaLocation; i++) {
        argument1[i - 5] = received[i];
        lasti = (i - 5);
      }

      argument1[(lasti + 1)] = '\0';
      lasti = 0;

      //let's write what's after the comma;
      char argument2[5];
      for (int i = (commaLocation + 1); i < (nullTerminatorIndex - 1); i++) {
        argument2[(i - (commaLocation + 1))] = received[i];
        lasti = (i - (commaLocation + 1));
      }

      argument2[(lasti + 1)] = '\0';
      lasti = 0;

      Firmata.sendString(argument1);
      Firmata.sendString(argument2);
    }
  }
}

```
> 1 votes

# Answer
Here's a simplified version of your command parser using cstrings and pointers:

```
void parseArgs(char * rec){
  char cmd[32];
  char arg1[32]= {0};
  char arg2[32]= {0};
  char * ptr; // this is a re-usable workhorse pointer
  char * ptrDelim; // another workhorse to split arguments

  // first copy all of it to cmd
  strcpy(cmd, rec);
  // find end of command
  ptr = cmd;
  while( isalpha(ptr[0]) ) ptr++;
  ptr[0] = '\0'; // mark end of command string

  // find first arg
  ptr = strchr(rec, '(')+1; // set ptr to char to right of open paren
  strcpy(arg1, ptr); // copy stuff after open paren to arg1:
  ptr = strchr(arg1, ')');// find max extent of arg1
  if(ptrDelim=strchr(arg1, ',')){
    ptrDelim[0]='\0'; // end arg1's string at delim
    ptrDelim++; // move right one char
    strcpy(arg2, ptrDelim); // copy stuff after comma
    arg2[strlen(arg2)-1] = '\0'; // chop off ")"
  }else{
    ptr[0]='\0';
  }//end if comma?

 Serial.println("\nGiven:" + String(rec)+";");
 Serial.println("Command:" + String( cmd )+";");
 Serial.println("Arg1:" + String( arg1 )+";");
 Serial.println("Arg2:" + String( arg2 )+";");

}

```

Examples:

```
parseArgs("CMDn()");
parseArgs("CMDn(arg1)");
parseArgs("CMDn(arg1,arg2)");

```
> 1 votes

---
Tags: string, firmata
---


# Question
Title: Arduino - Function -> return Cstr instead of string
I have following function for my Arduino:

```
String readLine() {
  String received = "";
  char ch;
  while (myFile.available()) {
    ch = myFile.read();
    if (ch == '\n' or ch == '\r') {
      if (ch == '\r')
      {
        //get rid of the \n
        myFile.read();
      }
      return String(received);
    } else {
      received += ch;
    }
  }
  myFile.close();
  hasFile = false;
  return received;
}

```

This function is used to return a line from a text file on a SD card. Since I do have to do quite some things on the returned string, I would like to have it as cstr instead of string to increase performance. But I am not able to convert this function to one that returns a Cstr. I tried this but it does not work:

```
char* readLine() {
  char* received = "";
  char ch;
  while (myFile.available()) {
    ch = myFile.read();
    if (ch == '\n' or ch == '\r') {
      if (ch == '\r')
      {
        //get rid of the \n
        myFile.read();
      }
      return received;
    } else {
      received += ch;
    }
  }
  return received;
}

```

Currently I am converting it after the function returns it, by using `c_str()`. It works, but I dont like it and would like to return a Cstr in the first place.

How can this be done?

Thank you!

# Answer
> 2 votes
You cannot work with c-strings like with `Strings`. You need to use the standard c-string functions (like `sprintf()`, `strcpy()` and siblings) or directly access the `char` array.

This gives the following problems with your code:

* See this line:

```
  char* received = "";

```

Here you create a pointer to a constant empty string. But this will **NOT** create a buffer, where you can put data. If you want to define a buffer to put the data in, you need to define an array:

```
  char received[30] = "";

```

where `30` is the size of the array and thus the buffer has space for 29 characters (30 minus the one character, that is needed for the terminating null character). Now you could use a counter variable to save the current position in the buffer and set the array elements to the received character:

```
  int position = 0;
  ...
  received[position] = ch;
  position++;

```

Then, when you reached the end of the buffer or you received end of line, you would end the data in the buffer with the null character:

```
  if (ch == '\n' || ch == '\r' || position == 29) {
      if (ch == '\r')
      {
          //get rid of the \n
          myFile.read();
      }
      received[position] = '\0';

```
* Now you have the second problem: When defining a variable inside the function, it will become invalid, when you exit the function. You try to return a pointer to `char`, which will point to a non-valid memory location. Thus you cannot simply return an array, that was created inside the function (outside of dynamic allocation). Here commonly an external buffer is provided to the function by reference as a pointer. The function will then write into that buffer and does not need to return it.

```
  //defining the array outside of the function, for example at global scope
  #define BUFFER_SIZE  30
  char received[BUFFER_SIZE] = "";
  ...
  void readLine(char *buffer, int size) {
      ...
      // Here you can use buffer as a simple char array
      buffer[position] = ch;
  }

```

Here I also provide the size of the array as parameter, so that the function can make sure not to exceed that (because that will give you bad and difficult to troubleshoot problems). Then, when the function has run, the read data is now in the `received` character array. This way you don't need to use multiple buffers and also don't need to copy data between buffers.

# Answer
> 1 votes
One way is passing external buffer to readLine() to fill:

```
size_t readLine(char * buff, size_t maxChars) {
  size_t pos = 0; // current position in buffer
  while (file.myFileAvalable()) {
    buff[pos] = file.read();
    if (buff[pos] == '\n' || buff[pos] == '\r') {
      buff[pos] = '\0';   // terminate string
      break;              // end the loop
    }
    if (++pos == maxChars-1) { // don't forget about nul terminal character
      buff[pos] = '\0';
      break;              // end the loop
    }
  }
  return pos; // return number of read characters (0 nothing was read)
}

/// ...

char ssid[25] = {0}; // create buffer to store at most 24 characters + \0
char pass[25] = {0}; // it'll also fill buffers by zeroes

readLine(ssid, sizeof(ssid)-1);  // it'd be better to check how many characters was read
readLine(pass, sizeof(pass)-1);  // same here

WiFi.begin(ssid, pass);
/// ... But it looks much worst than String, however it's much more efficient, as using += for Strings is quite heap unfriendly

```

**Big NO-NO is doing something like:**

```
char* readLine() {
  char buff[50] = {0};
  // ... fill ...
  return buff;           // NO!!!! buffer doesn't exist after the return - you've got dangling pointer
}
// ...
char * ssid = readLine(); // dangling pointer after that...
char * pass = readLine(); // now the ssid location was overwritten for sure

```

**Another NO-NO:**

```
char* readLine() {
  static char buff[50] = {0}; // one buffer for all calls, it won't get destroyed after the end... but
  // ... fill ...
  return buff;           // ok, buffer exists after the return,...
}
// ...
char * ssid = readLine(); //
char * pass = readLine(); // but surprise surprise, ssid and pass points to the same buffer and therefore the same data...

```

---
Tags: string, functions, c-string
---


# Question
Title: Arduino : send data via satellite (or other solutions ? without GSM)
I'm a researcher and I'm looking to build a very tiny embedded system. I must to send data from the desert and above the ocean, to do that I think that my single option is to use satellite transmission (and not GSM).

Thus, I found Iridium Satellite (RockBLOCK) but my main issue is that their Arduino module is too big for my project (4cm of length and too heavy).

Do you know if there is other module to send data via satellite with Arduino ? If not, do you know other microcontroller which can do that ? (Using Arduino is not mandatory for me)

Thank you a lot, Sincerely.

# Answer
> 1 votes
My two cents: A possibility might be LoRaWAN on the 2.4GHz spectrum, for which there are also satellites in orbit.

The LoRaWAN ("Long Range Wide-Area-Network") protocol is based on a chirp-spread-spectrum (CSS) modulation and has a very high range.

I've used LoRaWAN before but not on 2.4GHz or with a satelitte, so I can't comment on the practical feasibility. However, there are some materials from The Things Conference (by The Things Network, a leading developer of LoRa network servers).

Also maybe other modules that can talk to the Iridium satellites suite you better. Sparkfun has a few

---
Tags: gsm, gps, arduino-micro, data
---


title: Drawing a line at a given angle

text:
# Question
Title: Drawing a line at a given angle
Im attempting a device that measures lean angle. I have an ESP8266 + MPU6050 + SSD1306 setup, and I've managed to build a shaky but somewhat functioning device.

What Id like to do is use the Adafruit\_SSD1306 library to call the `display.drawLine(x, y, x1, y1, color)` function and have the line drawn to the measured angle output of the MPU6050.

The screen I'm using is 128 X 64

The MPU6050 is initially laying flat at 180 degrees, but is set and displayed as 0 degrees of tilt. The line is drawn vertically on the screen and pivots around x1 and y1 at 64, 64 respectively in the middle at the bottom of the screen.

If the MPU6050 pivots left like in the picture, the angle measurement itself is roughly correct, but the line indicator is showing more like 30 degrees than 45, and gets worse the larger the angle value.

**My code:**

```
#include <Adafruit_MPU6050.h>
#include <Wire.h>
#include <Adafruit_SSD1306.h>
#include <Adafruit_Sensor.h>

const int MPU_addr=0x68;
int16_t axis_X,axis_Y,axis_Z;

Adafruit_MPU6050 mpu;
Adafruit_SSD1306 display = Adafruit_SSD1306(128, 64, &Wire);

int minVal=265;
int maxVal=402;

double x;
double y;
double z;
int tiltAngle;
double y2;

void setup(){
  Serial.begin(9600);
  Serial.println("MPU6050 OLED demo");

  if (!mpu.begin()) {
    Serial.println("Sensor init failed");
    while (1)
      yield();
  }
  Serial.println("Found a MPU-6050 sensor");

    // SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally
  if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Address 0x3C for 128x64
    Serial.println(F("SSD1306 allocation failed"));
    for (;;)
      ; // Don't proceed, loop forever
  }

  display.display();
  delay(500); // Pause for 2 seconds
  display.setTextSize(2);
  display.setTextColor(WHITE);
  display.setRotation(0);
}
void loop(){
  display.clearDisplay();
  display.setCursor(0, 0);

  Wire.beginTransmission(MPU_addr);
  Wire.write(0x3B);
  Wire.endTransmission(false);
  Wire.requestFrom(MPU_addr,14,true);
  axis_X=Wire.read()<<8|Wire.read();
  axis_Y=Wire.read()<<8|Wire.read();
  axis_Z=Wire.read()<<8|Wire.read();
    int xAng = map(axis_X,minVal,maxVal,-90,90);
    int yAng = map(axis_Y,minVal,maxVal,-90,90);
    int zAng = map(axis_Z,minVal,maxVal,-90,90);

     x= RAD_TO_DEG * (atan2(-yAng, -zAng)+PI);
     y= RAD_TO_DEG * (atan2(-xAng, -zAng)+PI);
     z= RAD_TO_DEG * (atan2(-yAng, -xAng)+PI);

     tiltAngle = (int) x - 180; // we want the tilt angle to be 0 degrees
     display.println(" ");
     display.println(" ");
     display.println(" ");

     // display only positive angle values for either direction of tilt
     if(tiltAngle > 0){ display.print(tiltAngle);}
     else if (tiltAngle < 0) { display.print(tiltAngle * -1);}
     else {display.print(tiltAngle);}

     display.drawLine(-tiltAngle + 64, 0,64,64,WHITE);
     display.display();
     delay(100);
}

```

Im aware that for my first y co-ordinate I will need to use some kind of formula to get the line to move down from 0 (the top of the screen) as the lean angle gets greater. I'm hoping someone could point me in the right direction for drawing the line at the angle given by the MPU6050.

I did consider using case statements for each angle value and drawing the line with fixed co-ordinates based on each angle value. But that seems too compute intensive and could take up too much of the DRAM. Is anyone aware of a simple formula I could use? Thanks for reading.

# Answer
Use trigonometry (`sin()` and `cos()`) functions to get the right x and y coordinates.

I would consider replacing your `drawLine()` command with something like this (untested) assuming the `tiltAngle` is in degrees from -90 to +90 (with 0 degrees is straight up) and you want to draw a line at this angle from the origin (63, 63) with a radius of 64.

```
float tiltAngleRad = tiltAngle * DEG_TO_RAD; // convert angle to radians
int xEnd = 63 + 64 * sin (tiltAngleRad); // Ending x-coordinate offset & radius
int yEnd = 63 - 64 * cos (tiltAngleRad); // Ending y-coordinate offset & radius
display.drawLine (63, 63, xEnd, yEnd);

```

You might have to experiment with the offset and radius but I believe this will get you close yo what you want.
> 1 votes

---
Tags: esp8266, mpu6050, tft, ssd1306
---


title: Building a VU meter

text:
# Question
Title: Building a VU meter
I am building a VU meter with two 5v neopixel rings, two potentiometers, a headphone jack and an Arduino nano. Will 5 volts 1 amp cut it, or do I need more power? FYI I'll be powering it via a DC jack once I get it working.

# Answer
Normally the maximum amount of current a typical LED can withstand is 20 mA. This means per color and per LED.

So if you have 60 LEDs, than you get 60 (leds) * 3 (R/G/B colors) * 20 mA = 3,600 mA. To give some headroom I would use a 4A or 5A adapter.

However, note that probably 5 mA or 10 mA per LED would be enough to be very good visible, unless you want it to be as bright as possible.
> 1 votes

---
Tags: arduino-nano
---


# Question
Title: Unable to make a really basic sketch work
I've been learning how to encapsulate my code within functions, and one of the examples I worked on is a simple INPUT\_PULLUP button. When I upload the sketch from the arduino website everything works, so I know it's not a hardware issue. However, with the code below the button will just not go LOW.

I just don't see what the issue is, and I'm feeling really hopeless that I can't even get the simple thing done. I would be grateful for any advice.

```
int button_pin = 2;
int button_state = 0;

void setup() {
  Serial.begin(9600);
  pinMode(button_pin, INPUT_PULLUP);
}

void loop() {
  Button();
}

void Button() {
  // Read button(s)
  button_state = digitalRead(button_pin);
  if (button_state = LOW) {
    Serial.println(button_state);
  };
};

```

# Answer
> 1 votes
```
#define button_pin 2  //defining button pin as pin 2
bool button_state = 0; //button state is either 0/1 so using bool
void Button();
void setup()
{
    Serial.begin(9600);
    pinMode(button_pin, INPUT_PULLUP); //Setting input as input pullup
}

void loop()
{
    Button();
}

void Button()
{

    button_state = digitalRead(button_pin); //Read button state
    if (button_state == LOW)
    {
        Serial.println(button_state); //print button state when it is low
    }
}

```

In your code, you have used `=` operator in place of `==` in the if loop. Just if you change it, it will start working also you can use my above code it is same as yours just I have made some minor changes such as using `bool` in place of int and use of `#define` in place of pin declaration where you used `int`

---
Tags: button, input, pull-up
---


# Question
Title: Why is my passive buzzer clicking instead of buzzing when set to HIGH?
everyone. I am working on learning Arduino from scratch and I am on the buzzer lesson. The tutorial I am following consists on writing a code to get an input from the user in the form of an integer number, and, if it is greater than 10 (or whatever threshold you set it to) it will buzz.

I wrote the code exactly as the tutorial said but the buzzer would not buzz, it would do a weird clicking sound instead. I searched for a reason everywhere and could not find an explanation. Most questions in forums were solved by changing the positive wire from the 5V to a regular pin on the board, and those problems were due to the fact that the people asking the questions were not aware that the buzzer was a passive one.

Anyway, I managed to get a buzz by switching from digital to analogWrite and typing a value less than 255. It seemed weird that 255 and HIGH would produce the click, but values less than 255 would buzz, so I tried several analogWrite values:

* At 255 the buzzer does the weird clicking.
* At 254 the buzzer does a very faint buzz.

The buzzing got louder as I wrote lower numbers until it got stable at around 250, and then got less loud as I decreased the number.

Does anyone know why that is? Is the voltage too much for the buzzer at 255/HIGH? I tried a resistor but still got nothing but clicking with the program set to 255/HIGH.

This is mostly out of curiosity, but I'd still appreciate it if you could answer it.

Here is the code ("Numero" means "number" and "Dame un número" means "Give me a number":

```
int Numero;

int buzz=10;

int DLY=2000;

String msg="Dame un numero.";

void setup() {

Serial.begin(9600);
pinMode(buzz,OUTPUT);

}

void loop() {

Serial.println(msg);
while (Serial.available()==0){

}

Numero=Serial.parseInt();

if (Numero>25){

  Serial.println(Numero);

  analogWrite(buzz,10);

  delay(DLY);

  digitalWrite(buzz,LOW);

}

}

```

# Answer
> those problems were due to the fact that the people asking the questions were not aware that the buzzer was a passive one.

You seem to know, that you have a passive buzzer, but you don't know, what that means for you.

A buzzer consists mostly of a piezo element, which vibrates and thus makes a sound, if you provide it with an alternating voltage. Here we have 2 types of buzzers:

* The ones, that generate the alternating voltage themselves, thus only demanding a simple constant voltage from you to operate (these are the active buzzers)
* and the ones, that only have the piezo and thus demand to be provided with an alternating voltage by you (these are the passive buzzers).

You have the second type, a passive buzzer. The following is happening:

`digitalWrite(pin, HIGH)` will only set the pin to HIGH. On the transition from LOW to HIGH, you get a click, because the piezo in the buzzer is reacting to that change. `analogWrite()` on the other hand generates a PWM signal, which is an alternating voltage (alternating between LOW and HIGH).

When changing the number for `analogWrite()`, you are not changing the frequency, but only the duty cycle (the ratio of HIGH and LOW times in one period of the signal).

* `analogWrite(pin, 255)` means 100% duty cycle and thus a constant HIGH signal. Actually it is equivalent to `digitalWrite(pin, HIGH)`, because `analogWrite()` is doing exactly that, if you provide 255 (similarily it uses `digitalWrite(pin, LOW)`, if you provide 0). Thus you again hear the same click.
* As the piezo in the buzzer needs to oscillate to make a sound, you need to give him time for getting back to the LOW state. With the analog value 254 the LOW time of the signal is rather small, so that the piezo cannot reach its complete LOW state again. The oscillation amplitude is rather small that way. Thus you only hear a very faint buzz.
* With `analogWrite(pin, 250)` you reached the maximum, because now the piezo has enough time to get to its LOW state again. The amplitude is at its maximum here, thus it is the loudest value.
* When going lower than 250 towards zero, you are also reducing the amount of energy, that you give to the buzzer, thus the volume will reduce (though this is certainly not a linear process and depends also on the characteristics of the buzzer).

---

Just as Juraj already wrote in the comments, a passive buzzer can be interfaced with the `tone()` function. It will generate the alternating voltage for you and you can even set the frequency to your liking, so that you get tones with different pitches. There are tons of tutorials about the `tone()` function on the web.
> 2 votes

# Answer
A passive Piezo buzzer needs excitation to make sound, from your code you have a delay time of 2000 ms. 2000ms means a frequency of 0.5 Hz thats not enough.for my YL-44 Passive buzzer even the smallest possible number allowed by the arduino delay(ms) function wich is 1 ms isn't enough to hear a clear sound. A frequency of 2000 Khz was good with delayMicroseconds(us).

```
double outPin = outPin;
double freq_Hz = freq_Hz;
double period_s = 1 / m_freq_Hz;
double period_ms = m_period_s * 1000;
double period_us = m_period_ms * 1000;
void loop() {
 digitalWrite(m_outPin, HIGH);
 delayMicroseconds(period_us / 2);

 digitalWrite(m_outPin, LOW);
 delayMicroseconds(period_us / 2);
}

```
> 1 votes

# Answer
As chrisl explained, a passive buzzer needs a switched signal of the desired frequency in order to produce a tone of a specific pitch. It's going to produce the best/loudest output with a square wave (50% duty cycle.)

The analogWrite function outputs a PWM (pulse-width modulation) signal. That is a signal of a fixed frequency but varying duty cycle (The ratio of on time to off time.) At 50% (value 128) you should be able to get a decent tone out of it. (It looks like the PWM frequency varies by **Arduino model**: )

If you want to produce tones of varying frequncies, use the Arudino library's `tone()` function, documented here: https://www.arduino.cc/reference/en/language/functions/advanced-io/tone/

With the `tone()` function you provide the pin number and the desired frequency, and it does the rest. As mentioned in the docs, the tone function interferes with PWM output on boards other than Mega.

You could also get a tone with code like this:

```
bool state = HIGH;
int buzz=10;
unsigned long time = 0;

void setup() {
    pinMode(buzz,OUTPUT);
}

void loop() {
   if (millis() > time) {
      state = state == HIGH ? LOW: HIGH;
      time = millis() + 2;
      digitalWrite(buzz, state);
   }
}

```

If you loop does nothing else, that should give you a tone of roughly middle C. (250 hz, if my math is correct.)
> 0 votes

---
Tags: arduino-uno, voltage, buzzer
---