body:
Trying to understand the two libraries and setSyncProvider(RTC.now).
Using Arduino Uno with Adafruit ChronoDot.  Aduino IDE 1.8.13.

The code below is simply to understand what is happening.
I am getting surprising results which means I do not understand what the libraries are doing.

What I *think* I am telling it to do:

1.  Set time RTC to 05:10:30
2.  Set Time Library to 09:27:05
3.  In Loop, printing Library time (hour, minute, seconds)
4.  In Loop, printing RTC time (now.hour, now.minute, now.second)
5.  Every 5 seconds sync the Time Library to the RTC.
This is not what it is doing.
The output from serial prints is at the bottom.

**Question 1:**  Why does Time Library time  hour() minute() second() change from 9:27:9 to 12:43:44 after first sync and then from 12:43:48 to 19:1:20 after second sync, then reseting to  19:1:20 after each subsequent sync?

**Question 2:**  After the Sync, why is Time Library hour(), minute() and second() not set to RTC values of now.hour(), now.minute() and now.second()?

    #include "RTClib.h"
    #include <Wire.h>
    #include <TimeLib.h>

    RTC_DS1307 RTC;
    unsigned long LastSyncTime = 0;    //will control when it syncs just to understand

    time_t time_provider()

    {
        return RTC.now().unixtime();
    }

    void setup() {
    Serial.begin(9600);
    Wire.begin();  //sets up the I2C
    RTC.begin();   //initializes the I2C to the RTC

    //  Set the RTC Time to 5:10:30 Nov 3 2020
    RTC.adjust(DateTime(2020,11,3,5,10,30));

    //Set Arduino Time Library different than RTC time 9:27:05 so see how sync works
    setTime(9, 27, 05, 4, 07, 2015);

    }

    void loop() {

    //Sync time every 5 seconds
    if ((millis() - LastSyncTime) > 5000)
      {
      Serial.println("+++++   Sync  ++++++++");
      setSyncProvider(RTC.now);  //sets Time Library to RTC time: hour() set to RTC now.hour (?)
      LastSyncTime = millis();

       }

    DateTime now = RTC.now();  // gets RTC time into now Object

    //Print Time Lib Times
    Serial.print("hour:       ");
    Serial.print(hour());
    Serial.println();
    Serial.print("minute:     ");
    Serial.print(minute());
    Serial.println();
    Serial.print("seconds:    ");
    Serial.print(second());
    Serial.println();
    Serial.println();

    //Print RTC time
    Serial.print("now.hour:   ");
    Serial.print(now.hour());
    Serial.println();
    Serial.print("now.minute: ");
    Serial.print(now.minute());
    Serial.println();
    Serial.print("now.second: ");
    Serial.print(now.second());
    Serial.println();
    Serial.println("______________________");

    delay(1000);
    }

OUTPUT

hour:       9
minute:     27
seconds:    8

now.hour:   5
now.minute: 10
now.second: 33

hour:       9
minute:     27
seconds:    9

now.hour:   5
now.minute: 10
now.second: 34

+++++   Sync  ++++++++
hour:       12
minute:     43
seconds:    44

now.hour:   5
now.minute: 10
now.second: 35

hour:       12
minute:     43
seconds:    45

now.hour:   5
now.minute: 10
now.second: 36

hour:       12
minute:     43
seconds:    46

now.hour:   5
now.minute: 10
now.second: 37

hour:       12
minute:     43
seconds:    47

now.hour:   5
now.minute: 10
now.second: 38

hour:       12
minute:     43
seconds:    48

now.hour:   5
now.minute: 10
now.second: 39

+++++   Sync  ++++++++
hour:       19
minute:     1
seconds:    20

now.hour:   5
now.minute: 10
now.second: 40

hour:       19
minute:     1
seconds:    21

now.hour:   5
now.minute: 10
now.second: 41

hour:       19
minute:     1
seconds:    22

now.hour:   5
now.minute: 10
now.second: 42

hour:       19
minute:     1
seconds:    23

now.hour:   5
now.minute: 10
now.second: 43

hour:       19
minute:     1
seconds:    24

now.hour:   5
now.minute: 10
now.second: 44

+++++   Sync  ++++++++
hour:       19
minute:     1
seconds:    20

now.hour:   5
now.minute: 10
now.second: 45

hour:       19
minute:     1
seconds:    21

now.hour:   5
now.minute: 10
now.second: 46

hour:       19
minute:     1
seconds:    22

now.hour:   5
now.minute: 10
now.second: 47

hour:       19
minute:     1
seconds:    23

now.hour:   5
now.minute: 10
now.second: 48

hour:       19
minute:     1
seconds:    24

now.hour:   5
now.minute: 10
now.second: 49

+++++   Sync  ++++++++
hour:       19
minute:     1
seconds:    20

now.hour:   5
now.minute: 10
now.second: 50

hour:       19
minute:     1
seconds:    21

now.hour:   5
now.minute: 10
now.second: 51

hour:       19
minute:     1
seconds:    22

now.hour:   5
now.minute: 10
now.second: 52

hour:       19
minute:     1
seconds:    23

now.hour:   5
now.minute: 10
now.second: 53

title: Sync of Time Library and RTClib

Answers: 1

body:
> Why does Time Library time hour() minute() second() change from 9:27:9 to 12:43:44 after first sync and then from 12:43:48 to 19:1:20 after second sync, then reseting to 19:1:20 after each subsequent sync?

Because:

1. You keep calling `setSyncProvider()`. The whole point of the sync system is that **you should only call that once to set the sync provider and then it syncs itself *automatically***.
2. You are setting the sync provider to a function that returns an object. The sync provider needs a function that returns an unsigned long (`time_t`).

Your code should be:

```c++
setSyncProvider(time_provider);
```

And it should **only be called once from inside setup**.

> Question 2: After the Sync, why is Time Library hour(), minute() and second() not set to RTC values of now.hour(), now.minute() and now.second()?

Because of all the things I stated above and were also told in your last question.


body: I have a normal Elegoo TFT 2.8" display shield that also had an SD reader. I am trying to use it as a Nextion display. I want to do this because the Nextion tool allows you to make very nice looking sophisticated graphics and I wanted to do the same. Is there any possibility? Maybe some interpreter library?

title: Use normal TFT Shield with SD as a Nextion Display

Answers: 2

body:
No, you can't.

Nextion displays contain their own microcontroller with their own closed-source firmware on them.  You need that firmware to have a clue what is in Nextion files, and only Nextion have that firmware.

While it may be possible to reverse engineer Nextion display data and write your own software to interpret it, it would be a huge job with little to no real-world benefit.

body:
You cannot use a 2.8" TFT as a Nextion Display. Two are seperate things

Nextion Display is an HMI. You can configure prebuilt menus and graphics without coding.

The 2.8" TFT is a generic display module. It prints data according to the commands it receives. The user has to prepare the data to be printed. It can read data from an sd card, but the user program has to issue the commands for it.

Nextion displays use a generic display like the 2.8" TFT, an onboard controller with custom firmware running on it.


body:
I'm a newbie to program an Arduino but I need to turn off a LED from a external Spectroscopy Sensor.

This is the Sensor:

[![sensor][1]][1]

There are three LEDs on this sensor and they're turned on automatically when the Arduino is plugged in. Can someone perhaps explain in general how to address a LED mounted on something like that ?

  [1]: https://i.stack.imgur.com/JDqgy.png

title: How can you turn off the LEDs on a SparkFun AS7265x Spectral Triad (Spectroscopy Sensor)?

Answers: 0


body:
The second and third `while` and `if` are not working but the first `while` and `if` do work. Am I doing something wrong?

```c++
#include <DFMiniMp3.h>

int sw1 = 3;
int sw2 = 4;
int sw3 = 5;

class Mp3Notify
{
  public:
    static void OnError(uint16_t errorCode)
    {
      // see DfMp3_Error for code meaning
      Serial.println();
      Serial.print("Com Error ");
      Serial.println(errorCode);
    }

    static void OnPlayFinished(uint16_t globalTrack)
    {
      Serial.println();
      Serial.print("Play finished for #");
      Serial.println(globalTrack);
    }

    static void OnCardOnline(uint16_t code)
    {
      Serial.println();
      Serial.print("Card online ");
      Serial.println(code);
    }

    static void OnCardInserted(uint16_t code)
    {
      Serial.println();
      Serial.print("Card inserted ");
      Serial.println(code);
    }

    static void OnCardRemoved(uint16_t code)
    {
      Serial.println();
      Serial.print("Card removed ");
      Serial.println(code);
    }
};
DFMiniMp3<HardwareSerial, Mp3Notify> mp3(Serial); //Create the UART connection to the module

void setup()
{

  //3 push buttons with pullups
  pinMode(sw1, INPUT); //Define each button as input with pullup
  pinMode(sw2, INPUT);
  pinMode(sw3, INPUT);

  digitalWrite (sw1, HIGH); //12 Votls supply set to off state
  digitalWrite (sw2, HIGH); //5 Votls supply set to off state
  digitalWrite (sw3, HIGH); //3 Votls supply set to off state

  Serial.begin(9600);
  mp3.begin(); //Start communication with the DFplayer module
  uint16_t volume = mp3.getVolume(); //Get actual volume
  mp3.setVolume(30); //Set new volum (max is 30)
  uint16_t count = mp3.getTotalTrackCount(); //Get the total tracks on the SD card in case we want to sue this later...
}

//just a fucntion that we use to create delays in "ms"
//without using the delay() function
void waitMilliseconds(uint16_t msWait)
{
  uint32_t start = millis();

  while ((millis() - start) < msWait)
  {
    // calling mp3.loop() periodically allows for notifications
    // to be handled without interrupts
    mp3.loop();
    delay(1);
  }
}

void loop()
{

  if (digitalRead(sw1) == LOW)
  {
    mp3.playMp3FolderTrack(1); // Play audio track 0001
    waitMilliseconds(5000); // 1s of delay
    while (digitalRead(sw1) == HIGH); // do nothing until state changes

  }

  if (digitalRead(sw2) == LOW)
  {
    mp3.playMp3FolderTrack(2); // Play audio track 0002
    waitMilliseconds(5000); // 1s of delay

    while (digitalRead(sw2) == HIGH); // do nothing until state changes

  }

  if (digitalRead(sw3) == LOW)
  {
    mp3.playMp3FolderTrack(3); // Play audio track 0002
    waitMilliseconds(5000); // 1s of delay

    while (digitalRead(sw3) == HIGH); // do nothing until state changes
  }
}
```

title: If and while statements not working

Answers: 1

body:
After pressing `sw1`, the first `if` works. After releasing `sw1` (it's a push button), the line `while (digitalRead(sw1) == HIGH);` will make the code just sit there forever without continuing with the rest of the code until you press `sw1` again, which will be caught by the first `if` unless you release 'sw1' inhumanly fast.

So, once you have pressed and released `sw1`, the rest of the code with the next two `if`s will never run.


body:
I've seen other posts on this board which related to output from the LM35 sensor, but mine seem to be more 'extreme' than anything else I've seen.

I've connected the pins as is commonly suggested - left hand to 5v, middle A0, and right to GRN and used the folowing code

<!-- language: lang-cpp -->

    const int sensorPin = A0;

    float sensorValue;
    float voltageOut;

    float temperatureC;
    float temperatureF;

    void setup() {

    pinMode(sensorPin, INPUT);
    Serial.begin(9600);

    }

    void loop() {

      sensorValue = analogRead(sensorPin);
      voltageOut = (sensorValue * 5000) / 1024;
      temperatureC = voltageOut / 10;

      Serial.print(sensorValue);
      Serial.print("\n");
      //Serial.print(temperatureC);
      //Serial.print("\n");

      delay(10000);
    }

I commented out the temperature printing lines to avoid the error being in the conversion.

Leaving it run for a while I get the following

    756.00
    0.00
    27.00
    7.00
    16.00
    64.00
    0.00
    0.00
    0.00
    6.00
    82.00
    20.00
    10.00
    3.00
    38.00
    0.00
    73.00
    0.00
    78.00
    68.00
    0.00
    80.00
    0.00
    2.00
    29.00
    48.00
    10.00
    0.00
    23.00
    64.00
    27.00
    0.00
    79.00
    0.00
    0.00
    56.00
    60.00
    9.00
    0.00
    15.00
    82.00
    2.00
    2.00
    40.00
    76.00
    18.00
    43.00
    17.00
    74.00
    49.00
    21.00
    14.00
    0.00
    74.00
    0.00
    3.00
    81.00
    3.00
    55.00
    20.00
    0.00
    41.00
    72.00
    40.00
    0.00
    54.00
    27.00

Our house is fairly stable in temperature, and the sensor is in a location out of anything which could drastically alter the temperature.

If anybody can suggest a reason for this I'd be grateful.

title: Output from LM35 temperature sensor varies wildly

Answers: 0


body:
So my setup is:

A 12v DR7-12 battery is providing the power for the board through a DC buck converter set to 3.3V connected to the 3.3V pin of the esp8266.

I then am using pins D5 and D6 to control an L298N motor driver, which has it's 12V connected to the battery (not through the board), it's ground to the battery and the IN1 and IN2 pins connected to the D5 and D6 pins.

I've ended up with three dead ESP8266 boards, they heat up and become unresponsive but as far as I know, I'm not putting any power through the board am I? What am I doing wrong?!

title: NodeMCU ESP8266 burnt. What have I done fundamentally wrong here?

Answers: 0


body:
when I connect VCC pin to the 5V and GND to the GND on the Arduino MEGA, then sometimes the display glows and sometimes it doesn't. It kinda looks like some contacts are bad because it starts to work mostly when I move it somehow, but I'm sure the problem is not in contacts as they defintely touch.

I also measured voltage on the display and it showed correctly ~5V.

Where could be the problem? Thanks

//Edit

I am using those displays to build simple autopilot panel for MSFS20 using MobiFlight. There is not any code, you just have to define what pins you connected and that's it. But even if it turns on, then all the leds stay on.

There might be a problem since I soldered the pins into the display so I could damage the board, it's a cheap one from China. Is there a way how to test if it's a board problem?

title: Max7219 7-segment display not working

Answers: 0


body:
This part of my project is very hard for my brain to wrap around and comprehend. But basically I just need to go through every combination. For example:

If I have an array with 255 variables and I need to bruteforce all the combinations by 30's (0, 30, 60, 90) How would I go about doing that in a decently compact form? It's really brain hurting please help a noob out <3

Note: I'm making a universal IR Remote but if by chance I don't have the code then I can just change the mode to brute force it.

    volatile uint16_t IRCode[]={384,171,43,21,21,21,21,21,21,64,21,21,21,21,21,21,21,21,21,64,21,21,21,64,21,21,21,64,21,64,21,64,21,64,21,64,21,21,21,21,21,21,21,64,21,21,21,21,21,21,21,21,21,64,21,64,21,64,21,21,21,64,21,64,21,64}; // ProntoHex to uint16_t delete first 4 array numbers.
    volatile uint16_t MicrosPassed;
    volatile uint8_t ArraySeq;
    uint8_t LEDState;
    uint8_t SetMode=0;

    void setup() {
      Config();
      SendIRCode();
    }

    void loop() {

    }

    void SendIRCode() {
      if(LEDState==1) {
        TCCR1A&=63;
        LEDState=0;
      } else {
        TCCR1A|=192;
        LEDState=1;
      }
    }

    void Config() {
      DDRB|=10;
      ICR1=416;
      OCR1A=9983;
      TCCR1A=2;
      TCCR1B=24;
      TCCR1B|=1;
      TIMSK1=1;
    }

    ISR(TIMER1_OVF_vect) {
      MicrosPassed++;
      if(MicrosPassed==IRCode[ArraySeq]) {
        SendIRCode();
        MicrosPassed=0;
        ArraySeq++;
           }
    }

title: Multi-array number generation

Answers: 0


body:
### Background

In 2019, Microchip acquired Atmel and released several new AVR microcontrollers, including the Tiny-0 and Tiny-1 Series. On these mircocontrollers, traditional Atmel ICSP programming was not supported. Instead, they feature a new one-wire programming interface called *Unified Programming and Debug Interface (UPDI)*. The new hardware also made existing TTL-serial bootloader programming obsolete. Thus, one must use a native UPDI programmer to work with these microcontrollers, such as [pyupdi](https://github.com/mraardvark/pyupdi).

However, Optiboot's developers have subsquently developed a new version of the bootloader called [Optiboot_X](https://github.com/Optiboot/optiboot#Optiboot_X) and implemented the STK500 programming protocol on these new microcontrollers, allowing one to program these microcontrollers using the traditional TTL-serial bootloader approach, and it appears that the Arduino community has already supported them for a while, with [MegaCoreX](https://github.com/MCUdude/MegaCoreX) and [megaTinyCore](https://github.com/SpenceKonde/megaTinyCore), which was good news to me. Nevertheless, it seems that there's little resource beyond these prepackaged Arduino cores, in particular, there's almost no documentation on how to program them manually from the commandline.

### What I've already done

I designed a custom AVR development board based on the Atmel ATTiny1604 microcontroller, which is a member of the new Tiny-0 family. Due to technical considerations, it must be programmed via the serial port using the bootloader similar to a traditional Arduino, not UPDI (UPDI is only used to burn the bootloader).

To achieve this goal, I installed the latest version of binutils, GCC and an experimental patch to avr-libc, so the compiler is able to generate code targeting my microcontroller. Then, I compiled my personal Optiboot_X bootloader.

    $ git clone https://github.com/Optiboot/optiboot.git
    $ cd optiboot/optiboot/bootloaders/optiboot
    $ make -f Makefile.mega0 optiboot_attiny1604.hex UARTTX=A1 TIMEOUT=8 LED=A7 BAUD_RATE=57600 LED_START_FLASHES=10

    Using Compiler at: /home/user/code/optiboot/optiboot/bootloaders/optiboot/avr-gcc
    avr-gcc -g -Wall -Os -fno-split-wide-types -mrelax  -DWDTTIME=8  -DLED_START_FLASHES=10  -DLED=A7   -DUARTTX=A1 -DBAUD_RATE=57600       -Wl,-section-start=.text=0 -Wl,--section-start=.application=0x200 -Wl,--section-start=.version=0x1fe -Wl,--relax -nostartfiles -nostdlib  -mmcu=attiny1604 -o optiboot_attiny1604.elf optiboot_x.c
    avr-size optiboot_attiny1604.elf
       text    data     bss     dec     hex filename
        494       9       0     503     1f7 optiboot_attiny1604.elf
    avr-objdump -S  optiboot_attiny1604.elf > optiboot_attiny1604.lst
    avr-objcopy -j .text -j .data -j .version --set-section-flags .version=alloc,load -O ihex optiboot_attiny1604.elf optiboot_attiny1604.hex

Then I uploaded the Optiboot_X bootloader to the ATTiny1604 microcontroller via UPDI, using `pyupdi`.

    # set fuse BOOTEND
    $ pyupdi -d tiny1604 -c /dev/ttyUSB0 -fs 8:0x02

    # burn Optiboot_X
    $ pyupdi -d tiny1604 -c /dev/ttyUSB0 -f optiboot_attiny1604.hex

    # reset
    $ pyupdi -d tiny1604 -c /dev/ttyUSB0 -r

After burning the Optiboot_X via UPDI, I was able to see 10 pulses during power-on at A7 on my oscilloscope, indicating that Optiboot_X was alive.

Note: Technically the installation is not complete yet. Since UPDI and `/RESET` share the same pin, UPDI must be permanently disabled via fuse to allow programming via bootloader, but it means a nonfunctional bootloader can brick the chip. I decided to manually reset the chip by power cycling the board for now.

Next, I wrote a test program.

    $ cat blink.c

    #define F_CPU 20000000UL
    #include <avr/io.h>
    #include <util/delay.h>

    int main(void)
    {
        PORTB.DIRSET = 0b00000001;

        while(1) {
            PORTB.OUTSET = 0b00000001;
            _delay_ms(500);
            PORTB.OUTCLR = 0b00000001;
            _delay_ms(500);
        }
    }

And I compiled it.

    $ make
    avr-gcc -mmcu=attiny1604 -Wall -Os -o blink.elf blink.c
    avr-objcopy -j .text -j .data -j .rodata -O ihex blink.elf blink.hex

### Question

Now what? How do I upload `blink.hex` to the Optiboot_X on the microcontroller?

On a traditional Arduino, the command is something like...

    $ avrdude -C/etc/avrdude/avrdude.conf -v -patmega328p \
      -carduino -P/dev/ttyUSB0 -b38400 -D -Uflash:w:blink.hex:i

But this is not an ATMega328P and there's nearly zero documentation on the web, I have a lot of questions and I'm not sure how to proceed.

To begin with, in `man avrdude`, there's no mention of any Tiny0 or Tiny1 devices. What should the `-p` argument be? Also, do I need to use a patched version of `avrdude`? Do I need a customized `avrdude.conf`? If so, where can I find them?

title: How do I Upload a Program via Serial Port to an Optiboot_X-Enabled TinyAVR-0/1 Microcontroller using the Command Line?

Answers: 1

body:
After poking around in the git repository for a while, I've solved the problem. To work with these new TinyAVR-0/1 microcontrollers, a new version of `avrdude` is needed. Since `avrdude` hasn't made a stable release yet, it's necessary to build a new `avrdude` from source from SVN.

    $ svn co https://svn.savannah.nongnu.org/svn/avrdude/trunk avrdude
    $ cd avrdude/avrdude
    $ ./bootstrap
    $ mkdir build && cd build
    $ ../configure
    $ make
    $ make install

After installation, `/usr/local/bin/avrdude` and `/usr/local/etc/avrdude.conf` should be available. One can see that a bunch of new TinyAVR parts have been added...

    $ avrdude -p?

    Valid parts are:
      [...]
      t10      = ATtiny10
      t11      = ATtiny11
      t12      = ATtiny12
      t13      = ATtiny13
      t15      = ATtiny15
      t1604    = ATtiny1604
      t1606    = ATtiny1606
      t1607    = ATtiny1607
      t1614    = ATtiny1614
      t1616    = ATtiny1616
      t1617    = ATtiny1617
      t1634    = ATtiny1634
      t20      = ATtiny20
      t202     = ATtiny202
      t204     = ATtiny204
      t212     = ATtiny212
      t214     = ATtiny214
      t2313    = ATtiny2313
      t24      = ATtiny24
      t25      = ATtiny25
      t26      = ATtiny26
      t261     = ATtiny261
      t28      = ATtiny28
      t3214    = ATtiny3214
      t3216    = ATtiny3216
      t3217    = ATtiny3217
      t4       = ATtiny4
      t40      = ATtiny40
      t402     = ATtiny402
      t404     = ATtiny404
      t406     = ATtiny406
      t412     = ATtiny412
      t414     = ATtiny414
      t416     = ATtiny416
      t417     = ATtiny417
      t4313    = ATtiny4313
      t43u     = ATtiny43u
      t44      = ATtiny44
      t441     = ATtiny441
      t45      = ATtiny45
      t461     = ATtiny461
      t5       = ATtiny5
      t804     = ATtiny804
      t806     = ATtiny806
      t807     = ATtiny807
      t814     = ATtiny814
      t816     = ATtiny816
      t817     = ATtiny817
      t84      = ATtiny84
      t841     = ATtiny841
      t85      = ATtiny85
      t861     = ATtiny861
      t88      = ATtiny88
      t9       = ATtiny9
      [...]

To program the ATTiny1604, simply run...

    $ avrdude -C/usr/local/etc/avrdude.conf -v -pt1604 \
      -carduino -P/dev/ttyUSB0 -b57600 -D -Uflash:w:blink.hex:i

Don't forget to modify the `-b57600` argument to match the baud of your Optiboot_X build.

Lesson learned: When [RTFM](https://en.wikipedia.org/wiki/RTFM) is impossible, [use the source, Luke](https://wiki.c2.com/?UseTheSourceLuke)!

## Potential Problems

### avrdude: verification error; content mismatch

It's possible that `avrdude` successfully establishes communication with the board via the serial port, reads the correct device signature, then attempts to upload a program, but ultimately fails verification.

    $ avrdude -v -pattiny1604 -carduino -P/dev/ttyUSB0 -b57600 -D -Uflash:w:blink.hex:i

    Reading | ################################################## | 100% 0.00s

    avrdude: Device signature = 0x1e9425 (probably t1604)
    avrdude: reading input file "blink.hex"
    avrdude: writing flash (204 bytes):

    Writing | ################################################## | 100% 0.06s

    avrdude: 204 bytes of flash written
    avrdude: verifying flash memory against blink.hex:
    avrdude: load data flash data from input file blink.hex:
    avrdude: input file blink.hex contains 204 bytes
    avrdude: reading on-chip flash data:

    Reading | ################################################## | 100% 0.06s

    avrdude: verifying ...
    avrdude: verification error, first mismatch at byte 0x0000
             0x01 != 0x0c
    avrdude: verification error; content mismatch

Solution: In TinyAVR 0/1, the bootloader is located at the beginning of the flash memory, occupies the first 512 bytes. When compiling the program to be uploaded via the bootloader, the correct 512-byte text section offset must be specified. Otherwise, `avrdude` will attempt to program from 0x00, which is impossible, because it's the location of the bootloader. Upon readback, instead of your program, `avrdude` reads the bootloader, which triggers the verification failure in question (it's worth noticing that `0x01`, the first mismatched byte that triggers verification failure, is actually the first byte in the Optiboot_X binary code).

Instead of using...

    avr-gcc -mmcu=attiny1604 -Wall -Os -o blink.elf blink.c

Recompile your program with `

    avr-gcc -mmcu=attiny1604 -Wall -Os -o blink.elf blink.c \
    -Wl,--section-start=.text=0x200

    avr-objcopy -j .text -j .data -j .rodata -O ihex blink.elf blink.hex

And reupload it.

    $ avrdude -v -pattiny1604 -carduino -P/dev/ttyUSB0 -b57600 -D -Uflash:w:blink.hex:i

    avrdude: Device signature = 0x1e9425 (probably t1604)
    avrdude: reading input file "blink.hex"
    avrdude: writing flash (716 bytes):

    Writing | ################################################## | 100% 0.00s

    avrdude: 716 bytes of flash written
    avrdude: verifying flash memory against blink.hex:
    avrdude: load data flash data from input file blink.hex:
    avrdude: input file blink.hex contains 716 bytes
    avrdude: reading on-chip flash data:

    Reading | ################################################## | 100% 0.00s

    avrdude: verifying ...
    avrdude: 716 bytes of flash verified

    avrdude: safemode: Fuses OK (E:FF, H:FF, L:FF)

    avrdude done.  Thank you.

### avrdude: programmer type jtagice3_updi not found

It's possible that `avrdude` reports the following error...

    /usr/bin/avrdude -C/usr/local/etc/avrdude.conf -v -pattiny1604 -carduino -P/dev/ttyUSB0 -b38400 -D -Uflash:w:blink.hex:i

    avrdude: Version 6.3, compiled on Jul 24 2019 at 00:00:00
             Copyright (c) 2000-2005 Brian Dean, http://www.bdmicro.com/
             Copyright (c) 2007-2014 Joerg Wunsch

             System wide configuration file is "/usr/local/etc/avrdude.conf"
    avrdude: error at "/usr/local/etc/avrdude.conf:1091: programmer type jtagice3_updi not found
    avrdude: error reading system wide configuration file "/usr/local/etc/avrdude.conf"

Solution: You are trying to run an old version of `avrdude` with a new configuration file. Make sure the `avrdude` executable you are running is actually the up-to-date version compiled from the upstream SVN repository.


body:
I receive this message: "device signature 0x000000" when a try to burn the bootloader on a atmega328p-au (SMD) inserted on PCB
i am using arduino uno as isp i already uploaded the ArduinoISP sketch and i check "Arduino as ISP" as programmer  with "arduino nano" as board

i do not know what is the problem i tried to check the ISP wiring with the arduino uno and everything is alright
what i noticed is that when i remove the GND wire attached to ISP the pin13 of the arduino lights up when i connect it it lights off i do not know what to do
here is the full schematic [![enter image description here][1]][1]

  [1]: https://i.stack.imgur.com/3m2Tf.png
Thank you for helping me

title: device signature 0x000000 when burning bootloader

Answers: 0


body:
I'm using the Arduino framework on an ESP32 based board. The board has an SD card slot, but I'm not going to use it.

Anyway, I need to store somewhere the certificates. To the the firmware I've just hardcoded them into the code:

    const char *rootCABuff = \
    "-----BEGIN CERTIFICATE-----\n" \
    "MIIE0zCCA7ugAwIBAgIQGNrRniZ96LtKIVjNzGs7SjANBgkqhkiG9w0BAQUFADCB\n" \
    ...
    "hnacRHr2lVz2XTIIM6RUthg/aFzyQkqFOFSDX9HoLPKsEdao7WNq\n" \
    "-----END CERTIFICATE-----\n";

    const char certificateBuff[] = \
    "-----BEGIN CERTIFICATE-----\n" \
    "MIIDWTCCAkGgAwIBAgIUZXjPNnJFXMntXOki9BT+QmDFciUwDQYJKoZIhvcNAQEL\n" \
    ...
    "gGXtqlgPnenkZPTaBr9c8o+WjgQXFLM+Jwnw3/53dUI9zBcybTaptI63o3Ct\n" \
    "-----END CERTIFICATE-----\n";

    const char privateKeyBuff[] = \
    "-----BEGIN RSA PRIVATE KEY-----\n" \
    "MIIEpAIBAAKCAQEAuuKsFy98/xsJclnWo0d+qm8KImLEILB64BbH7WaYi3NnznLg\n" \
    ...
    "uHfBLQQDrA0HDRvYpAUNw/b2H4dpUK/nGM4FFVMP7V8RM2t2923nhQ==\n" \
    "-----END RSA PRIVATE KEY-----\n";

Of course this is not suitable for production where each unit will have a different set of certificates.
So wonder what is the best way to store them.

The obviously idea is into flash. So I tried to enhance my settings class, based upon the `Preferences` library. In the [official documentatio][1]n I read:

> String values are currently limited to 4000 bytes. This includes the null terminator. Blob values are limited to 508000 bytes or 97.6% of the partition size - 4000 bytes, whichever is lower.

But if I do something like this:

    Preferences prefs;
    prefs.begin("settings", false);
    Serial.println(prefs.freeEntries());

it return 460, even if I still have plenty of flash:

    Flash: [=======   ]  73.8% (used 967234 bytes from 1310720 bytes)

Is there another library more suitable to store such a data *that can be used* with `Preferences`?

  [1]: https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/storage/nvs_flash.html

title: ESP32: best way to embed certificates

Answers: 1

body:
I don't know what you need that `Preferences` thing for, but I would use SPIFFS/FAT anyway. Simply store the certificate in a file in flash and read that file when you need it. The required space is no problem as you can choose the size for file system in the partition table and also you can upload the file (there is a plugin in the arduino IDE for this purpose) after flashing the firmware, so having different certificates on individual devices is no problem.

I saw that you tagged the question with 'eeprom': the esp has no eeprom but emulates it with a blob in flash, so using any flash library is just as fine. The esp also supports wear-leveling, which makes using flash an even better option as the dedicated eeprom-partition, which was used in an older version of the sdk, would wear out orherwise. The "eeprom" is just there to be consistent with the use of other arduino's eeproms.


body:
I refer to the code from this page: http://www.toddholoubek.com/classes/pcomp/?page_id=58 :

    int ledPin = 13; // choose the pin for the LED
    int switchPin =2; // choose the input pin (for a pushbutton)
    int val = 0; // variable for reading the pin status
    int counter = 0;
    int currentState = 0;
    int previousState = 0;

    void setup() {
      pinMode(ledPin, OUTPUT); // declare LED as output
      pinMode(switchPin, INPUT); // declare pushbutton as input
      Serial.begin(9600);
    }

    void loop() {
      val = digitalRead(switchPin); // read input value
      if (val == HIGH) { // check if the input is HIGH (button released)
        digitalWrite(ledPin, HIGH); // turn LED on
        currentState = 1;
      }
      else {
        digitalWrite(ledPin, LOW); // turn LED off
        currentState = 0;
      }
      if(currentState != previousState) {
        if(currentState == 1) {
          counter = counter + 1;
          Serial.println(counter);
        }
      }
      previousState = currentState;
      delay(250);
    }

I do not have the Arduino device so couldn't test the result currently but am Interested to know if I omitted this line:

    if(currentState != previousState)

, using the command line

    if(currentState == 1) {
    counter = counter + 1;

only and lets say I using a FS-V21 fiber optic sensor to count the quantity of products of 1m long each and on a conveyer belt of speed 0.1m/s so the stat will be true of t=1/0.1=10second for each product.

Will the counter value increase one unit only for each product (happen on the transition edge only), or increase indefinitely in the 10 second duration?

title: What happen to the counter value if I do not input the statement (if previous state!=current state)

Answers: 2

body:
No, it will increment *as long as* there is a product and at the frequency your loop runs at. So, when the light is interrupted, it will count several objects within a second.

The line you want to ommit is very essential, it makes the sketch only detect edges rather than levels.

body:
Because of the line

```c++
delay(250);
```

towards the end of the `loop()` function it will count up once every quarter of a second all the time the "state" is 1.

That means over a 10 second period it will count 40 objects.


body:
I have a loop command reading temperature sensor data from 8 thermistors and are storing them as floats into an array. Instead of printing to Serial on each iteration, I would like to create a comma separated string of these values and send to serial (in one instance, versus 8). What would be the best way to do this? I have tried ```sprintf``` commands to no avail.

Thanks in advance!

*Edit:* I would like to also write this string of comma separated values to a MicroSD card slot so I am under the assumption that creating the string once and printing to Serial AND saving to MicroSD card is more efficient than 8 separate iterations

title: Float array to comma separated string

Answers: 2

body:
Basic Arduinos have no support for floating point in `sprintf` and related functions.

Instead you have to use `dtostrf()` to build up a string block by block.

However there is no benefit to building a string then outputting to serial "in one instance" compared to outputting the data a bit at a time.  Serial is slow. Very slow. When you "output" data to serial you aren't outputting data. You're merely putting the data into a buffer to be sent when it's possible.

In effect, by using multiple `Serial.print()` calls, you're building up the string to send in the Arduino's internal serial TX buffer.

By building the string first all you're doing is creating a buffer to copy data into a buffer to send it through serial. It's redundant, wasteful, and utterly pointless.

body:
Here's a sample program using sprintf() to convert some float data to ASCII in a buffer, format an output string containing that data into another buffer and print the result on the terminal. It's not quite as neat as
```
   "sprintf(buffer, "i=-, T=%f\n", i, Temp);
```
It takes three lines and two buffers but it gets the job done:

```
#include <Arduino.h>

float getTemp(void);

void setup()
{
   char tempBuf[10+1], outputBuf[50+1];

   // Open console
   Serial.begin(115200);

   // Print 20 successive temperatures to the terminal
   for( uint8_t i = 1;  i <= 20;  ++i){
      float Temp;

      Temp = getTemp();                 // get the next value
      dtostrf(Temp, 6, 2, tempBuf);     // Convert float to ASCII
      sprintf(outputBuf, "i=-, T=%s\n", i, tempBuf); // format the value for printing
      Serial.print(outputBuf);          // print the line to the terminal

      delay(1000L);
   }

}

// Function to return temperatures.
// STUB: The data is made-up.
float getTemp(void){
   static uint8_t n = 0;        // count of results returned

   return( (float)n++ * 1.7 );  // index 'n' times an arbitrary multiplier
}

void loop(void)
{
   ;
}

```


body:
I'm inspecting where the memory is used in an application which runs on Arduino. To my surprise, there are several locations where 100 to 200 bytes are consumed by simply calling a function. Example:

```cpp
void Dispatcher::processCommand() {
    ...
    displayMemory();
    this->process(this->instruction);
}

void Dispatcher::process(const Instruction &instruction) {
    displayMemory();
    if (instruction.length > 0) {
        ...
        return;
    }

    ErrorResponse::componentNotFound(instruction).output(this->serial);
    TerminationResponse(instruction.commandId, 0xFF).output(this->serial);
}
```

The first call to `displayMemory()` will report that there is 351 bytes left. The second one will tell that only 159 bytes remain (that is, 192 bytes less).

If I alter the body of the `process` function, the difference between the two memory reports vary. For instance, if I remove the two last lines, the difference drops from 192 bytes to 12 bytes.

I don't understand why this happens. I was thinking that between the moment I'm ready to call a function and a moment when the function starts, the memory should be used exclusively by the additional element in the call stack (the aforementioned 12 bytes maybe?) and the copying of the parameters passed by value (none here). Why is this not the case? What really happens under the hood?

title: What happens, memory-wise, when I call a function from another function?

Answers: 2

body:
The clue is in those last two lines:

```c++
    ErrorResponse::componentNotFound(instruction).output(this->serial);
    TerminationResponse(instruction.commandId, 0xFF).output(this->serial);
```

Let's tear them apart and see what they actually do.

```c++
ErrorResponse::componentNotFound(instruction).output(this->serial);
```

Call the static function `componentNotFound` with your `instruction`, then take the object that is returned, and call the `output()` method on it passing `this->serial` as a parameter.

The hint there is *take the object that is returned*.

`componentNotFound()` returns an object. That object has to be stored somewhere. That "somewhere" is on the stack.  And stack space is allocated during the function *preamble*.  That's the bit of code that runs at the start of the function allocating stack, pushing registers to the stack, etc.

The same happens in the second line:

```c++
TerminationResponse(instruction.commandId, 0xFF).output(this->serial);
```

Create a new `TerminationResponse` object and call the `output` method.

All that goes on the stack.

It's not the calling of the function that is using the memory, it's *what the function is doing that is using the memory*.

body:
A function's data-memory space is reserved on the stack when the function is called, and returned when the function returns. If that function1 calls another, function2, then function1's space remains on the stack and more space is reserved for function2 for the duration of its execution. When function2 returns to function1, function2's memory is released, and finally, when function1 returns, its memory is released.

Now in a little more detail:

When you call function1, the arguments you pass it are put on the stack. When control actually passes to function1, the instruction address following the call, where function1 should eventually return to, is put on the stack. If function1 needs data temporary data space (automatic variables), space for those is put on the stack. (Ditto for function2, if one is called from function 1; and so on.)

When each of those functions returns, their automatic data space (just the space, not the data!) and the return address are removed from the stack; the caller removes the space for the arguments it had pushed, and execution resumes immediately following the call.

The difference in usage you're seeing depending on the presence or absence of the last two lines of Dispatcher::process(), is the memory (arguments+return address+automatic data) used by those two functions.


body:
I am starting using Arduino and have very little to none experience coding. However, I have managed to code and understand how it works.

The problem that I have is that I am unable to log (record) data from the three sensors attached (Adafruit Anemometers). All of them work properly; the data file is created. However, there is no data (or time reference) being written on the file.
When I verify the code, it's approved...Therefore, it should work, right?.=/
Then, I uploaded code.

I am using an Arduino uno with an SD Logger shield (Data Logging Shield v1.0, from Deek-Robot(TM)), which uses a DS1307 RTC.

All comments are more than welcome!

Thanks in Advance

```
#include "SD.h"
#include <Wire.h>
#include "RTClib.h"

// A simple data logger for the Arduino analog pins
#define LOG_INTERVAL  60000 // mills between entries
#define ECHO_TO_SERIAL   0 // echo data to serial port
#define WAIT_TO_START    0 // Wait for serial input in setup()

// the digital pins that connect to the LEDs
#define redLEDpin 3
#define greenLEDpin 4

// The analog pins that connect to the sensors
#define Anemometer0           // analog 0
#define Anemometer1           // analog 1
#define Anemometer2           // analog 2

RTC_DS1307 RTC; // define the Real Time Clock object

//Setup Variables of Anemometers

//Anemometer0
const int sensorPin0 = A0; //Defines the pin that the anemometer output is connected to
int sensorValue0 = 0; //Variable stores the value direct from the analog pin
float sensorVoltage0 = 0; //Variable that stores the voltage (in Volts) from the anemometer being sent to the analog pin
float windSpeed0 = 0; // Wind speed in meters per second (m/s)

//Anemometer1
const int sensorPin1 = A1; //Defines the pin that the anemometer output is connected to
int sensorValue1 = 0; //Variable stores the value direct from the analog pin
float sensorVoltage1 = 0; //Variable that stores the voltage (in Volts) from the anemometer being sent to the analog pin
float windSpeed1 = 0; // Wind speed in meters per second (m/s)

//Anemometer2
const int sensorPin2 = A2; //Defines the pin that the anemometer output is connected to
int sensorValue2 = 0; //Variable stores the value direct from the analog pin
float sensorVoltage2 = 0; //Variable that stores the voltage (in Volts) from the anemometer being sent to the analog pin
float windSpeed2 = 0; // Wind speed in meters per second (m/s)

float voltageConversionConstant = .004882814; //This constant maps the value provided from the analog read function,
//which ranges from 0 to 1023, to actual voltage, which ranges from 0V to 5V
int sensorDelay = 1000; //Delay between sensor readings, measured in milliseconds (ms)

//Anemometer Technical Variables
//The following variables correspond to the anemometer sold by Adafruit but could be modified to fit other anemometers.

float voltageMin = .4; // Mininum output voltage from anemometer in mV.
float windSpeedMin = 0; // Wind speed in meters/sec corresponding to minimum voltage

float voltageMax = 2.0; // Maximum output voltage from anemometer in mV.
float windSpeedMax = 32; // Wind speed in meters/sec corresponding to maximum voltage

// for the data logging shield, we use digital pin 10 for the SD cs line
const int chipSelect = 10;

// the logging file
File logfile;

void error(char *str)
{
  Serial.print("error: ");
  Serial.println(str);

  // red LED indicates error
  digitalWrite(redLEDpin, HIGH);

  while(1);
}

void setup() {
  // put your setup code here, to run once:

  Serial.begin(9600);
  Serial.println();

#if WAIT_TO_START
  Serial.println("Type any character to start");
  while (!Serial.available());
#endif //WAIT_TO_START

  // initialize the SD card
  Serial.print("Initializing SD card...");
  // make sure that the default chip select pin is set to
  // output, even if you don't use it:
  pinMode(10, OUTPUT);

  // see if the card is present and can be initialized:
  if (!SD.begin(chipSelect)) {
    Serial.println("Card failed, or not present");
    // don't do anything more:
    return;
  }
  Serial.println("card initialized.");

  // create a new file
  char filename[] = "LOGGER00.CSV";
  for (uint8_t i = 0; i < 100; i++) {
    filename[6] = i/10 + '0';
    filename[7] = i + '0';
    if (! SD.exists(filename)) {
      // only open a new file if it doesn't exist
      logfile = SD.open(filename, FILE_WRITE);
      break;  // leave the loop!
    }
  }

  if (! logfile) {
    error("couldnt create file");
  }

  Serial.print("Logging to: ");
  Serial.println(filename);

  Wire.begin();
  if (!RTC.begin()) {
    logfile.println("RTC failed");
#if ECHO_TO_SERIAL
    Serial.println("RTC failed");
#endif  //ECHO_TO_SERIAL
  }

  pinMode(redLEDpin, OUTPUT);
  pinMode(greenLEDpin, OUTPUT);

   // If you want to set the aref to something other than 5v
  //analogReference(EXTERNAL);
}

void loop() {
  // put your main code here, to run repeatedly:

  DateTime now;

  // delay for the amount of time we want between readings
  delay((LOG_INTERVAL -1) - (millis() % LOG_INTERVAL));

  digitalWrite(greenLEDpin, HIGH);

  // log milliseconds since starting
  uint32_t m = millis();
  logfile.print(m);           // milliseconds since start
  logfile.print(", ");
#if ECHO_TO_SERIAL
  Serial.print(m);         // milliseconds since start
  Serial.print(", ");
#endif

  // fetch the time
  now = RTC.now();
  // log time
//logfile.print(); // seconds since 2000
  logfile.print(", ");
  logfile.print(now.year(), DEC);
  logfile.print("/");
  logfile.print(now.month(), DEC);
  logfile.print("/");
  logfile.print(now.day(), DEC);
  logfile.print(" ");
  logfile.print(now.hour(), DEC);
  logfile.print(":");
  logfile.print(now.minute(), DEC);
  logfile.print(":");
  logfile.print(now.second(), DEC);

#if ECHO_TO_SERIAL
  Serial.print(now.get()); // seconds since 2000
  Serial.print(", ");
  Serial.print(now.year(), DEC);
  Serial.print("/");
  Serial.print(now.month(), DEC);
  Serial.print("/");
  Serial.print(now.day(), DEC);
  Serial.print(" ");
  Serial.print(now.hour(), DEC);
  Serial.print(":");
  Serial.print(now.minute(), DEC);
  Serial.print(":");
  Serial.print(now.second(), DEC);
#endif //ECHO_TO_SERIAL

//Anemometer0
const int sensorPin0 = A0; //Defines the pin that the anemometer output is connected to
int sensorValue0 = 0; //Variable stores the value direct from the analog pin
float sensorVoltage0 = 0; //Variable that stores the voltage (in Volts) from the anemometer being sent to the analog pin
float windSpeed0 = 0; // Wind speed in meters per second (m/s)

//Anemometer1
const int sensorPin1 = A1; //Defines the pin that the anemometer output is connected to
int sensorValue1 = 0; //Variable stores the value direct from the analog pin
float sensorVoltage1 = 0; //Variable that stores the voltage (in Volts) from the anemometer being sent to the analog pin
float windSpeed1 = 0; // Wind speed in meters per second (m/s)

//Anemometer2
const int sensorPin2 = A2; //Defines the pin that the anemometer output is connected to
int sensorValue2 = 0; //Variable stores the value direct from the analog pin
float sensorVoltage2 = 0; //Variable that stores the voltage (in Volts) from the anemometer being sent to the analog pin
float windSpeed2 = 0; // Wind speed in meters per second (m/s)

float voltageConversionConstant = .004882814; //This constant maps the value provided from the analog read function,
//which ranges from 0 to 1023, to actual voltage, which ranges from 0V to 5V
int sensorDelay = 1000; //Delay between sensor readings, measured in milliseconds (ms)

//Anemometer Technical Variables
//The following variables correspond to the anemometer sold by Adafruit but could be modified to fit other anemometers.

float voltageMin = .4; // Mininum output voltage from anemometer in mV.
float windSpeedMin = 0; // Wind speed in meters/sec corresponding to minimum voltage

float voltageMax = 2.0; // Maximum output voltage from anemometer in mV.
float windSpeedMax = 32; // Wind speed in meters/sec corresponding to maximum voltage

  logfile.print(", ");
  logfile.print(A0);
  logfile.print(", ");
  logfile.print(A1);
  logfile.print(",");
  logfile.println(A2);

#if ECHO_TO_SERIAL
  Serial.print(", ");
  Serial.print(Anemometer0);
  Serial.print(", ");
  Serial.print(Anemometer1);
  Serial.print(",");
  Serial.println(Anemometer2);
#endif //ECHO_TO_SERIAL

  digitalWrite(greenLEDpin, LOW);
}
´´´

title: File created, but not logging data

Answers: 1

body:
Thanks for all your help. I managed to log data in the SD card including date and time. The new code is the following:

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

RTC_DS1307 rtc; // create local instances of library class objects

DateTime time;

File dataFile;

const int chipSelect = 10;

// Anemometer at 0.15 magl

const int sensorPinA0 = A0; //Defines the pin that the anemometer output is connected to
int sensorValue0 = 0; //Variable stores the value direct from the analog pin
float sensorVoltage0 = 0; //Variable that stores the voltage (in Volts) from the anemometer being sent to the analog pin
float WindSpeed0 = 0; // Wind speed in meters per second (m/s)

float voltageConversionConstant0 = .0048828125; //This constant maps the value provided from the analog read function, which ranges from 0 to 1024, to actual voltage, which ranges from 0V to 5V
// hence, this value corresponds to 5.00V/1024. Check https://forum.allaboutcircuits.com/threads/why-adc-1024-is-correct-and-adc-1023-is-just-plain-wrong.80018/
int sensorDelay0 = 60000; //Delay between sensor readings, measured in milliseconds (ms)

//Anemometer Technical Variables
//The following variables correspond to the anemometer sold by Adafruit but could be modified to fit other anemometers.

float voltageMin0 = .4; // Mininum output voltage from anemometer in mV.
float windSpeedMin0 = 0; // Wind speed in meters/sec corresponding to minimum voltage

float voltageMax0 = 2.0; // Maximum output voltage from anemometer in mV.
float windSpeedMax0 = 32; // Wind speed in meters/sec corresponding to maximum voltage

// Anemometer at 0.5 magl

const int sensorPinA1 = A1; //Defines the pin that the anemometer output is connected to
int sensorValue1 = 0; //Variable stores the value direct from the analog pin
float sensorVoltage1 = 0; //Variable that stores the voltage (in Volts) from the anemometer being sent to the analog pin
float WindSpeed1 = 0; // Wind speed in meters per second (m/s)

float voltageConversionConstant1 = .0048828125; //This constant maps the value provided from the analog read function, which ranges from 0 to 1024, to actual voltage, which ranges from 0V to 5V
// hence, this value corresponds to 5.00V/1024. Check https://forum.allaboutcircuits.com/threads/why-adc-1024-is-correct-and-adc-1023-is-just-plain-wrong.80018/
int sensorDelay1 = 1000; //Delay between sensor readings, measured in milliseconds (ms)

//Anemometer Technical Variables
//The following variables correspond to the anemometer sold by Adafruit but could be modified to fit other anemometers.

float voltageMin1 = .4; // Mininum output voltage from anemometer in mV.
float windSpeedMin1 = 0; // Wind speed in meters/sec corresponding to minimum voltage

float voltageMax1 = 2.0; // Maximum output voltage from anemometer in mV.
float windSpeedMax1 = 32; // Wind speed in meters/sec corresponding to maximum voltage

// Anemometer at 1.2 magl

const int sensorPinA2 = A2; //Defines the pin that the anemometer output is connected to
int sensorValue2 = 0; //Variable stores the value direct from the analog pin
float sensorVoltage2 = 0; //Variable that stores the voltage (in Volts) from the anemometer being sent to the analog pin
float WindSpeed2 = 0; // Wind speed in meters per second (m/s)

float voltageConversionConstant2 = .0048828125; //This constant maps the value provided from the analog read function, which ranges from 0 to 1024, to actual voltage, which ranges from 0V to 5V
// hence, this value corresponds to 5.00V/1024. Check https://forum.allaboutcircuits.com/threads/why-adc-1024-is-correct-and-adc-1023-is-just-plain-wrong.80018/
int sensorDelay2 = 60000; //Delay between sensor readings, measured in milliseconds (ms)

//Anemometer Technical Variables
//The following variables correspond to the anemometer sold by Adafruit but could be modified to fit other anemometers.

float voltageMin2 = .4; // Mininum output voltage from anemometer in mV.
float windSpeedMin2 = 0; // Wind speed in meters/sec corresponding to minimum voltage

float voltageMax2 = 2.0; // Maximum output voltage from anemometer in mV.
float windSpeedMax2 = 32; // Wind speed in meters/sec corresponding to maximum voltage

void setup() {
 Serial.begin(9600);
 while (!Serial) {;} // wait for serial port to connect.
 Serial.print("Initializing SD card...");
 if (!SD.begin(chipSelect)) {
 Serial.println("Card failed, or not present");
 while (1); // loop forever
 }
 Serial.println("Have SD card");
 rtc.begin();
}

void loop() {

sensorValue0 = analogRead(A0); //Get a value between 0 and 1023 from the analog pin connected to the anemometer
sensorValue1 = analogRead(A1); //Get a value between 0 and 1023 from the analog pin connected to the anemometer
sensorValue2 = analogRead(A2); //Get a value between 0 and 1023 from the analog pin connected to the anemometer

sensorVoltage0 = sensorValue0 * voltageConversionConstant0; //Convert sensor value to actual voltage
sensorVoltage1 = sensorValue1 * voltageConversionConstant1; //Convert sensor value to actual voltage
sensorVoltage2 = sensorValue2 * voltageConversionConstant2; //Convert sensor value to actual voltage

//Convert voltage value to wind speed using range of max and min voltages and wind speed for the anemometer
if (sensorVoltage0 <= voltageMin0){
WindSpeed0 = 0; //Check if voltage is below minimum value. If so, set wind speed to zero.
}

else {
  WindSpeed0 = (sensorVoltage0 - voltageMin0)*windSpeedMax0/(voltageMax0 - voltageMin0); //For voltages above minimum value, use the linear relationship to calculate wind speed on A0.
    }

if (sensorVoltage1 <= voltageMin1){
WindSpeed1 = 0; //Check if voltage is below minimum value. If so, set wind speed to zero.
}

else {
  WindSpeed1 = (sensorVoltage1 - voltageMin1)*windSpeedMax1/(voltageMax1 - voltageMin1); //For voltages above minimum value, use the linear relationship to calculate wind speed on A1.
    }

if (sensorVoltage2 <= voltageMin2){
WindSpeed2 = 0; //Check if voltage is below minimum value. If so, set wind speed to zero.
}

else {
  WindSpeed2 = (sensorVoltage2 - voltageMin2)*windSpeedMax2/(voltageMax2 - voltageMin2); //For voltages above minimum value, use the linear relationship to calculate wind speed on A2.
    }

 time = rtc.now(); // Read RTC
 String dataString = ""; // Assemble data

log:
 dataString = time.timestamp(DateTime::TIMESTAMP_DATE);
 dataString += ", ";
 dataString += time.timestamp(DateTime::TIMESTAMP_TIME);
 dataString += ", ";
 dataString += String(sensorVoltage0);
 dataString += ", ";
 dataString += String(WindSpeed0);
 dataString += ", ";
 dataString += String(sensorVoltage1);
 dataString += ", ";
 dataString += String(WindSpeed1);
 dataString += ", ";
 dataString += String(sensorVoltage2);
 dataString += ", ";
 dataString  += String(WindSpeed2);
 dataFile = SD.open("Speedlog.txt", FILE_WRITE);
 if (dataFile) { // Write to logfile

 dataFile.println(dataString);
 dataFile.close();
 Serial.println(dataString);
 delay(1000); // pause for one second between sensor logs
 }
 else {
 Serial.println("error opening datalog.txt");
 }
}
```


body:
I am trying to save a string/char to EEPROM with `EEPROM.put()` and then get the value, but it doesn't work and I get a blank value when I do a `EEPROM.get()`.
I remember this is how it worked on **arduino nano**, but now I am trying with an **ESP32 board**, do they work different ?

```
#include <EEPROM.h>

char my_string[8];

void setup() {

  Serial.begin(115200);

// I am writing by this code, then comment it out to try to read from EEPROM
/*
    my_string[0] = 'S';
    my_string[1] = 'N';
    my_string[2] = '-';
    my_string[3] = 'A';
    my_string[4] = 'B';
    my_string[5] = 'C';
    my_string[6] = 'D';

  EEPROM.put(0, my_string);
*/

  EEPROM.get(0, my_string);

  Serial.println("data is: ");
  Serial.println((char*)my_string);
}

void loop() { }
```

title: Why isn't this EEPROM.get() working?

Answers: 1

body:
EEPROM can't store string. It stores numbers.  `put()` takes a type and stores that type as numbers.

The `char[]` isn't a string - it's a number. More specifically it's a memory address for where the string data is stored.

All you're doing is storing that memory address, not the data itself.

Instead you need to iterate over your string. You should also store the length of the string if it's going to be variable.

For example:

```c++

void storeString(const char *str) {
    EEPROM.write(0, strlen(str)); // Store the string length
    for (int i = 0; i < strlen(str); i++) {
        EEPROM.write(i + 1, str[i]);
    }
}

void getString(char *str) {
    int len = EEPROM.read(0);
    for (int i = 0; i < len; i++) {
        str[i] = EEPROM.read(i + 1);
    }
}
```


body:
I designed a custom AVR development board using the Atmel ATTiny1604 microcontroller. It belongs to the new Tiny-0 family, due to its recentness, some required changes to relevant toolchains have yet to be included into the stable version  (I prefer to use the original upstream toolchains instead of Atmel/Microchip's SDK). Thus, I compiled the latest versions of toolchains from source. They include...

* AVR GCC 10.2.0

* avr-libc, svn trunk, with [patch `avrxmega3-v10.diff`](https://savannah.nongnu.org/patch/?9543) applied

After I installed the toolchains, I wrote a LED blinking program to verify whether my toolchain was working properly. The program was built with `avr-gcc -mmcu=attiny1604 -Wall -Os -o blink.elf blink.c -Wl,--section-start=.text=0x200` and [uploaded via the Optiboot_X bootloader](https://arduino.stackexchange.com/questions/79136/how-do-i-upload-a-program-via-serial-port-to-an-optiboot-x-enabled-tinyavr-0-1-m/79137#79137).

    #define F_CPU 20000000UL
    #include <avr/io.h>
    #include <util/delay.h>

    int main(void)
    {
        PORTB.DIRSET = 0b00000001;

        while (1) {
            PORTB.OUTSET = 0b00000001;
            _delay_ms(500);
            PORTB.OUTCLR = 0b00000001;
            _delay_ms(500);
        }
    }

However, I found that `_delay_ms(500)` doesn't work as expected. Instead of a 500-millisecond delay, the actual delay is closer to 3000 milliseconds as seen on the oscilloscope, it has been slowed down by a factor of 6.

[![Oscilloscope screenshot showing the delay is slowed down by a factor of 6, instead of 500 ms, it's 3000 ms.][1]][1]

I've double-checked my fuse settings.

    $ pyupdi -d tiny1604 -c /dev/ttyUSB0 -fr
    Device info: {'family': 'tinyAVR', 'nvm': 'P:0', 'ocd': 'D:0', 'osc': '3', 'device_id': '1E9425', 'device_rev': '0.0'}
    Fuse:Value
    0:0x00
    1:0x00
    2:0x02
    3:0xFF
    4:0x00
    5:0xF6
    6:0x07
    7:0x00
    8:0x02
    9:0xFF
    10:0xC5

I saw `pyupdi` reported that the fuse `OSCCFG` (No. 2) has been programmed to `0x02`, which according to the datasheet, means "Run at 20 MHz with corresponding factory calibration". Why do I get incorrect delays even when the system clock is running at the correct speed? Is my toolchain broken?

**Note: This is a question I already solved. But consider there are relatively few tutorials about the new TinyAVR 0/1 on the web, I posted the question and answer here to serve as a reference for the community.**

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

title: _delay_ms() is much slower than expected (by a factor of 6) on TinyAVR 0/1 (ATTiny1604)

Answers: 1

body:
Your toolchain is not broken. In the [ATTiny804/1604 datasheet](https://ww1.microchip.com/downloads/en/DeviceDoc/ATtiny804_1604-Data-Sheet-40002028A.pdf), page 77, it shows the CPU clock is divided from the 20/16 MHz oscillator by a prescaler (the [ATTiny1614 datasheet](https://ww1.microchip.com/downloads/en/DeviceDoc/ATtiny1614-data-sheet-40001995A.pdf) shows the same clock prescaler in page 80. So it's a feature found in both tinyAVR 0/1 microcontrollers).

[![Main Clock and Prescaler][1]][1]
Source: Microchip ATTiny804/1604 datasheet, fair use.

The datasheet says...

> **10.3.3 Main Clock After Reset** After any Reset, `CLK_MAIN` is provided by the 16/20 MHz Oscillator (`OSC20M`) and **with a prescaler division factor of 6**. Since the actual frequency of the `OSC20M` is determined by the Frequency Select bits (`FREQSEL`) of the Oscillator Configuration fuse (`FUSE.OSCCFG`), these frequencies are possible after Reset:
>
> * 16 MHz ---> 2.66 MHz
> * 20 MHz ---> 3.3 MHz

By default, the division factor is 6. It means the CPU is actually running at 3.333 MHz when the `OSCCFG` fuse is programmed to 20 MHz.

## Solution

### Use the correct `F_CPU`

If a slower CPU is not a problem to you, you can simply report the correct CPU frequency to the compiler by change `#define F_CPU 20000000UL` to `#define F_CPU 3333333UL`.

### Or disable frequency division

Alternatively, you can disable the frequency division and run the CPU at its 20 MHz full speed.

    #define F_CPU 20000000UL

    int main(void)
    {
        /* Set CPU clock to 20 MHz */
        _PROTECTED_WRITE(CLKCTRL_MCLKCTRLB, 0);

        /* your code */
    }

### But don't overclock the CPU

Nevertheless, you should note that 20 MHz operation is only guaranteed by Atmel at 4.5 V and above. If you are running the microcontroller at a lower voltage, such as 3.3 V, you are overclocking the CPU by putting it outside the safe operating area designated by Atmel. See datasheet page 473.

[![Safe Operating CPU clock vs Voltage][2]][2]
Source: Microchip ATTiny804/1604 datasheet, fair use.

Although an overclocked microcontroller will probably work, and in a hobby project, you are unlikely to see any issue. But still, at this point there is no guarantee of stability from the manufacturer. For example, the microcontroller is officially rated at 105°C, but an overclocked microcontroller may start crashing. Increased power consumption is also likely. The worst possible problem could be mysterious malfunction under certain rare conditions. Thus, if reliability and stability is important, you should not overclock the microcontroller.

At 3.3 V, given a 20 MHz system clock, the CPU should only operate at 10 MHz by setting the prescaler to 2x. And at 1.8 V, at 5 MHz with a 4x prescaler.

    /* Set CPU clock to 10 MHz */
    _PROTECTED_WRITE(CLKCTRL_MCLKCTRLB,
                     CLKCTRL_PDIV_2X_gc | CLKCTRL_PEN_bm);

    /* Set CPU clock to 5 MHz */
    _PROTECTED_WRITE(CLKCTRL_MCLKCTRLB,
                     CLKCTRL_PDIV_4X_gc | CLKCTRL_PEN_bm);

  [1]: https://i.stack.imgur.com/fDcZ7.png
  [2]: https://i.stack.imgur.com/ZDJGw.png


body:
I have two function implementations that I expected to work the same:

```
#define HEAD_STEP_DELAY 1000
unsigned long HeadLastMicros;
void HeadUpdate()
{
    if ((micros()>=HeadLastMicros) && ((micros()-HeadLastMicros)<HEAD_STEP_DELAY)) {
        return;
    }
    HeadLastMicros = micros();
    HeadStep(true);
}
```

and

```
#define HEAD_STEP_DELAY 1
unsigned long HeadLastMillis;
void HeadUpdate()
{
    if ((millis()>=HeadLastMillis) && ((millis()-HeadLastMillis)<HEAD_STEP_DELAY)) {
        return;
    }
    HeadLastMillis = millis();
    HeadStep(true);
}
```

I know that the resolution of `micros()` is limited to about 8us, but I figure given that I have a 1000us wait, both of the above ought to be relatively close to the same behavior. I'm driving a stepper motor from this code, and the stepper that used `micros()` was behaving erratically. I haven't put the scope on it yet, so I don't know for sure, but the torque was significantly less (motor stalled easily) and it sounded wonky.

I'm using an ATMEGA324A together with the MightyCore library.

Is there anything wrong with my approach? Thanks.

EDIT: I did put the scope on it after my initial post, and the period of the micros() code is approximately half the period of the millis() code.

title: Issue using micros() instead of millis()

Answers: 1

body:
First off, when dealing with a time system that wraps around, don't compare two times.  Compare the differences.

Second, cache your function call results if you are going to use it more than once.

Third, if you want a consistent time interval, ask for it.  Your current micros() based code could well take 1990µs on some iterations and 1001µs on others.

Fourth, don't use the current time more than once...

Do something like (not specifying millis() or micros()):
```
unsigned long HeadLast; /* This should be initialized somewhere (HeadStart()?),
                           as otherwise things could go weird.
                           On the Arduino platform, initializing to 0
                           may work.  On other systems, time can start anywhen.
                           This caused Microsoft Windows to have trouble after
                           being up for 49 days (started at 0), while X Windows
                           has no such issue (start anywhen).
                           */
void HeadUpdate()
{
    /* compile with -O and this will optimize to a register. */
    unsigned long now = get_time_function();

    /* We don't need to test now >= HeadLast, as time is monotonic. */
    if ((now-HeadLast)<HEAD_STEP_DELAY)) {
        return;
    }
    /* Select the time we consider this to have started at.
       This may well be before the current time. */
    HeadLast += HEAD_STEP_DELAY;
    HeadStep(true);
}
```


body:
I am trying to interface a Arduino Uno with an ASM330LHH using SPI. Whenever I try to read any register, I either get 0xff or 0x00 on the serial monitor

The code I am using:
```
#include <SPI.h>

#define LOOP_DELAY 1000 //ms
uint8_t data;

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

  /* Refer datasheet for ASM330LHH
   * SPI freq max 10MHz
   * MSB first
   * SPI mode 3
   */
  SPI.begin();
  SPI.beginTransaction(SPISettings(1000000, MSBFIRST, SPI_MODE3));

  pinMode(10, OUTPUT);
  digitalWrite(10, HIGH);
  Serial.println("Setup complete!");

}

void loop() {
  digitalWrite(10, LOW);
  byte masked_addr = 0x0F | 0x80;
  Serial.println(masked_addr, BIN);

  SPI.transfer(masked_addr);
  data = SPI.transfer(0x00);
  Serial.println(data, BIN);
  digitalWrite(10, HIGH);
  delay(LOOP_DELAY);
}
```

The output I get:
```
10001111
11111111
10001111
11111111
10001111
0
10001111
0
```
The expected output for the above code is 0x6B. What might have gone wrong?

Thanks in advance

title: SPI register read returns 0x00 or 0xff

Answers: 0


body:
I have a 12 VDC pump, 8.5A, connected to a MOSFET transistor PSMN5R6-100PS,127.

The connection from the transistor to transformer, pump and a ESP32:

1    Gate   --> port to ESP32

2    Drain  --> (-) pump

3    Source --> Gnd ESP32, (-) transformer

(+) transformer to (+) pump

This is, as I understand it, how it ought to work. But with this configuration it doesn't...
But changing **3    Source --> (-) transformer**, removing the Gnd connection to the ESP32, then it works. It, however, seems to be some kind of leakage in terms of current because the pump has a "clucking" sound, not fully activating, just making a sound. Sometimes it doesn't work at all, where a reset makes it work again. Any ideas how I can fix it reliably?

title: Unreliable function of transistor, pump and ESP32

Answers: 1

body:
As can be seen from [the datasheet for the PSNB5R6](https://assets.nexperia.com/documents/data-sheet/PSMN5R6-100PS.pdf) (Fig 7) at 3.3V the MOSFET is barely even beginning to switch on.

You need to select a more suitable MOSFET that switches on fully at a voltage well below 3.3V, such as the [STP40NF04L](https://uk.farnell.com/stmicroelectronics/stp40nf03l/mosfet-n-to-220/dp/9803149).


body: I want to send message NRF24L01 to NRF24L01. I want to see if I can send just one second. How can I stop code after 1 second?

title: how can I stop my Arduino code after 1 second?

Answers: 1

body:
You can use different ways:

**Use `setup` only**

Instead of putting code in the `loop` function,  put it in `setup`, which is only executed once (use a `for` loop to send around 1 second.

**`millis()` excluding `setup`**

It is better to use the `millis` function and compare it against the start of sending; when 1 second is reached, don't send anything or use an infinite `while` loop.

Use something like:

    unsigned long time_start;

    void setup()
    {
        // Your normal code

        time_start = millis();
    }

    void setup()
    {
        if (millis() - time_start >= 1000)
        {
            while(1) {};
        }

        // your normal code (which should not take many ms,
        // otherwise the above code is not reached.

**millis() including `saetup`** (Thanks to Edgar Bonnet):

     void loop()
     {
         if (millis() >= 1000)
         {
            while(1) {};
         }
     }

This will stop exactly after 1 s  after startup (excluding the `setup`). It will start counting after `millis` start counting, which is before the `setup` function.

Actually, in none of the above the Arduino 'stops', it just is doing endlessly nothing (well internally endlessly checking against the `true` condition which never changes).


body:
I'm new to using Arduino, and know next to nothing about programming. I'm currently trying to add a potentiometer, and possibly a few more button inputs to my [3D-printed guitar controller project](https://i.stack.imgur.com/fVsM6.jpg)

It uses an Arduino Pro Micro, the code is just an example file [from this joystick library](https://github.com/MHeironimus/ArduinoJoystickLibrary) that I mostly just played around with using trial and error, and [this pinout diagram from Sparkfun](https://cdn.sparkfun.com/assets/9/c/3/c/4/523a1765757b7f5c6e8b4567.png), with this being what I ended up with:

```
#include <Joystick.h>

Joystick_ Joystick;

void setup() {
  // Initialize Button Pins
  pinMode(0, INPUT_PULLUP);
  pinMode(1, INPUT_PULLUP);
  pinMode(2, INPUT_PULLUP);
  pinMode(3, INPUT_PULLUP);
  pinMode(4, INPUT_PULLUP);
  pinMode(5, INPUT_PULLUP);
  pinMode(6, INPUT_PULLUP);
  pinMode(7, INPUT_PULLUP);
  pinMode(8, INPUT_PULLUP);
  pinMode(9, INPUT_PULLUP);
  pinMode(10, INPUT_PULLUP);

  // Initialize Joystick Library
  Joystick.begin();
}

// Constant that maps the phyical pin to the joystick button.
const int pinToButtonMap = 0;

// Last state of the button
int lastButtonState[11] = {0,0,0,0,0,0,0,0,0,0,0};

void loop() {

  // Read pin values
  for (int index = 0; index <= 10; index++)
  {
    int currentButtonState = !digitalRead(index + pinToButtonMap);
    if (currentButtonState != lastButtonState[index])
    {
      Joystick.setButton(index, currentButtonState);
      lastButtonState[index] = currentButtonState;
    }
  }

  delay(10);
}
```

This is the original example code that I used:

```
// Simple example application that shows how to read four Arduino
// digital pins and map them to the USB Joystick library.
//
// Ground digital pins 9, 10, 11, and 12 to press the joystick
// buttons 0, 1, 2, and 3.
//
// NOTE: This sketch file is for use with Arduino Leonardo and
//       Arduino Micro only.
//
// by Matthew Heironimus
// 2015-11-20
//--------------------------------------------------------------------

#include <Joystick.h>

Joystick_ Joystick;

void setup() {
  // Initialize Button Pins
  pinMode(9, INPUT_PULLUP);
  pinMode(10, INPUT_PULLUP);
  pinMode(11, INPUT_PULLUP);
  pinMode(12, INPUT_PULLUP);

  // Initialize Joystick Library
  Joystick.begin();
}

// Constant that maps the phyical pin to the joystick button.
const int pinToButtonMap = 9;

// Last state of the button
int lastButtonState[4] = {0,0,0,0};

void loop() {

  // Read pin values
  for (int index = 0; index < 4; index++)
  {
    int currentButtonState = !digitalRead(index + pinToButtonMap);
    if (currentButtonState != lastButtonState[index])
    {
      Joystick.setButton(index, currentButtonState);
      lastButtonState[index] = currentButtonState;
    }
  }

  delay(50);
}
```

I started this project in late February/early March, but only got to the Arduino part recently. I've had my v1 working for a little over a month using this code, and I've been working on the v2 design (adding a whammy bar and repositioning the start and select buttons) since then. I only just got to the point where I need to change the code last week.

From the comments in the example and some trial and error, I figured out that "const int pinToButtonMap = 9" is the lowest-numbered pin that it will use, and "for (int index = 0; index < 4; index++)" seems to determine the rest of the pins, so I changed 9 to 0, and "< 4" to "< 18" (the number of usable pins), and it kind of worked. Pins 0-10 and 14-16 now worked as button inputs, but button 14 (which would've been on pin 13, which doesn't exist on the Pro Micro) reads as constantly pressed, and pins A0-A3 (digital pins 18-21) don't read anything. If instead, I change it to "< 19", "< 20", etc. It just stops working completely, and if I change it to "< 11" or "<= 10" (my current code), all the pins from 0-10 work, and there are no phantom button presses

Also, I'm honestly not planning on learning any kind of real programming anytime soon. Maybe in the future, but for now, I just need enough to get this working with a 10k potentiometer (the same type that official Guitar Hero controllers use for their whammy bars) and possibly a few more button inputs (I might add a tilt sensor and maybe a D-pad in a future version)

title: How can I add a potentiometer and more buttons to my custom game controller?

Answers: 2

body:
It seems pins 11, 12 and 13 do not exist as input pins and pins 0 and 1 are used for RX/TX which you don't want to use neither probably.

So instead of using a `for` loop iterating over indices, you should create an array with pin numbers and use that instead, something like:

Create globally:

    int input_pins = { 2, 3, 4, 5, 6, 7, 8, 9, 10, 14, 15, 16, ... };

Use in `loop`:

    for (int index = 0; index < sizeof(input_pins) / sizeof(int); index++)
    {
        int currentButtonState = digitalRead(input_pins[index]);

You can use the same `for` to set the pin modes in the `setup`:

    for (int index = 0; index < sizeof(input_pins) / sizeof(int); index++)
    {
        pinMode(input_pins[index], INPUT_PULLUP);
    }

`sizeof(input_pins) / sizeof(int)` will give the amount of items within the array. You can now easily change it depending on the pin numbers.

I suggest you learn a bit of coding to at least understand what you change, it will make your life much easier as you progress.

In case you want more pins beyond the actual existing pins, you need to use a multiplexer like 74HC595; there are plenty examples how to use this.

body:
Beautiful work with the 3D-printed guitar!  You have already spent a lot of time and effort with the physical design and construction of the controller, so I recommend you plan on spending some quality time with basic Arduino programming, including the basic pin layout for the Pro Micro and the basics of programming in the Arduino language (basically C++)

You can find all you need to know in the example programs that come with the Arduino IDE (File -> Examples - 01.Basics) and with the many available tutorials (search for Arduino tutorial).  Here's one that seems to be pretty clear https://www.youtube.com/watch?v=QO_Jlz1qpDw

You'll also need to look at one of the many Arduino pinout diagrams for the Pro Micro, like this one https://learn.sparkfun.com/tutorials/pro-micro--fio-v3-hookup-guide/hardware-overview-pro-micro

From the diagram, it appears you can use pins 2-10 and 16-21 for digital I/0 (for your buttons), but you'll need to use one of 10, 18-21 for your potentiometer input.  So, as one other poster already noted, you should use an array of pin numbers and then read each pin by indexing into the array.

For the potentiometer interface, one of the supplied examples in '01.Basics' is the 'AnalogReadSerial' program, which should get you started.  To use this program, connect the center pin of a potientiometer to pin 18(A0), and the other two to VCC & GND. Upload the program to the Pro Micro, and you should get some console printouts that vary when you change the potientiometer setting.

Make your programs very small to start with - think of them as disposable snippets that will later be incorporated into the final program.  One snippet just for the potentiometer, and another snippet just for, say, 4 buttons that connect to pins 2, 9, 16 & 21 just to make sure your array indexing scheme works.  Then when all is working, the snippets can be combined into a 'final' (nothing is ever really final in the Arduino world).

And lastly, use serial 'print' statements liberally for test & debug; they will save you no end of trouble & frustration.  You can comment them out after all testing has been done, or just leave them in.  In most projects the Serial.print statements don't take up enough time or memory to matter.

Welcome to the Arduino world!  You'll love it!

Frank


body:
I'm writing a choose-your-own-adventure style project for a class project. My Arduino Uno is set up with a 16-digit LCD display and two pushbuttons with pulldown resistors. I'm wanting each function to display text on the LCD and then take two user inputs, Yes or No, from the pushbuttons, and then call another function respective of which input is pressed. Each successive function will also take the two inputs to then call the next function in the series, and so on.

My issue is that after the first time a pushbutton is pressed, its state does not change. When `question1()` is called, and the user presses `button1`, `question2` is called. However, the function runs and never waits for user input, and `question4` is called right away because the state of `button1` seemingly stays `HIGH` after the first time it is pressed.

What am I missing? Is there a better way to be gathering the user input? My pushbuttons are properly wired with the resistor pulling down to ground so my issue must be with my code.

Thanks in advance for any help.

```
void loop()
{
  question1();
}

void question1()
{
  button1State = digitalRead(9);
  button2State = digitalRead(8);
  if (q1 == false)
  {
    text1();
  }

  if (button1State == HIGH)
  {
    question2();
  }

  if (button2State == HIGH)
  {
    question3();
  }
}

void question2()
{
  button1State = digitalRead(9);
  button2State = digitalRead(8);
  if (q2 == false)
  {
    text2();
  }

  if (button1State == HIGH)
  {
    question4();
  }

  if (button2State == HIGH)
  {
    question5();
  }
}
```

title: Input state is stuck HIGH when function called using input also uses same input to call another function

Answers: 1

body:
There needs to be a `delay()` after the button state is read to allow time for it to return `LOW`, dumba**.

You already have enough `delay()` in your `textN()` functions, just check the button state *after* calling that function, not before. Code should be as follows:

```
void loop()
{
  question1();
}

void question1()
{
  if (q1 == false)
  {
    text1();
  }

  button1State = digitalRead(9);
  button2State = digitalRead(8);

  if (button1State == HIGH)
  {
    question2();
  }

  if (button2State == HIGH)
  {
    question3();
  }
}

void question2()
{
  if (q2 == false)
  {
    text2();
  }

  button1State = digitalRead(9);
  button2State = digitalRead(8);

  if (button1State == HIGH)
  {
    question4();
  }

  if (button2State == HIGH)
  {
    question5();
  }
}
```

This solves the issue completely.


body: I want to make a CNC machine that uses 5 NEMA 17 rated for 2A and a RAMPS 1.4 to control it all. I have a power supply that can deliver 1.5A at 12V. Is it enough? I am worried that when all 5 motors are under load, the amperage will get distributed and there will be very low amperage per motor.

title: DIY CNC Machine Power Requirements

Answers: 1

body:
Figuring out your current needs is simply a matter of adding everything up. If you have 5 2 amp motors, you'll need 5 x 2, or 10 amps just to drive the motors.

You should probably have at least 20% extra capacity, so I'd suggest having a 12V power supply that can put out at least 12A.

15A would be better.

The stiffer your power supply the less it will "bobble" as the load varies.


body: I'm fairly new to Arduino. I'm working on a project where I'm making HTTP requests using a python code and this lets me read and write to a JSON file on my desktop. I have an Arduino with sensors that records values and I want to take those recorded values and update them to the JSON file on my desktop in real-time. I looked online and many suggested using some Arduino library, but it was only for reading. I'm still confused about reading and writing to the JSON file on my desktop. I appreciate any help to guide me in the right direction. Thank you.

title: Reading and Writing to a JSON File on the Desktop from Arduino?

Answers: 1

body:
The Arduino cannot access files on a desktop computer.

However you can write software on your computer (you already use Python, so why not [use that?](https://pyserial.readthedocs.io/en/latest/)) to accept information over [Serial](https://www.arduino.cc/reference/en/language/functions/communication/serial/), process it, and store it in any way you like (including JSON), or return data from the computer to the Arduino if needed.


body:
I want to store a counter that is always changing, but I want it to remain and be able to retrieve it on after a power loss.

It's only one long number data, but as it is always changing, I don't know where to store it to not over wear the memory space.

I'm aware that writing to much on ESP's EEPROM or SPIFFS would damage it. I've seen [that post](https://arduino.stackexchange.com/questions/71606/spiffs-vs-eeprom-on-esp8266/79172#79172), but it doesn't help in my case.

The data to be saved is the volume of water pumped with a water pump during it's entire life.

Of course I could save it only once a while to reduce the number of writes, but I would lose some acccuracy.

title: Where to store critical data in power outage situation on ESP8266

Answers: 2

body:
If you worry about the maximum number of write cycles, you could write the data to an SD card or some [FRAM][1] connected to the ESP8266, or you could send the data to a (web) server (if you have access to one) using WiFi. The server can then store the data.

If you really care about the data, you could do both. Having a backup is the only protection against catastrophic failure.

  [1]: https://www.google.com/search?q=fram arduino&oq=fram arduino

body:
A local solution would be to use *EERAM*.  This is an EEPROM and an SRAM coupled together with some intelligent power management circuitry - writes get stored in SRAM until the power goes (or an instruction to save is sent) when the contents of SRAM get copied into EEPROM using the power stored in a large capacitor.

A good choice is the [47C16](https://www.microchip.com/wwwproducts/en/47C16) (5V) or [47L16](https://www.microchip.com/wwwproducts/en/47L16) (3.3V).


body:
I am trying to compile the following code:

    logger.log_info(F(R"(some text here that may take
        multiple lines
        and here it is done.)"));

But the compiler exists with the following error:

> error: unterminated raw string

I am able to use either `R` or `F`, but not both together. **How should I be able to use them together?**

title: Cannot compile F() macro with R"string"

Answers: 1

body:
If you put:

````
    #define DO_NOTHING(s) (s)

    DO_NOTHING(R"xyz(Hello
    World)xyz")
````

you can see g++ choke on preprocessing the raw string literal in the macro invocation with the latest esp8266 board package as of writing (version 2.7.4).  This comes with g++ 4.8.2 for xtensa.

```
    ~/.arduino15/packages/esp8266/tools/xtensa-lx106-elf-gcc/2.5.0-4-b40a506/bin/xtensa-lx106-elf-g++ -E  donothing.h
````
You may need to adjust the command-line for your system.  donothing.h is just the macro and invocation described above.

Result:

````
# 1 "donothing.h"
# 1 "<command-line>"
# 1 "donothing.h"

donothing.h:3:13: warning: missing terminating " character [enabled by default]
 DO_NOTHING(R"xyz(Hello
             ^
(R"xyz(Hello World)
donothing.h:4:10: warning: missing terminating " character [enabled by default]
 World)xyz")
          ^
      xyz")
````

This does not happen with g++ 9.3.0 on an amd64 Linux target.

As a workaround you can reconstruct (more or less) what the F() macro does with the following:

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

    void loop() {
      static const char pgm_str[] PROGMEM = (R"xyz(Hello
    World)xyz");

      Serial.println(FPSTR(pgm_str));
      delay(4000);
    }
````


body:
I can't seem to find the error I made; can anyone help me?

The error message: `'Servo_Pointer' was not declared in this scope`

I get the error at the end of the code with the line: `Servo_Pointer.write(servo_pos)`

The code:

    const int photo_left = A0;    // select the input pins for the photoresistor
    const int photo_right = A1;
    const int ledPin_1 = 2; // These leds will be used for the testing of the pointing of the servo motor
    const int ledPin_2 = 4;
    const int ledPin_3 = 7;
    const int ledPin_4 = 8;
    const int ledPin_5 = 12;
    const int photoValue = 0;  // variable to store the value coming from the photoresistor
    const int numReadings = 10;
    int readings[numReadings];      // the readings from the analog input
    int readIndex = 0;              // the index of the current reading
    int total = 0;                  // the running total
    int average = 0;                // the average

    void setup() {
      // declare the ledPin as an OUTPUT:
      pinMode(ledPin_1, OUTPUT);
      pinMode(ledPin_2, OUTPUT);
      pinMode(ledPin_3, OUTPUT);
      pinMode(ledPin_4, OUTPUT);
      pinMode(ledPin_5, OUTPUT);
      Serial.begin(9600);
      #include <Servo.h>
      Servo Servo_Pointer;
      Servo_Pointer.attach(9);
      int servo_pos = 0;
      // initialize serial communication with computer:
      Serial.begin(9600);
      // initialize all the readings to 0:
      for (int thisReading = 0; thisReading < numReadings; thisReading  ) {
        readings[thisReading] = 0;
      }
    }

    void loop() {
      Servo_Pointer.write(servo_pos); // tell servomotor to go to position in variable 'servo_pos'
      delay(15);          // waits 15ms for the servo to reach the position
      // turn the ledPin on
      delay(15);
    }

Answers: 2

body:
You should make `Servo Servo_Pointer;` global, i.e. place it outside the `setup`function, e.g. after the line `int average = 0;`.

In your code, it is a local variable within the `setup` function. When this function ends, the local variables within this function (such as `Servo_Pointer` ) do not exist anymore.

By making the variable global, you can use it anywhere. However, it's not a good coding practice to use global variables when not needed.

A benefit of making the variable global is that you can see the memory consumption of the instance of `Servo_Pointer` when compiling.

Also see the comment of timemage below: Don't put `#include` statements in the middle of your code, put them in the beginning of your code.

body:
You need to place the decleration outside of your `setup()` function. In other words, you need to move the following 3 lines and place then above your `setup()` function:

    #include <Servo.h>
    Servo Servo_Pointer;
    int servo_pos = 0;

Your code should look like this:

    #include <Servo.h>

    const int photo_left = A0;    // select the input pins for the photoresistor
    const int photo_right = A1;
    const int ledPin_1 = 2; // These leds will be used for the testing of the pointing of the servo motor
    const int ledPin_2 = 4;
    const int ledPin_3 = 7;
    const int ledPin_4 = 8;
    const int ledPin_5 = 12;
    const int photoValue = 0;  // variable to store the value coming from the photoresistor
    const int numReadings = 10;
    int readings[numReadings];      // the readings from the analog input
    int readIndex = 0;              // the index of the current reading
    int total = 0;                  // the running total
    int average = 0;                // the average
    int servo_pos = 0;

    Servo Servo_Pointer;

    void setup() {
      // declare the ledPin as an OUTPUT:
      pinMode(ledPin_1, OUTPUT);
      pinMode(ledPin_2, OUTPUT);
      pinMode(ledPin_3, OUTPUT);
      pinMode(ledPin_4, OUTPUT);
      pinMode(ledPin_5, OUTPUT);
      Serial.begin(9600);
      Servo_Pointer.attach(9);
      // initialize serial communication with computer:
      Serial.begin(9600);
      // initialize all the readings to 0:
      for (int thisReading = 0; thisReading < numReadings; thisReading  ) {
        readings[thisReading] = 0;
      }
    }

    void loop() {
      Servo_Pointer.write(servo_pos); // tell servomotor to go to position in variable 'servo_pos'
      delay(15);          // waits 15ms for the servo to reach the position
      // turn the ledPin on
      delay(15);
    }


body:
really noob question..

I am thinking of using a 12v power source and a 5v power source as an external power supply for my 5v relay (and some other stuff that I might add up to my project that will need 5V) and the 12v is for my 12V solenoids.
Is it right to connect all ground wires to the ground of the Arduino?
I am really sorry that I have to ask this question cause all tutorials I see online are only connecting one external power supply to their Arduino.

Any form of correction is highly appreciated. Thank you so much

title: Multiple external power sources and one Arduino

Answers: 1

body:
Besides connecting all the grounds, a "good idea" whenever working with solenoids or magnetic (as opposed to solid state) relays is to add protection against inductive kickback, which can create really high voltages (hundreds of volts) when the current through an inductor changes suddenly. (The voltage is the product of the inductance and the rate-of-change of the current.)  The protection is simple:  Put a rectifier diode across each coil, with the arrow pointing to positive (reverse-biased).  The rectifier has to handle a big spike of current as well as the high voltage, so use something like 1N4004.
This protection will reduce the likelihood of spikes causing mysterious state changes in your circuits.


body:
I am using win 8.1 and trying to load Marlin 2.0.x onto Arduino Mega with an attached Ramps 1.4 board fitted with 3 8825 Drivers. Unfortunately everytime I try to compile It concludes with the following error. Can anyone please help.

    Alternatives for utility/spi_com.h:
    []ResolveLibrary(utility/spi_com.h)  -> candidates: []In file included from C:\Users\Dad\AppData\Local\Temp\arduino_build_750275\sketch\src\HAL\STM32\MarlinSPI.cpp:23:0:C:\Users\Dad\AppData\Local\Temp\arduino_build_750275\sketch\src\HAL\STM32\MarlinSPI.h:28:12: fatal error: utility/spi_com.h:
    No such file or directory   #include <utility/spi_com.h>

    compilation terminated.
    Using library SPI at version 1.0 in folder: C:\Users\Dad\Downloads\arduino-1.8.13-windows\arduino-1.8.13\hardware\arduino\avr\libraries\SPI
    exit status 1
    Error compiling for board Arduino Mega or Mega 2560.

title: utility/spi_com.h error when compiling Marlin for Arduino mega with Ramps 1.4

Answers: 1

body:
> trying to load Marlin 2.0.x onto Arduino Mega

I have no specific knowledge of Marlin.

For the moment, I'm ignoring the fact that it seems to be looking for STM32 files which would seem to play no role on an Arduino Mega.

I cloned the Marlin github repo and found no mention of a file "MarlinSPI.h" in the 2.0.x branch.  There is however a MarlinSPI.h in tag 1.1.9.1

You appear to be working with the code for the wrong version (or branch) of Marlin.


body:
So I don't know C so I'm just trying to get some very very basic code running on my arduino to send it commands over serial.

I'm feeding serial into buf

irsend.sendNEC(0x210704FB, 32)

this works but I need to read from buf instead of hardcoding for one code.

irsend.sendNEC(buf, 32) won't compile but irsend.sendNEC((uint32_t) buf, 32) will. It just doesn't do anything.

When I use

serial.print((uint32_t) buf, 32);

it prints just seemingly random letters?

I'm trying to just feed it a serial code with a language I know a little better. I can send the hex code over serial with python but I don't know the first thing about C. I don't understand why I can't just feed it a variable and have it read it as is.
here's my code

```
#include <IRremote.h>

char buf[80];

int readline(int readch, char *buffer, int len) {
  static int pos = 0;
  int rpos;

  if (readch > 0) {
    switch (readch) {
      case '\r': // Ignore CR
        break;
      case '\n': // Return on new-line
        rpos = pos;
        pos = 0; // Reset position index ready for next time
        return rpos;
      default:
        if (pos < len-1) {
          buffer[pos++] = readch;
          buffer[pos] = 0;
        }
    }
  }
  return 0;
}

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

IRsend irsend;

void loop() {
  if (readline(Serial.read(), buf, 80) > 0) {
    //tried to set up code to show what the arduino received and tried ways to send
    //Serial.print("You entered: >");
    //Serial.print(buf);
    //Serial.println("<");
    //doesn't seem to do anything irsend.sendNEC((uint32_t) buf, 32);
    //works but only for this one button irsend.sendNEC(0x210704FB, 32);
    //want to use irsend.sendNEC(buf, 32);
    //me trying to figure out what irsend is being fed through buf Serial.print((uint32_t) buf, 32);

  }
}
```

title: Help using uint32_t? Trying to feed arduino serial from raspberry pi. Any help is very very much appreciated

Answers: 1

body:
Same issue for me, but this is my solution.

Mapping beween python struct (packed data) and arduino struct is as follows:

    Python              Arduino
    ?                   boolean
    i                   int32_t or uint32_t
    f                   float

Arduino Code:

    // The struct we want to send over the serial connection
    struct Data {
      int32_t timer;
      float value2;
      uint32_t sensor1;
      uint32_t datasize;
    };
     Data data;
    void setup() {
      // Initialize the serial connection
      Serial.begin(115200);
    }

    void loop() {
      // Create an instance of the Data struct

      data.timer = micros();
      data.value2 = 3.14;
      // read the input on analog pin 0:
      data.sensor1 = analogRead(A0);

      // Calculate the size of the struct in bytes
      size_t size = sizeof(data);
      data.datasize = size;
      // Allocate a buffer for the packed data
      uint8_t *buf = (uint8_t*)malloc(size);

      // Pack the data into the buffer
      memcpy(buf, &data, size);

      // Send the packed data over the serial connection
      Serial.write(buf, size);

      // Free the buffer
      free(buf);

      // Wait before sending the data again
      delay(10);

    }

Python Code:

    #
    # read struct from arduino / sample code above
    #

    import serial
    import struct

    # Open the serial port
    ser = serial.Serial('/dev/ttyUSB0', 115200)

    # The struct we expect to receive from the Arduino
    #struct Data {
    #  int32_t value1;
    #  float value2;
    #  uint32_t value3;
    #}
    expFormat = "i f i i"         # Format to match arduino struct
    structDataLength = struct.calcsize(expFormat)
    print(structDataLength)       # RESULT IS 12

    while True:
    # Read the data from the serial port
    # We read until we have received all the bytes for the struct

        data = b''
        while len(data) < structDataLength:
            data += ser.read(structDataLength - len(data))
        # Unpack the data into an instance of the Data struct
        val = struct.unpack('i f i i', data)

    # Print the values
        print(val)

    # Close the serial port
    ser.close()


body:
I've got a project in which I'll be controlling 8 24V/10A brushless DC motors with an Arduino Due on a quadrupedal robot. I've been having trouble finding ESCs that would work well for this application and was wondering if anyone could provide recommendations. My ideal ESC would be one with on-board PID control given an encoder. In looking around, I've only been able to find one [ESC with this capability][1] but lacked the power output these motors want.

A secondary question would be if it's reasonable to run 8 PID loops on the Due alongside its other tasks (primarily serial data receiving/transmitting). I feel like it might be too much for the Due to handle, but I wanted to get other's opinions on this.

Sidenote: I have enough of a gear reduction between motor and output shaft that fine movements should not be an issue.

  [1]: https://www.embention.com/product/motor-controller/

title: Brushless ESC Recommendations

Answers: 0


body:
I actually made a prototype with multiplexing Chip select pin on Arduino, which connects to RESET pin of target board to program. When I am connecting one target board at once I am able to program it but when I am connecting multiple target boards then not able to program ICs.

I am using Nick gammon's code for programming the target Arduino using the master Arduino
https://github.com/nickgammon/arduino_sketches/tree/master/Atmega_Hex_Uploader_Fixed_Filename

This is rough block diagram of multiplexing chip select pin -

[![block diagram of multiplexing chip select pin][1]][1]

I also tried connecting RESET pin of target Arduino to its chip select pin but that is also not working.

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

title: Programming multiple arduino at once

Answers: 0