# Question
Title: Unable to use rising edge interrupt for external clock Arduino 2650
I'm messing about with an Arduino Mega2560r3 and failing to get timer 4 to trigger on the rising edge of an external clock. It only ever triggers on the falling edge.

I've tried

```
     TCCR4B = (1 << CS42) | (1 << CS41) | (1 << CS40);

```

and

```
     TCCR4B = (1 << CS42) | (1 << CS41);

```

... one of which should do the trick, but now I've pulled all my hair out and I'm turning to the wider community to see what I'm not seeing!

```
void setup() {
  DDRE = (1 << PE5);   //Dig pin 3 as output

  noInterrupts();
// Configure Timer 4 (only ICP4 (pin 49) and ICP5 (pin 48) are connected with Arduino MEGA2560 r3)
  TCCR4A = 0;
  TCCR4B = 0;
  TCCR4B = (1 << CS42) | (1 << CS41) | (1 << CS40);    // CTC mode does not reset when using force
  TIMSK4 = (1 << ICIE4);    // enable capture interrupt
  interrupts();
}

ISR(TIMER4_CAPT_vect)
{
  PORTE ^= (1 << PE5);  // Toggle PE5
}

```

Scope output below - blue is external clock (yes I know it's a sine wave!) and magenta is pin 3 output

# Answer
You seem to be mixing up two very different things.

1. You can use an external signal to drive the timer. That is, the timer will “tick” on the edges of that signal. In this mode, the timer behavior could be more accurately described as being a “counter”, since it is counting the external signal's edges. The external signal has to be fed to pin Tn (for timer *n*). Only the pins T0 (38) and T5 (47) are routed out on the Arduino Mega2560.
2. You can use a timer to timestamp the edges of an external signal. This is called “input capture”. When an edge is detected, the current value of the counter register is immediately copied to the input capture register ICRn, and an interrupt can be delivered. The external signal has to be fed to pin ICPn (ICP4 = 49, ICP5 = 48).

If you want to use input capture, you most likely want to clock the timer from the system clock, maybe through a prescaler. And you want to read the ICRn register within the ISR. The edge that triggers the capture is selected via the bit ICESn (Input Capture Edge Select) of the control register TCCRnB.
> 1 votes

---
Tags: arduino-mega, port-mapping
---


title: Can't get 1 second on a ATMega168 timer

text:
# Question
Title: Can't get 1 second on a ATMega168 timer
```
  TCCR1A = 0;
  TCCR1B = 0;
  OCR1B =  0xFF00;
  TCCR1A = (1<<WGM10) ;
  TCCR1B = (1<<CS12) | (1<<CS10);; //set the pre-scalar as 1024
  TIMSK1 = (1 << OCIE1A);

```

This doesn't produce a 1 second timer, it seems to produce a 0.5 second timer? I've calculated it based on the fact that I'm using the internal 8MHz internal clock on the chip.

Where am I going wrong?

EDIT: OK, I truly don't understand anything about timers, this is the first time I've ever tried one. I tried to figure it out using this tutorial: https://exploreembedded.com/wiki/AVR\_Timer\_programming All the examples are related to 16MHz, and the calculations are confusing to me because of the switch between formats which I don't know. After a lot of googling I figure out what I should be pushing into the calculator is ((8000000/1024)\*1)-1) = 7811.5 (Although what I do with this number is a mystery) I think I'm supposed to subtract this from 65536 or perhaps some other randomly generated number. You then take the result of this and turn it into the hexadecimal equivalent of a boy band name, like E17 use lots of arrows to point away from things that look like the names of radio stations, WGM10 (bringing you all the hits of the 80's and 90's)

I apologize for the sarcasm, I couldn't help myself. What I really need to know is:

1. How do you actually calculate a 1-second delay one timer 1 when you are using the 8MHz internal clock of the ATMega168PA ? What are the numbers to type into a calculator?
2. Which switches should I be setting? I thought these were the correct ones.
3. What does OCIE1A stand for, can't find it in the documentation or the tutorial, only in the example code?

I should probably also add all I am doing is incrementing a count and displaying the count in my loop.

```
ISR (TIMER1_COMPA_vect)
{
  count++;
}

```

# Answer
> 2 votes
In normal mode, the timer counts from 0 to 65535 (0xffff), and then rolls over back to zero. With a prescaler set to 1024, the period is then 1024 × 65536 = 67108864 CPU cycles.

If you want to control the timer's period, you should not use normal mode, but rather CTC mode (for “clear timer on compare match”). In this mode, it counts from 0 to the value stored in OCR1A, and then starts back at zero. With the same prescaler, the period is then 1024 × (OCR1A + 1) CPU cycles.

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


# Question
Title: Procedure for changing frequency of Nano or similar
I need to get interrupts at one of three specific rates: 1920, 2000, and 2400 per sec, at a fairly high precision (~10 ppm). I've asked about this on Electronics but I think here might be more appropriate.

I can't use the standard 16MHz with internal timers, since 16MHz / 2400 (for example) gives 66666.666... counts.

I would use an external standard, but I don't seem to be able to find one that fits the need. Something small and precise at 48KHz / 96KHz etc would be fine.

Alternatively, I could swap the crystal / resonator for one running at 18.432MHz, which divides evenly by those freqs and shouldn't tax a 328p. Can I even do that on a Nano, or some clone / comparable, with the required 10ppm?

-- extra removed --

# Answer
You could use an internal timer.

You are using interrupts, and you are probably aware that interrupt handling inevitably incurs some jitter. Thus, if you do not mind an extra single CPU cycle of jitter, you could reconfigure the timer on each interrupt in order to control the *average* interrupt period.

Here is how I would do it, with Timer 1 running in normal mode (CTC mode would require an extra operation):

```
// Interrupt period in units of 1/2^16 CPU cycles.
// For 2.4 kHz, that is 16000/2.4*65536 = 436906666.666...
uint32_t interrupt_period = 436906667;

ISR(TIMER1_COMPA_vect) {
    // Update the timer for the next interrupt.
    static uint32_t accumulator;
    accumulator += interrupt_period;
    OCR1A = accumulator >> 16;

    // The periodic task goes here...
}

void setup() {
    // Configure Timer 1.
    TCCR1A = 0;            // normal mode
    TCCR1B = _BV(CS10);    // clock @ F_CPU
    TIMSK1 = _BV(OCIE1A);  // enable COMPA interrupt
}

void loop(){}

```

Here, `accumulator` is a 32-bit extension of the timer's output compare register. The upper 16 bits are copied into the actual timer register, whereas the lower 16 bits ensure that the accumulated error never exceeds one cycle.

This way of updating the timer should only take about 2 µs per interrupt. It is a constant time operation, so it doesn't add extra jitter to your task, other than the single cycle of jitter induced by rounding to the next edge of the CPU clock.

There are a couple of caveats though:

1. This can only work on an Arduino clocked off a crystal (e.g., a Micro). Those clocked off a ceramic resonator (Uno...) would be too unstable in frequency to meet your 10 ppm requirement.
2. Even though a crystal is more than stable enough to meet your requirement, it is unlikely to be accurate enough. You will then need to calibrate it, e.g. by outputting a PWM signal (`analogWrite()`) into a frequency meter. Then adjust the variable `interrupt_period` according to the measured clock frequency.

---

**Edit**: I added the timer configuration to the code, and here comes an explanation of how this code works.

Think of the timer as a digital alarm clock. It measures time in units of CPU cycles instead of hours and minutes. It rolls over every 216 cycles instead of every 1440 minutes. But it is otherwise a regular alarm clock. It has two alarms called “COMPA” and “COMPB”, but you only need one. In order to perform a periodic task, you turn the alarm on and, every time it rings, you advance the alarm time by the required period. That is, you set:

new alarm time = previous alarm time + task period

Note that the addition has to be computed modulo the roll-over period of your clock : 1440 minutes for a regular alarm clock, 216 cycles for the timer. Thankfully, the arithmetics on unsigned numbers do this automatically.

Now, lets say the task period is 43 minutes and 35 seconds, but the alarm can only be set with a resolution of one minute. What you can do is compute the “ideal” alarm time on paper (this is the `accumulator` variable), and truncate it to the resolution of the clock when setting the alarm. If you start at 00:00:00, you will compute the next ideal time to be 00:43:35 and set the alarm to 00:43. When it rings, you add the period to the previously computed time, you get 01:27:10, and you set the alarm to 01:27. Etc. Here is the list of the alarm times as computed and as actually set on the clock:

```
computed  set
───────────────
00:00:00  00:00
00:43:35  00:43
01:27:10  01:27
02:10:45  02:10
...

```

Note that, even though the limited resolution of the alarm setting creates some jitter, the *average* task period is still exactly 43 minutes and 35 seconds.

The code I wrote above does exactly the same. The “ideal” alarm time is computed as a fractional number of CPU cycles, written down in binary fixed point, with 16-bits on each side of the radix point. In hex, it is 1A0A.AAAB CPU cycles. The computed alarm times are multiples of this period, whereas the times actually written to OCR1A are the same truncated to an integer:

```
computed   set
───────────────
1A0A.AAAB  1A0A
3415.5556  3415
4E20.0001  4E20
682A.AAAC  682A
...

```
> 3 votes

---
Tags: arduino-nano, atmega328, frequency
---


# Question
Title: how can I delete contents of an SD card in arduino?
I have a datafile, datalog.txt I can open, read and write cool. What is the best way to delete all the file contents? Should I try rewriting the SD card file with NULL data? I have been reading the "SD.h" header file. I see a flush() and truncate() function should I use one of these?

or maybe I should just close and reopen the file, and overwrite the data. But I'm concerned that this might lead to some miss representations if the old data is not completely removed.

I am using a teensy 4.1 with built\_in SD card.

# Answer
To remove a file use `SD.remove("datalog.txt");`

SD library's `FILE_WRITE` is `O_READ | O_WRITE | O_CREAT | O_APPEND` so it would append at the end of the existing file.

~~to start with an empty file: File file = FS.open("datalog.txt", O\_READ | O\_WRITE | O\_CREAT);~~

EDIT: opening the file with O\_READ | O\_WRITE | O\_CREAT doesn't clear the content of the file, only starts to overwrite it from the beginning.
> 3 votes

---
Tags: sd-card, teensy, datalogging
---


# Question
Title: SPI Digital Potentiometer not working on ESP32
I have an MCP4151 digital potentiometer chip. I have managed to get it to work using and Arduino Uno using the code below:

```
#include <SPI.h>

byte address = 0x00;
int CS= 5;

void setup()
{
  pinMode (CS, OUTPUT);
  SPI.begin();
}

void loop()
{
  for (int i = 0; i <= 128; i++)
  {
    digitalPotWrite(i);
    delay(10);
  }
  delay(500);
  for (int i = 128; i >= 0; i--)
  {
    digitalPotWrite(i);
    delay(10);
  }
}

int digitalPotWrite(int value)
{
  digitalWrite(CS, LOW);
  SPI.transfer(address);
  SPI.transfer(value);
  digitalWrite(CS, HIGH);
}

```

But when I try to get it to work using an ESP32 programmed using Arduino language it doesn't. I have connected like that

* SCK -\> 18
* MOSI -\> 23
* SS -\> 5

I also used the potentiometer inside like a voltage divider for test purposes. GND on one leg, 3.3v on the other and an LED on the wiper. Are there other settings that I have to implement in order the ESP32 SPI to work like an Arduino SPI? Did I miss something?

# Answer
> 2 votes
I managed to get it to work in a strange way. I opened the example included in the ESP32 SPI Library and copied some points from there.

I first initialise a pointer to the SPI class, then I call **`begin()`** at that pointer and inside the `digitalPotWrite` function I call **`beginTransaction(10000,MSBFIRST,SPI_MODE0)`** and end the transaction before `digitalPotWrite` finishes. Full code here:

```
#include <SPI.h>

static const int spiClk = 1000000;
byte address = 0x00;
SPIClass * hspi = NULL;

void setup()
{
  pinMode(15, OUTPUT);
  hspi = new SPIClass(HSPI);
  hspi->begin();
}

void loop()
{
  for (int i = 0; i <= 128; i++)
  {
    digitalPotWrite(i);
    delay(10);
  }
  delay(500);
  for (int i = 128; i >= 0; i--)
  {
    digitalPotWrite(i);
    delay(10);
  }
}

int digitalPotWrite(int value)
{
  hspi->beginTransaction(SPISettings(spiClk, MSBFIRST, SPI_MODE0));
  digitalWrite(15, LOW);
  hspi->transfer(address);
  hspi->transfer(value);
  digitalWrite(15, HIGH);
  hspi->endTransaction();
}

```

# Answer
> 0 votes
The ESP32 SPI library has defaults for the HSPI pins (14, 12, 13, 15). For VSPI pins, you must specify the pins in begin().

```
SPI.begin(18, 19, 23, 5);

```

# Answer
> -1 votes
Change the int for a void in the function... That's it. When you call that function is never going back, still waiting for a return.

```
int digitalPotWrite(int value)
{
  digitalWrite(CS, LOW);
  SPI.transfer(address);
  SPI.transfer(value);
  digitalWrite(CS, HIGH);
}

```

---
Tags: spi, esp32
---


# Question
Title: Synchronizing an internal frequency to an external one
In this question: Procedure for changing frequency of Nano or similar, @EdgarBonet gave a very nice method of generating timings that don't divide the system clock evenly. He also said that it would require tuning of the exact value by measuring the resulting frequency. I'd like to see if that tuning could be made automatic.

Suppose I had a precise external reference that could interrupt at a a sub-multiple of my frequency, say 60Hz. Is there a way to use that precision to, over time, bring my generated frequency into rough agreement with it?

In other words, for a frequency of 2400 Hz, and a reference of 60 Hz, I would adjust the period of the generator so that there are exactly 80 cycles of the 2400 Hz signal in each 60Hz period, even though there might be variations within the periods of those 80 cycles.

In effect this is a crude phase-locked loop multiplier. I know it can't be highly precise, but even close would be very valuable.

# Answer
You could use the input capture feature of Timer 1 to timestamp the edges of the reference input signal. This way you can compute the period of the input relative to the CPU clock, compare to the expected nominal period, and use this to adjust the interrupt period.

Combining this idea with the answer to the previous question gives:

```
const float input_frequency = 60;
const float interrupt_frequency = 2400;
const uint32_t nominal_input_period = round(F_CPU / input_frequency);
const uint32_t nominal_interrupt_period =
    round(F_CPU / interrupt_frequency) * 65536;

volatile uint32_t interrupt_period = nominal_interrupt_period;

uint16_t last_input_timestamp;

ISR(TIMER1_COMPA_vect) {
    // Update the timer for the next interrupt.
    static uint32_t accumulator;
    accumulator += interrupt_period;
    OCR1A = accumulator >> 16;

    // The periodic task goes here...
}

void setup() {
    // Configure Timer 1.
    TCCR1A = 0;            // normal mode
    TCCR1B = _BV(CS10);    // clock @ F_CPU
    TIMSK1 = _BV(OCIE1A);  // enable COMPA interrupt

    // Capture the first input edge.
    TIFR1 |= _BV(ICF1);  // clear interrupt flag
    loop_until_bit_is_set(TIFR1, ICF1);
    TIFR1 |= _BV(ICF1);  // clear interrupt flag again
    last_input_timestamp = ICR1;
}

void loop() {
    // Detect edges of the input signal.
    if (bit_is_set(TIFR1, ICF1)) {
        TIFR1 |= _BV(ICF1);  // clear interrupt flag

        // Update the interrupt period.
        uint16_t input_timestamp = ICR1;
        uint32_t input_period =
            (int16_t) (input_timestamp - last_input_timestamp
                - (uint16_t) nominal_input_period)
            + nominal_input_period;
        last_input_timestamp = input_timestamp;
        uint32_t new_interrupt_period = round(nominal_interrupt_period
                * ((float) input_period / nominal_input_period));
        noInterrupts();
        interrupt_period = new_interrupt_period;
        interrupts();
    }
}

```

Note that rounding the input period to an integer number of cycles comes with a rounding error of 1.25 ppm, well within your 10 ppm requirement. You can do better if needed, by using fixed point or floating point computations. Note also that the Timer rolls over multiple times per cycle of the input signal, which is dealt with by some arithmetic tricks, hence the casts to `uint16_t` and `int16_t` in the expression of `input_period`.

Strictly speaking, this is not a phase lock loop. It is more like a frequency lock loop. A real PLL would probably be a bit more involved. However, if you can tolerate your resulting frequency to be 10 ppm off, this approach is likely to be good enough.
> 1 votes

---
Tags: frequency, timing, arduino-mini
---


# Question
Title: 'for loop' seems to change the execution of pow()
The first time, pow() works. But inside of a 'for loop', or again afterwards, it doesn't behave !? (I'm using a Chinese Pro Mini with Arduino 1.8.16)

**EDIT** To clarify what I am asking, my question is: "Why does pow() only give the correct answer the first time?"

```
uint8_t places;
uint8_t temp8;
uint32_t n;

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

void loop() {
  places  = 5U;

  n = pow( 10, places);
  Serial.println(n);

  Serial.println("\nHERE'S THE SAME CODE INSIDE OF A 'FOR LOOP'\n");

  for (temp8 = 0; temp8 < places; temp8++)  {
    n = pow( 10, places);
    Serial.println(n);
  }

  Serial.println("\nNOW THE EXACT SAME CODE AS BEFORE GIVES A DIFFERENT RESULT\n");

  n = pow( 10, places);
  Serial.println(n);

  while(1){}
}

```

Here's what the serial monitor shows:

> 100000
>
> HERE'S THE SAME CODE INSIDE OF A 'FOR LOOP'
>
> 99999
>
> 99999
>
> 99999
>
> 99999
>
> 99999
>
> NOW THE EXACT SAME CODE AS BEFORE GIVES A DIFFERENT RESULT
>
> 99999

# Answer
This seems like a case of a confused compiler. More specifically, a confused optimizer.

On the first occurrence of `pow(10, places)`, the compiler noticed that `places` must be equal to 5, and so replaced the expression with its value. If you disassemble the compiled code, you will notice it calls

```
Serial.println(100000);

```

On the following occurrences, the compiler did not notice that `places` can not be anything other than 5, so it did not optimize-out the call to `pow()`, and got the result 99999.9765625. This is 3 ULPs less than the exact result, and is consistent with the accuracy you can expect from `pow()`. Converting to an integer implicitly rounds towards zero, hence the printed result: 99999.
> 3 votes

---
Tags: programming, arduino-pro-mini, code-review, loop, debugging
---


# Question
Title: Random "Compilation error: Error: 13 INTERNAL: exit status 1". No clue how to resolve or even what causes this error
I am a beginner with Arduino. I have a program that is intentionally simple.

The code refuses to compile, spitting out the error `Compilation error: Error: 13 INTERNAL: exit status 1`. I have gotten this type of error multiple times, and I have no idea what causes it, nor how to fix it.

My code is below, by the way.

```
void setup() {
  pinMode(9, OUTPUT);
  pinMode(10, OUTPUT);
  pinMode(11, OUTPUT);

  analogWrite(10, 10);
}

void loop() {
  digitalWrite(9, HIGH);
  digitalWrite(11, LOW);
  delay(250)
  digitalWrite(9, LOW);
  digitalWrite(11, HIGH);
}

```

# Answer
> 4 votes
The problem with that error message is that you are only reading the very last line. That line says "Oops, it didn't compile". The *actual* error message occurs *before* that. You need to read the entire message to know what is going on.

With your code, for example, you get the following output:

```
blah.ino: In function 'void loop()':
blah.ino:13:3: error: expected ';' before 'digitalWrite'
   digitalWrite(9, LOW);

```

That is your *actual* error. It's telling you that there's a semi-colon missing before the `digitalWrite` on line 13. There's nothing before the `digitalWrite` on line 13, but, if you look closely, you can see that line 12 has the semi-colon missing from the *end* of it.:

```
  delay(250)    <---- missing ;
  digitalWrite(9, LOW);

```

Thus it proves that it is always important to both read and (if you don't understand it) post **the entire error message not just the last line.**

---
Tags: compile, ide, analogwrite, digitalwrite, delay
---


# Question
Title: UART connected device communication only works one way
As the title implies, I have two Arduino devices (Uno and Mega) connected to each other over UART (the Mega is hardware UART, the Uno is software UART); I need the Mega to send a command to the Uno, the Uno to perform the command, then the Uno to report back to the Mega when it has finished the task. In this way, I want to implement asynchronous programming to control various light patterns as well as several motors (code not shown, it is unnecessary as the light control is in an isolated segment) without needing any firmware hacking. Sending commands from the Mega to the Uno works, but the reverse is not true, and even polling waitloops do not work. Note that if I send the "affirm" command repeatedly for infinity, but then I hang the code in the Uno and the Mega has no way to stop the barrage; it starts receiving likely random bytes. My code for the Mega is bulky and multi-file so I can't send the entire thing, but here is the control code:

```
lights::showRow(Serial1, 0, 0, 1, 1, 2, 2);
lights::waitUntilFinished(Serial1);
delay(500);
lights::clear(Serial1);
lights::waitUntilFinished(Serial1);
lights::chantO(Serial1);
lights::waitUntilFinished(Serial1);
lights::showRow(Serial1, 1, 0, 1, 1, 1, 2);
lights::waitUntilFinished(Serial1);
delay(500);
lights::clear(Serial1);
lights::waitUntilFinished(Serial1);
lights::chantX(Serial1);
lights::waitUntilFinished(Serial1);

```

These commands are implemented by:

```
namespace lights{
  boll ready = false;
  boll helloSent = false;
  void chantO(HardwareSerial coms){
    coms.write(1);
  }
  void chantX(HardwareSerial coms){
    coms.write(2);
  }
  void showRow(HardwareSerial coms, uint8_t x1, uint8_t y1, uint8_t x2, uint8_t y2, uint8_t x3, uint8_t y3){
    coms.write(3);
    coms.write(x1);
    coms.write(y1);
    coms.write(x2);
    coms.write(y2);
    coms.write(x3);
    coms.write(y3);
  }
  void clear(HardwareSerial coms){
    coms.write(4);
  }
  void waitUntilFinished(HardwareSerial coms){
    while (coms.available() == 0){};
    Serial.println("Done.");
    // It can't say anything but "affirmed", so we can save some code by not checking.
  }
}

```

The light code:

```
/* To make life easy, I will include a wiring map. Change as needed.
 *  Note that each ring is 24 pixels, and is labeled with the first-position to access it. The next one is obviously going to be the final point.
 ____     ____     ____
/48  \___/72  \   /192 \
\____/   \____/   \____/
 |___     |___     |___
/24  \   /96  \   /168 \
\____/   \____/   \____/
 |___     |___     |___
/0   \   /120 \___/144 \_____[END]
\____/   \____/   \____/
 |
 |
[CONTROLLER]

*/

#include <Adafruit_NeoPixel.h>
#include <SoftwareSerial.h>

#ifdef __AVR__
  #include <avr/power.h>
#endif
#define PIN       6
#define NUMPIXELS 216
#define DELAYVAL 500

Adafruit_NeoPixel pixels(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);
SoftwareSerial coms(9, 8);
int white = pixels.Color(255, 255, 255);
int red = pixels.Color(255, 0, 0);

int getPixel(uint8_t x, uint8_t y, uint8_t num){
  if (x == 0){
    return 48 - (y * 24) + num;
  }
  else if (x == 1){
    return 72 + (y * 24) + num;
  }
  else if (x == 2){
    return 192 - (y * 24) + num;
  }
}

void setRing(uint8_t x, uint8_t y, int color){
  for (int i = 0; i < 24; i ++){
    pixels.setPixelColor(getPixel(x, y, i), color);
  }
}

void setup(){
  pinMode(9, INPUT);
  pinMode(8, OUTPUT);
  coms.begin(9600);
  Serial.begin(9600);
  pixels.begin();
  pixels.setBrightness(205); // 0.8 * 256 = 204.8; thus this is 80% power. Only 6 can be lit up before you have issues.
}

void loop(){
  if (coms.available() > 0){
    uint8_t d = coms.read();
    Serial.println("He talkin' me");
    Serial.print("He say ");
    Serial.println(d);
    switch (d){
      case 1:
        for (uint8_t x = 0; x < 2; x ++){
          setRing(0, 1, white);
          setRing(1, 0, white);
          setRing(2, 1, white);
          setRing(1, 2, white);
          pixels.show();
          delay(500);
          pixels.clear();
          pixels.show();
          delay(500);
        }
        break;
      case 2:
        for (uint8_t x = 0; x < 2; x ++){
          setRing(0, 0, white);
          setRing(2, 2, white);
          setRing(2, 0, white);
          setRing(0, 2, white);
          setRing(1, 1, white);
          pixels.show();
          delay(500);
          pixels.clear();
          delay(500);
        }
        break;
      case 3:
        Serial.println("Hello, World");
        setRing(coms.read(), coms.read(), red);
        setRing(coms.read(), coms.read(), red);
        setRing(coms.read(), coms.read(), red);
        pixels.show();
        break;
      case 4:
        pixels.clear();
        pixels.show();
        break;
    }
    coms.write(1);
  }
}

```

# Answer
You are passing your `HardwareSerial` (`Serial1`) objects by value. That means that the object is copied, which is not good - it breaks the connection between the incoming data buffer and the interrupt that loads the RX ringbuffer.

Instead you must either pass *by reference* or *by pointer*. Personally I prefer pointers because it's what I am used to using, but you can use either.

For example:

```
  void waitUntilFinished(HardwareSerial &coms){ // <--- note the &
    while (coms.available() == 0){};
    Serial.println("Done.");
    // It can't say anything but "affirmed", so we can save some code by not checking.
  }

```

I would also consider changing this from a namespace to a class and passing the serial object you wish to use as a parameter to the constructor and storing the pointer to it in the class - then you only need ever pass it once and then use that pointer from then on. It would just simplify your code and clean things up somewhat.
> 0 votes

---
Tags: arduino-uno, arduino-mega, uart, remote-control
---


title: PID Arduino UNO

text:
# Question
Title: PID Arduino UNO
I want to implement a PD controller in Arduino using the PID library. Should I put Ki=0 and the rest of the constants as desired?

```
/*
BALL BALANCING USING A PID CONTROL with 6" resistive Touchscreen
*/
//////////////////////////////////////////////////////
///Libraries///
#include <PID_v1.h>
#include <stdint.h>
#include <TouchScreen.h>
#include <Servo.h>

//______________________________________________________________
// Definitions TOUCH PINS
#define YP A1 //brown
#define XM A2 //black
#define YM 7  //yellow
#define XP 6  //red

//______________________________________________________________
// For better pressure precision, we need to know the resistance
// between XP and XM Use any multimeter to read it
// For the 6" its 273 ohms across the X plate
#define Rx 273 //  Resistance in Ohm of Touchscreen measured in X-Direction
TouchScreen ts = TouchScreen(XP, YP, XM, YM, Rx);

// Coordinates Touchscreen
TSPoint p;
double xmin = 146.0;  //154
double xmax = 854.0;   //851
double xLength = 160.0; //Width of Touchscreen in mm at 6.0" 158

double ymin = 63.0;    //63.0
double ymax = 953.0;    //950.0
double yLength = 96.0; //Length of Touchscreen in mm at 6.0" 94

double convertX = xLength / (xmax - xmin);   // converts raw x values to mm. found through manual calibration  0.2295   0.225988
double convertY = yLength / (ymax - ymin);   // converts raw y values to mm. found through manual calibration  0.1082   0.107865

//______________________________________________________________
//Center-Position
double x0=74.35; double y0=42.71; //center  Correct: 0.5//-7     double x0=74.35; double y0=42.71
//______________________________________________________________

int state = 0;

// servos variables
Servo servoX; //X axis
Servo servoY; //Y axis

/////TIME SAMPLE
int Ts = 45;  //Delay between taking samples/measurements

unsigned long Stable=0;
unsigned int noTouchCount = 0; //variable for noTouch
//______________________________________________________________

double Kpx = 0.08;  //Kpx = 0.08; //Proportional (P) Get the ball to set point
double Kix = 0.02;  //Kix = 0.02 0.022 //Integral (I)
double Kdx = 0.035;  //Kdx = 0.035; //Derivative (D)  Stop the ball at set point

double Kpy =0.08;  //Kpy = 0.08
double Kiy =0.02; //Kiy = 0.02 0.022;
double Kdy =0.035;  //Kdy = 0.035;

//______________________________________________________________
//INIT PID
double SetpointX, InputX, OutputX; //for X
double SetpointY, InputY, OutputY; //for Y
PID myPIDX(&InputX, &OutputX, &SetpointX, Kpx, Kix, Kdx, REVERSE);
PID myPIDY(&InputY, &OutputY, &SetpointY, Kpy, Kiy, Kdy, REVERSE);
//______________________________________________________________

void setup(){
servoX.attach(9);
servoY.attach(10);

  OutputX=92;
  OutputY=100;
  servoX.write(OutputX); // Make Plate flat in X-Direction
  servoY.write(OutputY); // Make Plate flat in Y-Direction

  //INIT OF TOUSCHSCREEN
   p = ts.getPoint();

  //INIT SETPOINT, Center of Plate
  SetpointX = 0.0;
  SetpointY = 0.0;

  //Setup PID Controller
  myPIDX.SetMode(AUTOMATIC);
  myPIDX.SetOutputLimits(77, 107); // 83 107
  myPIDY.SetMode(AUTOMATIC);
  myPIDY.SetOutputLimits(85, 115); // -- 81 105

  // TIME SAMPLE
  myPIDX.SetSampleTime(Ts);
  myPIDY.SetSampleTime(Ts);
  delay(100);

  state=0;
  setDesiredPosition();

} // end of setup

void loop()
{
  while(Stable < 15)    //REGULATION LOOP
  {
   p = ts.getPoint();   //measure pressure on plate
   if (p.x > 0 ) //ball is on plate
   {
      servoX.attach(9); servoY.attach(10); //connect servos
      setDesiredPosition();
      noTouchCount = 0;
      p = ts.getPoint(); // measure actual position
      InputX = (p.x - xmin) * convertX;  // read and convert X coordinate
      InputY = (p.y - ymin) * convertY;  // read and convert Y coordinate
      if((InputX == SetpointX && InputY == SetpointY ))

          { Stable = Stable + 1;}

       myPIDX.Compute();  // action control X compute
       myPIDY.Compute();  // action control  Y compute
  }
   else //if there is no ball on plate
  {
    noTouchCount++; //increment no touch count
    if(noTouchCount == 150)
    {
     noTouchCount++;
     OutputX=92; OutputY=100;  //make plate flat
     servoX.write(OutputX); servoY.write(OutputY);
    }
    if(noTouchCount == 300) //if there is no ball on plate longer, detach servos
    { servoX.detach(); servoY.detach(); }
  }
  servoX.write(OutputX); servoY.write(OutputY);  //control

  } // END OF REGULATION LOOP

servoX.detach(); servoY.detach(); //detach servos

///STABILITY////
 while(Stable==15)    //if is stable
 { //still measure actual postiion
    setDesiredPosition();
    p = ts.getPoint();
    InputX = (p.x - xmin) * convertX;  // read and convert X coordinate
    InputY = (p.y - ymin) * convertY; // read and convert Y coordinate
    if(InputX < SetpointX || InputX > SetpointX || InputY > SetpointY || InputY < SetpointY  ) //if ball isnt close to setpoint
    {
      servoX.attach(9); //again attach servos
      servoY.attach(10);
      Stable=0; //change STABLE state
    }

  }//end of STABLE LOOP
}//loop end

//______________________________________________________________
//#### DESIRED POSITION ####
void setDesiredPosition(){
 switch(state){

// Start-Sequence
     case 0:  SetpointX = x0;
              SetpointY = y0;
              p = ts.getPoint();
              if (p.x > 0)
              {
                state = 1;
              } // if ball is on plate
              else if (p.x <= 0)
              {
                state = 0;
                setDesiredPosition();
               } // if no ball is on plate
              break;

// Center-Position
      case 1:  SetpointX = x0;
               SetpointY = y0;
               state = 1;
               break;

    default : state = 0; break;

 }  //end of switch state
}   //end of setDesiredPosition()

//______________________________________________________________

```

# Answer
Yes, you can use the PID library with `Ki=0;` to get a PD controller.
> 1 votes

---
Tags: arduino-uno, pid
---


# Question
Title: How to smooth transition to another color NEOPIXELS
I am working on a led strip project and was looking for ways to smooth transition from color to another. Problem is my current method is not so good.

```
#include <Adafruit_NeoPixel.h>

#define LED_PIN     25
#define LED_COUNT  60
#define BRIGHTNESS 50

Adafruit_NeoPixel strip(LED_COUNT, LED_PIN, NEO_GRBW + NEO_KHZ800);

bool isFading = false;
unsigned long startTime;
uint32_t fadeDuration = 1000;          //fade for 3seconds
uint32_t startingColor = 0x00ffff00;      // W = 0x00 R=0xFF G=0xFF B=0x00  yellow
uint32_t targetColor = 0x008f00ff;        // W = 0x00 R=0x8F G=0x00 B=0xff  violet

void setup() {

  pinMode(25, OUTPUT);
  digitalWrite(25, LOW);

    Serial.begin(9600);
  while (!Serial);
  Serial.println("Starting");

  strip.begin();
  strip.show();
  strip.setBrightness(BRIGHTNESS);

  for (int i = 0; i < strip.numPixels(); i++)
    strip.setPixelColor(i, startingColor);
  strip.show();

  delay(5000); // wait 5 seconds before fading

  isFading = true;
  startTime = millis();
}

void loop() {

  if (isFading) { //Fade from yellow to violet in 3 seconds
    for (int i = 0; i < strip.numPixels(); i++)
      strip.setPixelColor(i, getFadeColor(startingColor, targetColor, startTime, startTime + fadeDuration));
    strip.show();
  }

  if ( millis() >= startTime + fadeDuration){; // i intentionally did not include an overflow check to keep it simple
  Serial.println("Fade ended");
  isFading = false;
  }
}

uint32_t getFadeColor(uint32_t startColor, uint32_t endColor, unsigned long timeStart, unsigned long timeEnd) {

  uint8_t startWhite  = (startColor >> 24) & 0xff;
  uint8_t startRed    = (startColor >> 16) & 0xff;
  uint8_t startGreen  = (startColor >> 8 ) & 0xff;
  uint8_t startBlue    =  startColor & 0xff;

  uint8_t endWhite    = (endColor >> 24) & 0xff;
  uint8_t endRed      = (endColor >> 16) & 0xff;
  uint8_t endGreen    = (endColor >> 8) & 0xff;
  uint8_t endBlue      = endColor & 0xff;

  unsigned long timeNow = millis();

  uint8_t mapTime = map(timeNow, timeStart, timeEnd, 0, 255);
  uint8_t white   = map(mapTime, 0, 255, startWhite, endWhite);
  uint8_t red     = map(mapTime, 0, 255, startRed, endRed);
  uint8_t green   = map(mapTime, 0, 255, startGreen, endGreen);
  uint8_t blue    = map(mapTime, 0, 255, startBlue, endBlue);

  Serial.print("Time: \t");
  Serial.print(mapTime);
  Serial.print('\t');
  Serial.print("Color now: \t");
  Serial.println(strip.Color(  red,   green,   blue, white),HEX);

  return strip.Color(  red,   green,   blue, white);

}

```

The problem im having with this code is visually it would seem that it goes from

Yellow -\> White -\> violet

and it does not look like a proper transition. I have tried with other colors, and it always seems to pass throught the white color

Are there color theories i can apply for the transition? if you can show me an example sketches on how to do the transition that would also be great.

# Answer
> something that will go through the color wheel until the destination color

For that the `FastLED` library has the function `ColorHSV()`, which can be used to define colors using the HSV color space. It stands for **H**ue, **S**aturation and **V**alue (or brightness). Hue is the value representing the position in the color wheel, so that is what you want to change.

Instead of

```
strip.Color(  red,   green,   blue, white);

```

use

```
strip.ColorHSV( hue, saturation, brightness );

```

and change `hue` over time with the algorithm, that you already programmed. When `saturation` and `brightness` stay the same the LEDs will cycle through the color wheel.

Note: The library provides the way from HSV to RGB color (with the above function), but it does not provide a way back. For getting back HSV from an RGB color you would need to write your own conversion function and I don't know how to do that. Though at the current state you don't need it.
> 2 votes

---
Tags: neopixel
---


# Question
Title: Optimised random alphanumeric string generator
I'm trying to build arduino nonce generator, but the only thing I found is this question on arduino forum but I can't find out how to make it work for me. I checked and Serial.available() is always 0 for me and if I delete the If I still get nothing

**My code:**

```
void setup() {
    Serial.begin(9600);
    randomSeed(analogRead(0));
}

void loop() {
    byte randomValue;
    char temp[5];
    char letter;
    char msg[50];     // Keep in mind SRAM limits
    int numBytes = 0;
    int i;
    int charsRead;

    if(Serial.available() == 0)
    {
        charsRead = Serial.readBytesUntil('\n', temp, sizeof(temp) - 1); // Look for newline or max of 4 chars
        temp[charsRead] = '\0';   // Now it's a string
        numBytes = atoi(temp);
        if(numBytes > 0)
        {
            memset(msg, 0, sizeof(msg));
            for(i = 0; i < numBytes; i++) {
            randomValue = random(0, 36);
            msg[i] = randomValue + 'a';
            if(randomValue > 26) {
                msg[i] = (randomValue - 26) + '0';
            }
            }
            Serial.println("Here is your random string: ");
            Serial.println(msg);
            Serial.print("I received: ");
            Serial.println(numBytes);
            delay(1000);
        }
    }
}

```

How do I make it work?

Do you have some working random alphanumeric string generator that you are using?

# Answer
> 2 votes
Your problem seems to be related to how you get the actual length you want to generate. There are other ways you could do that. Since your max seems to be 4 characters, you could possibly enter "9999" which would overflow the 50 bytes `temp` variable.

You could simply read until `\n` and then `atoi`. Then cap at 50.

As a side note, here's a function I've used in the past to generate (pseudo)random strings for network requests (e.g. `state` or `nonce` parameters)

```
#define MAX_UID 8 /* Change to whatever length you need */

const char * generateUID(){
  /* Change to allowable characters */
  const char possible[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
  static char uid[MAX_UID + 1];
  for(int p = 0, i = 0; i < MAX_UID; i++){
    int r = random(0, strlen(possible));
    uid[p++] = possible[r];
  }
  uid[MAX_UID] = '\0';
  return uid;
}

```

---
Tags: serial, programming, string, code-optimization
---


# Question
Title: Arduino outputs garbage values on serial monitor with ESP8266
I have connected my Arduino with an ESP8266.

When I check the ESP8266, by manually entering commands at serial monitor, I get correct results.

However, when I run this program

```
#include<SoftwareSerial.h>

SoftwareSerial esp8266(2,3);

void setup() {
  Serial.setTimeout(5000);
  Serial.begin(115200);
  esp8266.begin(115200);
  delay(1000);
}

void loop() {
  delay(2000);
  String command="AT";

  esp8266.println(command);
  if(esp8266.available())
  {
    while(esp8266.available())
    {
      char c=esp8266.read();
      Serial.write(c);
    }
  }
}

```

I get garbage values where sometimes it has an `OK` in between the output:

> " Received: "ÁT OK " Received: "AÔ ÏË " Received: "AÔ OK " Received: "ÁT ÏË " Received: "ÁT OË " Received: "ÁÔ OK " Received: "Á¬ OK " Received: "ÁT OË "

Could someone help me?

# Answer
> 11 votes
As noted by Matt, the baud rate for the ESP8266 can vary depending on the firmware version/manufacturer. 9600 and 115200 are the most common. If you can connect using a serial terminal program (like CoolTerm) you can then test the baudrate.

It sounds like the ESP8266 is set to 115200, but in my experience (and others') SoftwareSerial isn't capable of 115200 baud rate (despite "allowing" this as a setting). Some reports suggest as high as 57600 is workable, though in my experience 9600 is best for reliability. But you can reset this and see what the max reliable value is for you in your configuration.

How to change the baud rate on the ESP8266 will depend on the firmware version. I've had success with `AT+IPR=9600`. You only need to run this command once (it's a persistent setting). I'd suggest, based on your description, that this is the most likely culprit that's causing the intermittent "garbage" output you describe.

# Answer
> 9 votes
Using 115200 has too many instructions for the Arduino Uno to reliably decode characters and that's where the garbage is coming from.

The ESP8266 default baud is 115200, so you need to connect at the default rate and issue an AT command to reduce the baud rate to 9600.

Each time you reset, the ESP8266 goes back to the default baud rate.

Here's an example script that connects at the default baud rate and then reduces it to 9600. You'll connect the Serial Monitor at 9600. At the lower baud rate, I'm not getting any garbage characters.

```
#include <SoftwareSerial.h>
SoftwareSerial ESPserial(2, 3); // RX | TX

void setup()
{
  Serial.begin(9600);
  ESPserial.begin(115200);
  ESPserial.println("AT+IPR=9600");
  delay(1000);
  ESPserial.end();
  // Start the software serial for communication with the ESP8266
  ESPserial.begin(9600);

  Serial.println("Ready");
  ESPserial.println("AT+GMR");
}

void loop()
{
    // listen for communication from the ESP8266 and then write it to the serial monitor
    if ( ESPserial.available() )   {  Serial.write( ESPserial.read() );  }

    // listen for user input and send it to the ESP8266
    if ( Serial.available() )       {  ESPserial.write( Serial.read() );  }
}

```

An odd thing that happened to me is that I tried to use a baud rate of 4800 and I bricked one ESP8266 module. I don't know if that was a glitch or just a coincidence.

# Answer
> 6 votes
Using AT+IPR is a very dangerous command. Many ESP8266 will get bricked after the command. The only way to do it is by flashing your ESP to a 9600 baudrate.

I just had to do this myself with a friend today after using the AT+IPR command and loads of websites tell you to never use the command.

# Answer
> 1 votes
Finally, solved garbage symbols in serial monitor by lowering the ESP's baud rate from 115200 to 9600 with the following command: `AT+UART_DEF=9600,8,1,0,0` The root cause of the problem is speed limitations of the SoftwareSerial. On hardware Serial connection, it should work ok with speeds up to 115200.

There is my ESP AT+GMR info:

```
AT version:1.3.0.0(Jul 14 2016 18:54:01)
SDK version:2.0.0(5a875ba)
v1.0.0.3
Mar 13 2018 09:37:06

```

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


title: RP2040 RTC alarm or similar function

text:
# Question
Title: RP2040 RTC alarm or similar function
I have a rp2040 board using Earl E. Philhower core. I would like to use the rtc functions just like the one mentioned in the sdk. Especially the alarm function which is critical in my project.

Supposedly from what i know you have access to all the functions in the sdk on the arduino IDE but when i tried out the example in the sdk it would not compile saying that rtc functions are not declared

```
char datetime_buf[256];
char *datetime_str = &datetime_buf[0];

    datetime_t t = {
            .year  = 2020,
            .month = 06,
            .day   = 05,
            .dotw  = 5, // 0 is Sunday, so 5 is Friday
            .hour  = 15,
            .min   = 45,
            .sec   = 00
    };

void setup() {
    Serial.begin(9600);
    Serial.println("Hello RTC!");

    rtc_init();
    rtc_set_datetime(&t);
}

// the loop function runs over and over again forever
void loop() {
        rtc_get_datetime(&t);

        Serial.println(datetime_str);
        sleep_ms(100);             // wait for a second
}

```

Earl E. Philhower comes with a Time sketch example but problem is i could not find a documentation if a alarm like function exist

```
/* Simple demonstration of setting and printing the current time */
/* The initial time will need to come from an RTC, NTP, or user */

/* Released to the public domain by Earle F. Philhower, III <earlephilhower@yahoo.com> */

#include <time.h>
#include <sys/time.h>

void setup() {
  Serial.begin(115200);
  delay(5000);
  struct timeval tv;

  tv.tv_sec = 1611198855; // Jan 21, 2021  3:14:15AM ...RPi Pico Release;
  tv.tv_usec = 0;
  settimeofday(&tv, nullptr);
}

void loop() {
  time_t now;
  char buff[80];

  time(&now);
  strftime(buff, sizeof(buff), "%c", localtime(&now));
  Serial.println(buff);
  delay(1000);
}

```

# Answer
You can try to use my RP2040\_RTC Library, especially this RP2040\_RTC\_Alarm example.

Both **ArduinoCore-mbed** and Earle Philhower **arduino-pico** cores are supported.
> 3 votes

---
Tags: arduino-nano-rp2040
---


# Question
Title: RP2040 example sketch for dual core queuing
I would like to use queuing because i think its best for my application. I have very limited experience in dual core programming all i want is to hopefully pass 32 bit numbers to the second core properly. queuing seems to be good because it makes sure that the second core who is receiving the data wont miss anything in the sequence if data comes in very fast and core 2 is not ready to process it.

But Im having trouble finding examples. I did find one but its for a runner queue, which i think is a bit different to what i want

Can anyone show me an example sketch? what i would really like to see is core 1 adding to the queue and core 2 retrieving and removing data from the queue

# Answer
After digging around i was able to use the queue\_t from the sdk. and here it is

```
queue_t queue;

typedef struct queueItem {
  uint32_t value;
} item;

const int QUEUE_LENGTH = 128;

void setup() { //CORE 1 setup

  Serial.begin(9600);
  while (!Serial);
  queue_init(&queue, sizeof(item), QUEUE_LENGTH); //initialize the queue

}

void loop() { //CORE 1 TIGHTLOOP

  queueItem temp;
  temp.value = random (1000);
  if (queue_try_add(&queue, &temp)) { //adding items to the queue
    Serial.print("ADDING:\t");
    Serial.println(temp.value);
  }

  else
    Serial.println("FIFO was full\n");
  delay(500);
}

void setup1() { // CORE2
}

void loop1() {  //CORE 2 TIGHTLOOP

  queueItem temp;
  while (queue_try_remove(&queue, &temp)) { //retrieving item from the queue and deleting it from the queue
    Serial.print("ITEM RETRIEVED:\t");
    Serial.println(temp.value);
  }

  delay(500);

}

```
> 2 votes

# Answer
This requires a thread-safe queue, where one thread writes to the queue, and another thread reads from the queue.

But I find that with a little care, you can just use a circular buffer where the consumer will increase the head, and the producer will increase the tail.

Something like this:

```
#define MAXSZ 80
static int buff[MAXSZ];
static int head=0;
static int tail=0;

bool full(void)  { return (tail+1)%MAXSZ == head; }
bool empty(void) { return head==tail; }
int  usage(void) { int num = tail-head; return num<0 ? num+MAXSZ : num; }

int produce(int val)
{
   if ( full() ) return -1;
   buff[tail] = val;
   tail = (tail+1)%MAXSZ;
   return 0; // signal success.
}

int consume(void)
{
   if ( empty() ) return -1;
   int val = buff[head];
   head = (head+1)%MAXSZ;
}

```

This will work as long as your compiler doesn't do crazy re-ordering of the operations, and as long as you only touch the head with the consumer, and only touch the tail with the producer. Also, the assignments of head/tail need to be atomic, not split up as: `tail++ ; tail = tail%MAXSZ;`

Come to think of it: if a small capacity suffices, like the 80 from the example code, I would use `int8_t` for head/tail, just in case writing an int to memory gets context-switched between writing the LSB and MSB parts. (I don't know RP2040 well enough to know if writing an int is atomic.)
> 1 votes

---
Tags: arduino-nano-rp2040
---


title: Arduino data-types

text:
# Question
Title: Arduino data-types
(Im new to the arduino side of stackexchange). Im working on a worksheet for to begin with arduino. I have prior experiences working with arduinos, but problem is new for my field of expertise. Any help will be well appreciated (need help pls uwu)

Problem statement:

I tried different methods to obtain those values, but all are to vain.

Methods that I tried so far:

* using limits.h, floats.h and inbuild variables of those library -- Problem: Im getting wrong minimum and maximum values for float and double:  Code:

```
#include <stdio.h>
#include <limits.h>
#include <float.h>
#include <math.h>

char fltmax[250];
char fltmin[250];
char dblmax[250];
char dblmin[250];

void sint() {
  Serial.print("Range of signed int: ");
  Serial.print(INT_MIN);
  Serial.print(" to ");
  Serial.print(INT_MAX);
  Serial.print(", which has a storage size of ");
  Serial.print(sizeof(int));
  Serial.println(" bytes");
}
void usint() {
  Serial.print("Range of unsigned int: 0 to ");
  Serial.print(UINT_MAX);
  Serial.print(", which has a storage size of ");
  Serial.print(sizeof(unsigned int));
  Serial.println(" bytes");
}
void schar() {
  Serial.print("Range of signed char: ");
  Serial.print(SCHAR_MIN);
  Serial.print(" to ");
  Serial.print(SCHAR_MAX);
  Serial.print(", which has a storage size of ");
  Serial.print(sizeof(signed char));
  Serial.println(" bytes");
}
void uschar() {
  Serial.print("Range of unsigned char: 0 to ");
  Serial.print(UCHAR_MAX);
  Serial.print(", which has a storage size of ");
  Serial.print(sizeof(unsigned char));
  Serial.println(" bytes");
}
void slong() {
  Serial.print("Range of signed long: ");
  Serial.print(LONG_MIN);
  Serial.print(" to ");
  Serial.print(LONG_MAX);
  Serial.print(", which has a storage size of ");
  Serial.print(sizeof(signed long));
  Serial.println(" bytes");
}
void uslong() {
  Serial.print("Range of unsigned long: 0 to ");
  Serial.print(ULONG_MAX);
  Serial.print(", which has a storage size of ");
  Serial.print(sizeof(unsigned long));
  Serial.println(" bytes");
}
void sshort() {
  Serial.print("Range of signed short: ");
  Serial.print(SHRT_MIN);
  Serial.print(" to ");
  Serial.print(SHRT_MAX);
  Serial.print(", which has a storage size of ");
  Serial.print(sizeof(signed short));
  Serial.println(" bytes");
}
void usshort() {
  Serial.print("Range of unsigned long: 0 to ");
  Serial.print(USHRT_MAX);
  Serial.print(", which has a storage size of ");
  Serial.print(sizeof(unsigned short));
  Serial.println(" bytes");
}
void flt() {
  Serial.print("Range of float: ");
  dtostrf(FLT_MIN, -1, 50, fltmin);
  Serial.print(fltmin);
  Serial.print(" to ");
  sprintf(fltmax,"%e", FLT_MAX);
  puts(fltmax);
  Serial.print(", which has a storage size of ");
  Serial.print(sizeof(float));
  Serial.println(" bytes");
}
void dbl() {
  Serial.print("Range of double: ");
  dtostrf(DBL_MIN, -1, 50, dblmin);
  Serial.print(dblmin);
  Serial.print(" to ");
  dtostrf(DBL_MAX, -1, 0, dblmax);
  Serial.print(dblmax);
  Serial.print(", which has a storage size of ");
  Serial.print(sizeof(double));
  Serial.println(" bytes");
}

void setup() {
  Serial.begin(115200);
  sint();
  usint();
  schar();
  uschar();
  slong();
  uslong();
  sshort();
  usshort();
  flt();
  dbl();
}

void loop() {
}

```

I tried combining both where the test code that I used before actual implementation:

```
#include <stdio.h>
#include <math.h>
#include <string.h>
#include <float.h>
#include <limits.h>

void setup () {
  char str[30];
  Serial.begin(115200);
  snprintf(str, 30, "Value of float max = %e", FLT_MAX);
  /*puts(str);*/
  Serial.print(str);
  return(0);
}
void loop(){

}

```

But `puts(str)` is not getting printed in the serial monitor. Then It clicked, that I have to use Serial.(code) for it to get printed in serial monitor, but it ended up in `Serial.puts(str)` code not found. Then I tried just `Serial.print(str)`, but it just outputs `Value of float max = ?` (Initially, before I wrote this problem here, it output `Va` only, which i have no idea how it changed, but its still wrong). What do I do now? also, Why cant I use puts to print in serial monitor?

The board im using for this is Arduino UNO (ATmega328P)

# Answer
There are two issues here.

One is that the Arduino core uses `Serial` to handle serial I/O, rather than the traditional libc interface (`printf()`, `puts()` and co.). The avr-libc does provide the traditional stdio functions, but these will not work unless you tell them where `stdout` is, which is a bit complex.

The take away is to just use the methods of `Serial` for accessing the serial port.

Then there is the question: why did it print “Value of float max = ?”. The reason is that the avr-libc does not provide by default support for formatting floating point numbers with `sprintf()`. That support is quite expensive in flash space, and it is omitted unless you link with a specific version of the avr-libc. The simple workarounds are:

* Use `Serial.print()` to both format and print floating point numbers, which is inconvenient for very small or very large numbers.
* Use `dtostre()` or `dtostrf()` to format them.

In your case, `dtostre()` is a better fit:

```
void setup() {
    char val[40];
    Serial.begin(9600);
    Serial.print("Range of float: ");
    dtostre(FLT_MIN, val, 5, 0);
    Serial.print(val);
    Serial.print(" to ");
    dtostre(FLT_MAX, val, 5, 0);
    Serial.print(val);
    Serial.println();
}

void loop(){}

```

prints:

```
Range of float: 1.17549e-38 to 3.40282e+38

```
> 4 votes

---
Tags: arduino-uno, atmega328, data-type
---


# Question
Title: fingerprint scanner and GSM module- how do i put a timer condition using if statements?
I am using a fingerprint sensor and GSM module on Arduino MEGA 2560. I want a fingerprint to be scanned every minute, if a minute elapses with no finger scanned, then the next code for the GSM to send an SMS must be executed

```
const unsigned long timeLimit = 60000;
unsigned long prevTime;
unsigned long currTime;

void setup() {
  prevTime = millis();
}

void loop() {
  unsigned long currTime = millis();
  getFingerprintID(); //fingerprint func
  if (currTime - prevTime <= timeLimit) {
    if (finger.fingerSearch() == FINGERPRINT_OK) { //if the fingerprint matches
      prevTime = currTime;
    }
  } else {
    Serial.print("MAXIMUM TIME OF ");
    Serial.print(currTime / 1000);
    Serial.print(" SECONDS HAS LAPSED\n");
  }
}

```

# Answer
i cleaned up your version. make sure to update the `prevTime` variable.

```
const unsigned long timeLimit = 60000;
unsigned long prevTime ;
unsigned long currTime;
unsigned long elapsedTime;
int id;
void setup() {
prevTime=millis();
}

void loop() {
  if (fingerprint()){
    currTime = millis();
    elapsedTime = currTime- prevTime;
    if (elapsedTime < 60*1000) {
      prevTime = currTime;
    } else {
       sendSms();
    }
  }
}

void sendSms() {
Serial.print("MAXIMUM TIME OF ");
Serial.print(currTime/1000);
Serial.print(" SECONDS HAS LAPSED\n");
}

bool fingerprint(){
  bool fingerPrintAccepted = false;
  if (finger.fingerSearch()==FINGERPRINT_OK){
    fingerPrintAccepted = true;
  }
  return fingerPrintAccepted;
}

```
> 1 votes

---
Tags: arduino-mega
---


title: Sparkfun OpenLog both lights flashing

text:
# Question
Title: Sparkfun OpenLog both lights flashing
I'm building a simple RS232 data logger with the Sparkfun OpenLog and a SEEED RS232-TTL adaptor. I'm powering it with a 9 volt battery and a 7805 voltage regulator.

It's dead simple. I built it on a breadboard first and determined that TX-TX and RX-RX connections are called for. I logged several files on the breadboard then soldered it all up. Now it's not working, sigh.

When I power it up both lights will flash rapidly for about a second and then it settles down to a steady on-off with both lights.

If I delete the config file a new one is created, which shows that it recognizes the card at least.

I've triple checked my wiring and confirmed I have no shorts, and that the voltage is good.

I'm attaching a photo as built. Hopefully it's obvious what's what. The purple trace is ground.

# Answer
> 1 votes
The problem with the circuit was a bad rs232-ttl converter. Not sure how that messed up the openlog, but replacing it fixed the problem.

In the photo above, D1 on the converter is an led which should be normally on.

# Answer
> 1 votes
If the OpenLog's RX pin is held low for too long at startup, it'll reset to 9600 baud to attempt to recover. A bad rs232-ttl converter could cause this, if the RX pin was being held low. If you need the OpenLog to ignore this, see the ignoreRX parameter in config.txt and the hookup guide.

---
Tags: datalogging, rs232
---


# Question
Title: sizeof tm struct (datetime) different on ESP32 vs linux64x
I am logging binary data to my SD. I log a datetime object of type 'tm', which is 36 bytes on ESP32. When I create a datetime of type 'tm' on linux it is 56 bytes.

ESP32 write tm to SD: \[tm datetime = 36 bytes\]

```
time_t t = std::time(nullptr);
tm datetime = *std::localtime(&t);
uint16_t t = file.write((const uint8_t *)&datetime, sizeof(datetime)); // ==36 bytes.

```

PC \[tm datetime = 56 bytes\] (compiled using g++ on linux 64)

```
tm datetime;
std::ifstream fileStream(filename, std::ios::binary);
fileStream.read((char *)&datetime, sizeof(datetime));

```

tm is defined in time.h:

```
struct tm
{
  int   tm_sec;
  int   tm_min;
  int   tm_hour;
  int   tm_mday;
  int   tm_mon;
  int   tm_year;
  int   tm_wday;
  int   tm_yday;
  int   tm_isdst;
#ifdef __TM_GMTOFF
  long  __TM_GMTOFF;
#endif
#ifdef __TM_ZONE
  const char *__TM_ZONE;
#endif
};

```

My tm struct doesn't have the 'tm\_gmtoff' or 'tm\_zone', even if it had it wont add up to 56 bytes.

How can my tm be 56 bytes on my PC? If someone has a better way to log a datetime object, without this issue, let me know.

# Answer
> 2 votes
You can not trust system-level structs for data storage or transfer between different systems. The main reasons are:

1. Different data type sizes (16 / 32 / 64 bit ints, floats vs doubles, etc)
2. Struct element alignment differences owing to underlying architecture optimizations and limitations

Unless you are working with a system struct that is specifically designed for cross-system communication you must define your own and pay special attention to the layout.

1. Always use explicitly sized variable types (uint8\_t, int32\_t, etc for example) to ensure both ends always agree on data storage sizes
2. Always "pack" your struct (`__attribute__((packed))`) to collapse any specially aligned variables into just the room needed to store those variables

Point 2 requires special attention if you're doing much more than filling the struct and saving / transmitting it. It's advisable to never do more than create the struct instance, fill it, save it, then throw it away. If you start doing advanced operations with pointers to the struct you risk corrupting the packing code if the alignment changes. Also packed structs are often slightly slower to access owing to more complex code usually needed to be used to read / write the individual fields within them (especially if there are no byte-wise operations in the underlying architecture).

---
Tags: esp32, time, sd
---


# Question
Title: RS-485 Serial communication problem with arduino
I use 485 modules to transmit data serially from one arduino uno to another uno.

If I connect the 2 arduino boards directly without using the rs485 module, the data is sent and received without a problem. But when using the rs485 module, the transmission stops.

Tx code:

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

void loop() {
    Serial.write(200);
    Serial.flush();
    delay(50);
}

```

Rx code:

```
#include <LiquidCrystal.h>

// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

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

void loop() {
    if (Serial.available()) {        // If data has come in from Master
        int reply= Serial.read();    // Read the byte
        delay(10);

        lcd.print(reply);
    }
}

```

I can't see what is the problem. I checked every thing wiring and the code is so simple. I'm just sending one number 200 and want to display it on the rx.

Please help. If anyone has an idea about this problem thanks any way.

# Answer
> 1 votes
In modbus there are two pins which are as DE and RE which you need to set and reset while transmitting the data. Also you can check Modbus this library it has some examples which could be useful to you also in arduino Uno don't use software serial for transmitting the data use the hardware serial only I will suggest implement your code on arduino Mega if you have any and then port the code for Uno. Just go through the library you will find some helpful examples and it will solve your issue

# Answer
> 0 votes
I polished my glasses, I did not find the schematic and parts list. It appears you have to enable the transmitter and or receiver to make them work. DE and RE are pins on the Max RSS 485 driver chip and others. They will not transmit or receive if these are wrong. Many connect the DE and RE together to simplify the switching. In your case you have to enable the transmitter on the transmitting Arduino and the Receive on the receiving Arduino. Do not enable the transmitter on the receive side as it wall cause bus contention and it will probably stop working. The receive can be enabled on the transmitter. This is done is some protocols to validate the message sent. Since you are only sending one way you can hardwire them to the correct logic level. Also you should terminate the buss, it may work without but best to add the resistors.

---
Tags: arduino-uno, serial, programming, communication, rs485
---


# Question
Title: Bootload from a Nano to an ATMega328 without a crystal
I have a program to load from a Aduino Nano as ISP to a ATMega328p chip that will have an internal clock at 16M, but I don't have a crystal handy.

Is there a way I can not have to buy a crystal? What should be the circuit's look like?

Here's how I have it hooked:

1. Ground to Ground (Pin 8)
2. 5V to VCC (Pin 7)
3. D10 to Reset (Pin 1)
4. D11 to MOSI (Pin 17)
5. D12 to MISO (Pin 18)
6. D13 to AVCC (Pin 20) (There are no resistors or capacitors, that all was part of a tutorial I cannot find anymore)

So I'm testing now with the basic Blink sketch and here is the resulting terminal comments.

```
/Applications/Arduino.app/Contents/Java/arduino-builder -dump-prefs -logger=machine -hardware /Applications/Arduino.app/Contents/Java/hardware -hardware /Users/b77/Library/Arduino15/packages -tools /Applications/Arduino.app/Contents/Java/tools-builder -tools /Applications/Arduino.app/Contents/Java/hardware/tools/avr -tools /Users/b77/Library/Arduino15/packages -built-in-libraries /Applications/Arduino.app/Contents/Java/libraries -libraries /Users/b77/Documents/Arduino/libraries -fqbn=megax8:avr:atmegax8:cpu=328_16 -vid-pid=0403_6001 -ide-version=10816 -build-path /var/folders/hv/kcqzq2sd5sl5kwxjrbq96vs80000gn/T/arduino_build_216627 -warnings=none -build-cache /var/folders/hv/kcqzq2sd5sl5kwxjrbq96vs80000gn/T/arduino_cache_67558 -prefs=build.warn_data_percentage=75 -prefs=runtime.tools.avr-gcc.path=/Users/b77/Library/Arduino15/packages/arduino/tools/avr-gcc/7.3.0-atmel3.6.1-arduino5 -prefs=runtime.tools.avr-gcc-7.3.0-atmel3.6.1-arduino5.path=/Users/b77/Library/Arduino15/packages/arduino/tools/avr-gcc/7.3.0-atmel3.6.1-arduino5 -prefs=runtime.tools.avrdude.path=/Users/b77/Library/Arduino15/packages/arduino/tools/avrdude/6.3.0-arduino17 -prefs=runtime.tools.avrdude-6.3.0-arduino17.path=/Users/b77/Library/Arduino15/packages/arduino/tools/avrdude/6.3.0-arduino17 -verbose /Applications/Arduino.app/Contents/Java/examples/01.Basics/Blink/Blink.ino
/Applications/Arduino.app/Contents/Java/arduino-builder -compile -logger=machine -hardware /Applications/Arduino.app/Contents/Java/hardware -hardware /Users/b77/Library/Arduino15/packages -tools /Applications/Arduino.app/Contents/Java/tools-builder -tools /Applications/Arduino.app/Contents/Java/hardware/tools/avr -tools /Users/b77/Library/Arduino15/packages -built-in-libraries /Applications/Arduino.app/Contents/Java/libraries -libraries /Users/b77/Documents/Arduino/libraries -fqbn=megax8:avr:atmegax8:cpu=328_16 -vid-pid=0403_6001 -ide-version=10816 -build-path /var/folders/hv/kcqzq2sd5sl5kwxjrbq96vs80000gn/T/arduino_build_216627 -warnings=none -build-cache /var/folders/hv/kcqzq2sd5sl5kwxjrbq96vs80000gn/T/arduino_cache_67558 -prefs=build.warn_data_percentage=75 -prefs=runtime.tools.avr-gcc.path=/Users/b77/Library/Arduino15/packages/arduino/tools/avr-gcc/7.3.0-atmel3.6.1-arduino5 -prefs=runtime.tools.avr-gcc-7.3.0-atmel3.6.1-arduino5.path=/Users/b77/Library/Arduino15/packages/arduino/tools/avr-gcc/7.3.0-atmel3.6.1-arduino5 -prefs=runtime.tools.avrdude.path=/Users/b77/Library/Arduino15/packages/arduino/tools/avrdude/6.3.0-arduino17 -prefs=runtime.tools.avrdude-6.3.0-arduino17.path=/Users/b77/Library/Arduino15/packages/arduino/tools/avrdude/6.3.0-arduino17 -verbose /Applications/Arduino.app/Contents/Java/examples/01.Basics/Blink/Blink.ino
Using board 'atmegax8' from platform in folder: /Users/b77/Library/Arduino15/packages/megax8/hardware/avr/1.0.3
Using core 'megax8' from platform in folder: /Users/b77/Library/Arduino15/packages/megax8/hardware/avr/1.0.3
Detecting libraries used...
/Users/b77/Library/Arduino15/packages/arduino/tools/avr-gcc/7.3.0-atmel3.6.1-arduino5/bin/avr-g++ -c -g -Os -w -std=gnu++11 -fpermissive -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -Wno-error=narrowing -flto -w -x c++ -E -CC -mmcu=atmega328p -DF_CPU=16000000L -DARDUINO=10816 -DARDUINO_ATmegaxX8 -DARDUINO_ARCH_AVR -I/Users/b77/Library/Arduino15/packages/megax8/hardware/avr/1.0.3/cores/megax8 -I/Users/b77/Library/Arduino15/packages/megax8/hardware/avr/1.0.3/variants/megax8 /var/folders/hv/kcqzq2sd5sl5kwxjrbq96vs80000gn/T/arduino_build_216627/sketch/Blink.ino.cpp -o /dev/null
Generating function prototypes...
/Users/b77/Library/Arduino15/packages/arduino/tools/avr-gcc/7.3.0-atmel3.6.1-arduino5/bin/avr-g++ -c -g -Os -w -std=gnu++11 -fpermissive -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -Wno-error=narrowing -flto -w -x c++ -E -CC -mmcu=atmega328p -DF_CPU=16000000L -DARDUINO=10816 -DARDUINO_ATmegaxX8 -DARDUINO_ARCH_AVR -I/Users/b77/Library/Arduino15/packages/megax8/hardware/avr/1.0.3/cores/megax8 -I/Users/b77/Library/Arduino15/packages/megax8/hardware/avr/1.0.3/variants/megax8 /var/folders/hv/kcqzq2sd5sl5kwxjrbq96vs80000gn/T/arduino_build_216627/sketch/Blink.ino.cpp -o /var/folders/hv/kcqzq2sd5sl5kwxjrbq96vs80000gn/T/arduino_build_216627/preproc/ctags_target_for_gcc_minus_e.cpp
/Applications/Arduino.app/Contents/Java/tools-builder/ctags/5.8-arduino11/ctags -u --language-force=c++ -f - --c++-kinds=svpf --fields=KSTtzns --line-directives /var/folders/hv/kcqzq2sd5sl5kwxjrbq96vs80000gn/T/arduino_build_216627/preproc/ctags_target_for_gcc_minus_e.cpp
Compiling sketch...
/Users/b77/Library/Arduino15/packages/arduino/tools/avr-gcc/7.3.0-atmel3.6.1-arduino5/bin/avr-g++ -c -g -Os -w -std=gnu++11 -fpermissive -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -Wno-error=narrowing -MMD -flto -mmcu=atmega328p -DF_CPU=16000000L -DARDUINO=10816 -DARDUINO_ATmegaxX8 -DARDUINO_ARCH_AVR -I/Users/b77/Library/Arduino15/packages/megax8/hardware/avr/1.0.3/cores/megax8 -I/Users/b77/Library/Arduino15/packages/megax8/hardware/avr/1.0.3/variants/megax8 /var/folders/hv/kcqzq2sd5sl5kwxjrbq96vs80000gn/T/arduino_build_216627/sketch/Blink.ino.cpp -o /var/folders/hv/kcqzq2sd5sl5kwxjrbq96vs80000gn/T/arduino_build_216627/sketch/Blink.ino.cpp.o
Compiling libraries...
Compiling core...
Using precompiled core: /var/folders/hv/kcqzq2sd5sl5kwxjrbq96vs80000gn/T/arduino_cache_67558/core/core_megax8_avr_atmegax8_cpu_328_16_27f180324ce8b44e5ad3e6dc83e4e5ee.a
Linking everything together...
/Users/b77/Library/Arduino15/packages/arduino/tools/avr-gcc/7.3.0-atmel3.6.1-arduino5/bin/avr-gcc -w -Os -g -flto -fuse-linker-plugin -Wl,--gc-sections -mmcu=atmega328p -o /var/folders/hv/kcqzq2sd5sl5kwxjrbq96vs80000gn/T/arduino_build_216627/Blink.ino.elf /var/folders/hv/kcqzq2sd5sl5kwxjrbq96vs80000gn/T/arduino_build_216627/sketch/Blink.ino.cpp.o /var/folders/hv/kcqzq2sd5sl5kwxjrbq96vs80000gn/T/arduino_build_216627/../arduino_cache_67558/core/core_megax8_avr_atmegax8_cpu_328_16_27f180324ce8b44e5ad3e6dc83e4e5ee.a -L/var/folders/hv/kcqzq2sd5sl5kwxjrbq96vs80000gn/T/arduino_build_216627 -lm
/Users/b77/Library/Arduino15/packages/arduino/tools/avr-gcc/7.3.0-atmel3.6.1-arduino5/bin/avr-objcopy -O ihex -j .eeprom --set-section-flags=.eeprom=alloc,load --no-change-warnings --change-section-lma .eeprom=0 /var/folders/hv/kcqzq2sd5sl5kwxjrbq96vs80000gn/T/arduino_build_216627/Blink.ino.elf /var/folders/hv/kcqzq2sd5sl5kwxjrbq96vs80000gn/T/arduino_build_216627/Blink.ino.eep
/Users/b77/Library/Arduino15/packages/arduino/tools/avr-gcc/7.3.0-atmel3.6.1-arduino5/bin/avr-objcopy -O ihex -R .eeprom /var/folders/hv/kcqzq2sd5sl5kwxjrbq96vs80000gn/T/arduino_build_216627/Blink.ino.elf /var/folders/hv/kcqzq2sd5sl5kwxjrbq96vs80000gn/T/arduino_build_216627/Blink.ino.hex
/Users/b77/Library/Arduino15/packages/arduino/tools/avr-gcc/7.3.0-atmel3.6.1-arduino5/bin/avr-size -A /var/folders/hv/kcqzq2sd5sl5kwxjrbq96vs80000gn/T/arduino_build_216627/Blink.ino.elf
Sketch uses 924 bytes (2%) of program storage space. Maximum is 32768 bytes.
Global variables use 9 bytes (0%) of dynamic memory, leaving 2039 bytes for local variables. Maximum is 2048 bytes.
/Users/b77/Library/Arduino15/packages/arduino/tools/avrdude/6.3.0-arduino17/bin/avrdude -C/Users/b77/Library/Arduino15/packages/arduino/tools/avrdude/6.3.0-arduino17/etc/avrdude.conf -v -patmega328p -cstk500v1 -P/dev/cu.usbserial-AC012GAB -b19200 -Uflash:w:/var/folders/hv/kcqzq2sd5sl5kwxjrbq96vs80000gn/T/arduino_build_216627/Blink.ino.hex:i

avrdude: Version 6.3-20190619
         Copyright (c) 2000-2005 Brian Dean, http://www.bdmicro.com/
         Copyright (c) 2007-2014 Joerg Wunsch

         System wide configuration file is "/Users/b77/Library/Arduino15/packages/arduino/tools/avrdude/6.3.0-arduino17/etc/avrdude.conf"
         User configuration file is "/Users/b77/.avrduderc"
         User configuration file does not exist or is not a regular file, skipping

         Using Port                    : /dev/cu.usbserial-AC012GAB
         Using Programmer              : stk500v1
         Overriding Baud Rate          : 19200
         AVR Part                      : ATmega328P
         Chip Erase delay              : 9000 us
         PAGEL                         : PD7
         BS2                           : PC2
         RESET disposition             : dedicated
         RETRY pulse                   : SCK
         serial program mode           : yes
         parallel program mode         : yes
         Timeout                       : 200
         StabDelay                     : 100
         CmdexeDelay                   : 25
         SyncLoops                     : 32
         ByteDelay                     : 0
         PollIndex                     : 3
         PollValue                     : 0x53
         Memory Detail                 :

                                  Block Poll               Page                       Polled
           Memory Type Mode Delay Size  Indx Paged  Size   Size #Pages MinW  MaxW   ReadBack
           ----------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- ---------
           eeprom        65    20     4    0 no       1024    4      0  3600  3600 0xff 0xff
           flash         65     6   128    0 yes     32768  128    256  4500  4500 0xff 0xff
           lfuse          0     0     0    0 no          1    0      0  4500  4500 0x00 0x00
           hfuse          0     0     0    0 no          1    0      0  4500  4500 0x00 0x00
           efuse          0     0     0    0 no          1    0      0  4500  4500 0x00 0x00
           lock           0     0     0    0 no          1    0      0  4500  4500 0x00 0x00
           calibration    0     0     0    0 no          1    0      0     0     0 0x00 0x00
           signature      0     0     0    0 no          3    0      0     0     0 0x00 0x00

         Programmer Type : STK500
         Description     : Atmel STK500 Version 1.x firmware
         Hardware Version: 2
         Firmware Version: 1.18
         Topcard         : Unknown
         Vtarget         : 0.0 V
         Varef           : 0.0 V
         Oscillator      : Off
         SCK period      : 0.1 us

avrdude: AVR device initialized and ready to accept instructions

Reading | ################################################## | 100% 0.04s

avrdude: Device signature = 0x000000 (retrying)

Reading | ################################################## | 100% 0.04s

avrdude: Device signature = 0x000000 (retrying)

An error occurred while uploading the sketch
Reading | ################################################## | 100% 0.05s

avrdude: Device signature = 0x000000
avrdude: Yikes!  Invalid device signature.
         Double check connections and try again, or use -F to override
         this check.

avrdude done.  Thank you.

```

From what I've seen online, the device signature being 0x000000 could potentially mean that the lack of crystal may make it impossible for me to do the bootloading. The chip is also brand new and I've tested with more than one as I have 3.

My thought is that I probably read the tutorial wrong especially with the AVCC pin?

In any case, **how should I connect a Nano to an ATMega328p without a crystal?**

Thanks for your help!

# Answer
> 1 votes
Alright. After reading some and some more, I was able to notice that SCK, just one pin down from AVCC, was the missing link.

Yet another reminder to properly **read the fabulous manual**.

It looks so easy now.

---
Tags: arduino-nano, atmega328, bootloader, wires
---


# Question
Title: multiple blinking LEDs at different intervals, morse code A included
Good evening,

I am writing Arduino code to flash multiple LEDS at different sequences from different pins. Everything is working well, however I cant determine how to add in a Morse Code A flash sequence.

Ideally the sequence would go 1s, on 1s off, 3s on, 3s off. then repeat continuously, this would be for a MO (A) bouy

Below is the format I have used for all other lights and works well with 8 different sequences.

```
// A is 1s, B is 2.5s, C is 4s, D is 5s, F is 6s, G is 8s, H is 10s ,

#define aLed 2
#define bLed 3
#define cLed 4
#define dLed 5
#define fLed 6
#define gLed 7
#define hLed 8

void setup() {
  pinMode(aLed, OUTPUT); //pin2 Output
  pinMode(bLed, OUTPUT); //pin3 Output
  pinMode(cLed, OUTPUT); //pin4 Output
  pinMode(dLed, OUTPUT); //pin5 Output
  pinMode(fLed, OUTPUT); //pin6 Output
  pinMode(gLed, OUTPUT); //pin7 Output
  pinMode(hLed, OUTPUT); //pin8 Output

}

void loop() {
  BlinkA(1000);
  BlinkB(2500);
  BlinkC(4000);
  BlinkD(5000);
  BlinkF(6000);
  BlinkG(8000);
  BlinkH(10000);

}
 void BlinkA (int interval){
   static long prevMill = 0;
   if ((millis() - prevMill) >= interval){
    prevMill = millis();
    digitalWrite(aLed, !digitalRead(aLed));
 }
}
void BlinkB (int interval){
   static long prevMill = 0;
   if (((long)millis() - prevMill) >= interval){
    prevMill = millis();
    digitalWrite(bLed, !digitalRead(bLed));
  }
 }
  void BlinkC (int interval){
   static long prevMill = 0;
   if ((millis() - prevMill) >= interval){
    prevMill = millis();
    digitalWrite(cLed, !digitalRead(cLed));
 }
}
 void BlinkD (int interval){
   static long prevMill = 0;
   if ((millis() - prevMill) >= interval){
    prevMill = millis();
    digitalWrite(dLed, !digitalRead(dLed));
 }
}
 void BlinkF (int interval){
   static long prevMill = 0;
   if ((millis() - prevMill) >= interval){
    prevMill = millis();
    digitalWrite(fLed, !digitalRead(fLed));
 }
}
 void BlinkG (int interval){
   static long prevMill = 0;
   if ((millis() - prevMill) >= interval){
    prevMill = millis();
    digitalWrite(gLed, !digitalRead(gLed));
 }
}
 void BlinkH (int interval){
   static long prevMill = 0;
   if ((millis() - prevMill) >= interval){
    prevMill = millis();
    digitalWrite(hLed, !digitalRead(hLed));
 }
}

```

# Answer
> multiple blinking LEDs at different intervals, (*not all periodic*)...

I changed your question hopefully with out changing its meaning.

Based on this question, I would suggest using a finite state machine. Assuming you are using differently named "BlankI()" functions for each LED, consider adding state machine features to 1 of these functions to control the "*not periodic*" LED. Consider a state machine with 4 state one for each action:

0. LED On for 1 second.
1. LED Off for 1 second.
2. LED On for 3 seconds.
3. LED Off for 3 seconds.

Use a counter (either global or static to preserve its value between calls to that function) to track the states. Use a switch/case coding pattern to set the "prevMill" to the appropriate time delay for the current state.
> 2 votes

---
Tags: led
---


# Question
Title: Issue with input from weighing scale controlling a stepper motor based valve
Hello and thanks for any help in advanced.

What changes do I need to make to my code to get rid of the issue of the valve opening up again at end of cycle in "Auto" function.

Hardware:

* Arduino Mega
* Bi-polar Stepper Motor connected to Valve.
* Weighing scale with TTL output.

Here is my code:

```
//Buttons
#include <mechButton.h> //Button Library
#define BTNa_PIN  10    //Button Pins
#define BTNb_PIN  6
mechButton aButton(BTNa_PIN);  // Set button to pin BTN_PIN.
mechButton bButton(BTNb_PIN);

//Stepper
#include <AccelStepper.h> //Stepper Library
#define dirPin 4          //Stepper Pins
#define stepPin 2
#define motorInterfaceType 1 //Interface set to driver
AccelStepper stepper = AccelStepper(motorInterfaceType, stepPin, dirPin);// Create a new instance

//Analog inputs for setting Max and Min Distance
const int analogPin = A0;
const int analogPin2 =A1;

//Data types for Scale Reading for Optima OP900a
char inString[32];
float Input;
float Setpoint;
float fSetpoint;

//Setup
void setup() {

  Serial.begin(9600);           // Fire up our serial monitor for arduino and computer
  Serial3.begin(9600);          //Fire up Serial for Scale for input

  aButton.setCallback(Manual);    // Set up our callback. (Also calls hookup() for idling.)
  bButton.setCallback(Auto);
  stepper.setMaxSpeed(3500);      // Set the maximum speed and acceleration for stepper motor:
  stepper.setAcceleration(5000);

  Setpoint = 4.44;               // Auto parameters
  fSetpoint = (Setpoint*0.9);

}
// Main Loop
void loop() {
   bool abuttonState;
   bool bButtonState;

   idle();                      // Let all the idlers have time to do their thing.
   abuttonState = aButton.trueFalse();    // Have a look at what the current button state is.
   bButtonState = bButton.trueFalse();
}
//Sub Functions
void Manual(void) {
    int maxOpen = analogRead(analogPin);
    maxOpen = map(maxOpen, 0, 1023, 0,100);

   Serial.print("Manual ");
   if (aButton.trueFalse()) {
      stepper.moveTo(0);
      stepper.runToPosition();
   } else {
      stepper.moveTo(maxOpen*40);
      stepper.runToPosition();

   }
}

void Auto(void) {
    int maxOpen = analogRead(analogPin);
    int minOpen = analogRead(analogPin2);
    maxOpen = map(maxOpen, 0, 1023, 0,100);
    minOpen = map(minOpen, 0, 1023, 0,100);

   while (Input < Setpoint){
     readScale();
     if (Input >= fSetpoint && Input < Setpoint){
     stepper.runToNewPosition((minOpen*10)+400);  //Blocking function research work around...
     Serial.print("Min");Serial.print(",");       //debugging
     Serial.println(Input);                       //debugging
     }
     else if (Input < fSetpoint) {
     stepper.runToNewPosition(maxOpen*40);         //Blocking function research work around...
     Serial.print("Max");Serial.print(",");       //debugging
     Serial.println(Input);                       //debugging
     }
     else{
     stepper.runToNewPosition(0);                 //Blocking function research work around...
     Serial.print("Close");Serial.print(",");     //debugging
     Serial.println(Input);                       //debugging
     }
     }
}

void readScale(void){
    byte inChar = Serial3.readBytesUntil('\n', inString, 18); //Scale reading for input
    float scaleInput = atof(&inString[7]);
    Input = scaleInput;
  }

```

I keep getting this strange behavior at the end of the "Auto" function where I am getting false 0.00 from the scale that causes the valve to open and close fully at the end.

```
Max,0.01
Max,0.01
Max,0.01
Max,0.00
Max,0.00
Max,0.00
Max,0.00
Max,0.35
Max,0.42
Max,0.51
Max,0.60
Max,0.66
Max,0.69
Max,0.75
Max,0.83
Max,0.88
Max,0.93
Max,1.00
Max,1.05
Max,1.11
Max,1.16
Max,1.21
Max,1.26
Max,1.32
Max,1.38
Max,1.43
Max,1.48
Max,1.53
Max,1.59
Max,1.64
Max,1.68
Max,1.74
Max,1.80
Max,1.84
Max,1.89
Max,1.94
Max,1.99
Max,2.04
Max,2.09
Max,2.14
Max,2.18
Max,2.23
Max,2.27
Max,2.32
Max,2.37
Max,2.41
Max,2.45
Max,2.50
Max,2.55
Max,2.59
Max,2.62
Max,2.68
Max,2.72
Max,2.76
Max,2.81
Max,2.85
Max,2.88
Max,2.93
Max,2.97
Max,3.00
Max,3.04
Max,3.08
Max,3.13
Max,3.17
Max,3.20
Max,3.23
Max,3.27
Max,3.31
Max,3.35
Max,3.39
Max,3.42
Max,3.46
Max,3.50
Max,3.52
Max,3.55
Max,3.60
Max,3.63
Max,3.66
Max,3.69
Max,3.73
Max,3.77
Max,3.80
Max,3.83
Max,3.87
Max,3.91
Max,3.94
Max,3.95
Max,3.98
Min,4.03
Min,4.06
Min,4.09
Min,4.13
Max,0.00
Max,0.00
Min,4.35
MZ��r��j
Min,4.36
Close,4.46

```

Any suggestions are welcome.

Thanks

# Answer
There are a few issues here:

* `Serial3.readBytesUntil()` does not add a null character at the end of the string. You have to do it yourself if you want a properly terminated string.
* You are attempting to read a float starting at the eight byte of the string, even if you got less than eight bytes.
* `atof()` does not report errors. If it fails to parse a float, it just returns zero.

Just to see what may be going wrong, I suggest this version of `readScale()` with verbose debug output:

```
void readScale(void) {
    byte inChar = Serial3.readBytesUntil('\n', inString, 18);
    inString[inChar] = '\0';  // terminate the string
    const char *start = &inString[7];  // where the number is expected
    char *end;  // where strtod() found it ends
    float scaleInput = strtod(start, &end);
    Serial.print("Scale -> \"");
    Serial.print(inString);
    Serial.print("\", parsed \"");
    *end = '\0';  // terminate the string after the number
    Serial.print(start);
    Serial.print("\" as ");
    Serial.println(scaleInput);
    Input = scaleInput;
}

```
> 1 votes

---
Tags: arduino-mega, stepper, serial-data
---


# Question
Title: ESP32 TCP disconnect takes very long to be recognized
I'm using the following class to create a stream from a WiFi (server) connection. The client (a PC application) connects to the ESP32 and then issues commands over this connection. This works fine. When the client disconnects gracefully, the connection is reset and the ESP32 is ready for another connection. Only one client can connect at a time, but that's ok for now.

The problem arises when the client disconnects unexpectedly (e.g. if I just kill the process on the PC). The connection remains open for a very long time (10 minutes or so) until the ESP32 detects that the connection died. Within that time, no new connection can be established. In that state, I can still see it printing "Still connected" messages to the serial console, with reducing pace (the number of messages per second drops significantly until it finally gives up).

Is there a way to reduce the timeout on a dead connection? The (working) connection itself might be idle for long times as well, so just because no messages are received doesn't mean we can drop the connection from the ESP32 end.

The `Connect()` function below is called from `loop()` and in normal mode, it just prints "New client connected" and "client disconnected" messages.

```

class WifiCachingStream : public Stream
{
private:
    WiFiServer _server;
    WiFiClient _activeClient;
    bool _hasActiveClient;
public:
    WifiCachingStream(int port) :
    _server(port), _activeClient()
    {
        _hasActiveClient = false;
    }

    void Init()
    {
        _server.begin();
    }

    bool Connect();

    int read() override;

    size_t write(byte b) override;

    void maintain();

    int available() override
    {
        return _activeClient.available();
    }

    int peek() override
    {
        return _activeClient.peek();
    }

    void flush() override
    {
        // Do nothing. The implementation of WifiClient clears the _INPUT_ queue instead of the output queue!
        // _activeClient.flush();
    }

    bool isConnected() const
    {
        return _hasActiveClient;
    }
};

int idx = 0; // for testing only
bool WifiCachingStream::Connect()
{
    if (_activeClient.available() || _activeClient.connected())
    {
        if ((idx ++) % 10000 == 0)
        {
            // For testing: This is printed to the console, even after the communication has been killed on the PC
            Serial.println("Still connected");
            // This (attempts to) send a message over the link, which I would expect to cause the implementation to detect that the connection was dropped.
            Firmata.sendString(F("Still connected"));
        }
        return true;
    }

    _activeClient.stop();
    _activeClient = _server.accept();

    if (_activeClient)
    {
        Serial.println("New client connected");
        WiFi.setSleep(false);
        _hasActiveClient = true;
        return true;
    }

    if (_hasActiveClient)
    {
        _hasActiveClient = false;
        Serial.println("Client disconnected - entering WiFi low-power mode");
        // Low-power mode significantly increases round-trip time, but when nobody
        // is connected, that's ok.
        WiFi.setSleep(true);
    }

    return false;
}

// Other functions irrelevant

```

# Answer
> 1 votes
It's more or less a fact of life that having TCP detect a lost connection (ungraceful disconnect) takes a long time when nothing is being sent over it.

There may be some quaint and curious keepalive and time-out settings in the protocol itself, but implementing a heartbeat (call it an application-level keep-alive) that is sent by the client, and closing the connection from the ESP32-end when no heartbeat/keep-alive message has been received for a certain period, is probably your best bet and it will also give you precise control over the time-out time.

---
Tags: wifi, esp32
---


# Question
Title: How do I connect 20 outputs and 20 inputs to an Arduino board?
I am a mechanical engineer starting my journey with Arduino, so please excuse me if I put some very generalized message.

* I need to sequentially operate 20 output relays, and then verify if the correct relay has been triggered. If the correct relay was triggered, the next relay will be triggered after a delay of 1-2 seconds.
* I plan to do this with an Arduino Uno so that I can generate error messages if any output has not been triggered.

However, the Uno doesn't have sufficient inputs and outputs to do this. So what are my options?

I want to ask you the below:-

1. If there are I/O expansion boards available for the Uno? If yes, sharing the details will be helpful;
2. A friend recommended to use a multiplexer. Can I use a multiplexer to convert a 4 pin output from the Arduino to 16 pin output, and probably use the saved pins to monitor the inputs? If yes, how?
3. Is there something available like a reverse multiplexer wherein the chip can convert the 16 output signals to 4 pin inputs to the Arduino?

Please let me know the best solution wrt the below parameters - reliability of operation, cost, compactness.

Thanks for your time and support.

# Answer
Look for port expansion boards for the arduino, there are a lot of them many under a dollar. Typically they are in 8 or 16 channel designs. They probably will have PCF8574 or PCF8575 chips. These are low voltage (typically 5V) for the Arduino. You will have to use an interface if it is connected to another voltage. Each of these modules the channels can be individually programmed as an input or output. You can turn on or any of the outputs in any order and pattern you want. These devices operate with the I2C interface so you need only two lines from the Arduino to drive up to 8 of these modules. The pins should be labeled A4 (SDA), A5 (SCL) depending on the model of Arduino you have. Good luck!
> 2 votes

# Answer
Instead of using expansion boards, you could use an Arduino Mega or an Arduino Due instead. These have more than enough GPIO pins for 20 inputs and 20 outputs. The price isn't much higher compared to the extra expansion board and the extra wiring required.
> 1 votes

---
Tags: arduino-uno, multiplexer
---


# Question
Title: ESP8266 module ESP-12F does not connect to esptool.py
I have bought some blank ESP-12F modules like this: https://www.aliexpress.com/item/1005001520382593.html

For these modules I have made my own adapter PCB to connect them, but now I don't get any connection with the esptool.py to these modules.

The connection is:

```
TX --------------- RX with an PL2303 USB adapter
RX --------------- TX with an PL2303 USB adapter
EN --------------- 3.3V
GPIO-0 ----------- GND over button
GPIO-15 ---------- GND over 4K7 resistor
RESET ------------ GND over button
GND -------------- GND
VCC -------------- 3.3V from AMS1117-3.3 blocked with Elko 220µF

```

With a serial terminal I can cleary see with 74880 baud the response for standard boot on TXD (GPIO1):

```
 ets Jan  8 2013,rst cause:2, boot mode:(7,7)

waiting for host

```

and on TXD1 (GPIO2)

```
 ets Jan  8 2013,rst cause:2, boot mode:(7,6)

waiting for host

```

---

For flash mode with RESET and GPIO-0 on TXD (GPIO1):

```
 ets Jan  8 2013,rst cause:2, boot mode:(5,7)

waiting for host

```

and on TXD1 (GPIO2)

```
 ets Jan  8 2013,rst cause:2, boot mode:(5,6)

waiting for host

```

---

I tried to connect with:

python3 esptool.py --port /dev/ttyUSB0 flash\_id
or
python3 esptool.py --chip esp8266 --port /dev/ttyUSB0 flash\_id
or
python3 esptool.py --no-stub --port /dev/ttyUSB0 flash\_id

but no connection can be established.

"A fatal error occurred: Failed to connect to Espressif device: No serial data received."

With the trace option I get:

```
TRACE +0.000 Write 46 bytes:
    c000082400000000 0007071220555555 | ...$........ UUU
    5555555555555555 5555555555555555 | UUUUUUUUUUUUUUUU
    5555555555555555 5555555555c0     | UUUUUUUUUUUUU.
TRACE +0.082 Read 1 bytes: 72
TRACE +0.000 Read invalid data: 72
TRACE +0.000 Remaining data in serial buffer: 6c00

```

I tried the connection with this two versions:

esptool.py v3.3-dev
esptool.py v2.0-beta2

I assume this is simply bad hardware.
Is there anybody who has mastered this problem?

# Answer
You have io 15 HIGH. Check the pull-down.

The first number in () on first line of the boot log is the state of the boot config pins. First bit is the state of io 2, second the state of io 0 and third is the state of io 15.

You have 5 or 7 which is 101 or 111 in binary. So you have io 15 HIGH.

io 15 HIGH is a mode where the esp8266 doesn't have its own flash memory but boots from the host MCU so you get "waiting for host".

io 15 must be LOW for the esp8266 to use the flash memory.

So you should see for normal mode

```
ets Jan  8 2013,rst cause:2, boot mode:(3,6)

```

and for flashing mode

```
ets Jan  8 2013,rst cause:2, boot mode:(1,6)

```

Note: it can be (3,7) and (1,7) too
> -1 votes

---
Tags: esp8266, flash
---


# Question
Title: Should I use C or C++ for a pure code implementation of Arduino?
I have an arduino board (SAMD21 microcontroller) which supports either Arduino or CircuitPython programming. I'd like to program in pure C/C++ instead of Arduino, which seems to be possible without too much trouble. But I'm not sure whether to use C or C++. I thought Arduino was based in C++ but I went to look at some of the library files and they were written in C. Since I'm pretty sure they're not interchangeable, can someone help me learn which language I should use to program my board?

# Answer
> 3 votes
> I thought Arduino was based in C++

There is no language "Arduino" - the Arduino IDE runs a the GNU C++ compiler so "its language" is the language supported by the compiler. It is primarily C++ with a little bit of preprocessing done to your code to help learners get past some of the places they can trip over easily (adding #include statements when it thinks you need them, for instance).

Here is an answer I wrote to a similar question a few years ago. I think it's relevant to your question.

---
Tags: arduino-ide, c++, c
---


title: Arduino native USB port and Simulink

text:
# Question
Title: Arduino native USB port and Simulink
I am trying to communicate through the native USB port of the Arduino Due with a PC.

The native port itself works, I have tested this. The problem is, that every time I upload my Simulink model via the programming port onto the Arduino, Windows loses the connection to the native (Bossa) port.

It does not recocnize the port anymore after programming the Arduino with Simulink (Arduino Support Package). The only way to get Windows to recognise the port again is holding reset+erase on the Arduino, which obviously deletes my application.

Do you know any solution? Is this possible to get the native port working for communication after using Simulink to deploy my application?

# Answer
> 0 votes
Got it working myself by simply writing the communication part in C for the Due, not using the Simulink blocks.

---
Tags: serial, usb, arduino-due, communication
---