message:
Arduino IDE not compile .S program to board

After answering my previous question correctly I'm getting all sorts of errors when trying to compile the following program:

I'm completely new to both assembly and the arduino IDE so I apologise in advance for any basic errors.

sketch.ino:

    #include "blink.S"
    extern void blink();
    void setup() {
      // put your setup code here, to run once:
    blink();
    }

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

    }

blink.S file:

    #define __SFR_OFFSET 0
    #include <avr/io.h>

      .section .text

      ldi r18, 0x20   ; loading 0x20 = 00100000 into register r18
      out DDRB, r18   ; making pin 5 of port B an output

      mov r16, r18    ; copy mask 00100000 also to r16

    loop: out PORTB, r16    ; switch on or off the pins of port B
            ; according to bit pattern in r16

      ldi r17, 82   ; 1000ms delay, see below

    outer_delay:
      clr r1
    middle_delay:
      clr r2
    inner_delay:
      dec r2      ; 1 clock tick
      brne inner_delay  ; 2 clock ticks when z!=0, 1 tick when z=0.

      dec r1      ; when this line is reached, about
            ; 256*3 = 768 ticks have been consumed since inner_delay.
      brne middle_delay ;

      dec r17                 ; when this line is reached, about
            ; 256*256*3 = 196608 ticks have been
            ; consumed since middle delay.
      brne outer_delay

      eor r16,r18   ; invert bit 5 in r16 using exclusive or.
      rjmp loop   ; jump back to loop.

body:
There's four things I can see wrong (one of which is my fault, actually - I should have mentioned it in the previous question - nevermind).

Firstly you cannot include a .S file in a .INO file. A .S file is assembly, a .INO file is C++. You can't mix the two in one file (and including a file does just that - includes the file verbatim at that point). So remove that `#include`. Otherwise it would be like opening a book written in English only to find the preface is written in Klingon.

Secondly you need to give your function a name. It doesn't have one at the moment. Naming the file is *not* naming the function.

So you need to provide a label at the entry point:

      .section .text

    blink:    ; << This is the name of the function
      ldi r18, 0x20   ; loading 0x20 = 00100000 into register r18
      out DDRB, r18   ; making pin 5 of port B an output

Third you need to export that name as a global symbol:

      .section .text
      .global blink ; << This exports the function name

    blink:    ; << This is the name of the function
      ldi r18, 0x20   ; loading 0x20 = 00100000 into register r18
      out DDRB, r18   ; making pin 5 of port B an output

And finally you have the problem of linkage name munging.  You're linking a C++ file with (ostensibly) a C file - and C++ munges names. So you have to tell your C++ file that the function is not a C++ function, but a C function (which is what I should have mentioned previously):

    extern "C" void blink(); // << Add the "C" to tell it not to munge the name

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

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


sender: user

sender: assistant

body:
A couple of things you can try.

First, make sure your assembly code makes the `blink()` function visible
to the linker. blink.S should start like this:

<!-- language: lang-asm -->

    #define __SFR_OFFSET 0
    #include <avr/io.h>

    .section .text
    .global blink
    blink:
      ; Your assembly code goes below the above label.

Next, your sketch file should not try to include the assembly source. It
should only reference it as an external symbol. And note that the symbol
should be declared `extern "C"`.

If your program is a mix of assembly and Arduino code, you could start
with this sketch.ino:

<!-- language-all: lang-c++ -->

    extern "C" void blink();

    void setup() {
        blink();
    }

    void loop() {}

If you are not using the Arduino core library, you could instead write:

    extern "C" void blink();

    int main(void)
    {
        blink();
        return 0;
    }

And if you don't want to use C++ at all, you could try to use a dummy or
empty sketch.ino, and rename “blink” to “main” in blink.S.


message:
Voltage divider for 6 non intrusive current sensors

I have an Arduino project where I intend to use 6 non intrusive current sensor model SCT013 (100A/50mA) manufactured by yhdc.com

As reference voltage on examples I find at the internet it is suggested the use of 2 10K resistor connected in series from 5V to ground, the reference voltage is extracted from the middle connection between the resistors (2.5v).

Question:

In the case of six sensors will I have to use 6 independent voltage dividers or can I use a single divider as reference for all sensors?

I am concerned the interference between sensors may cause reading imprecision.

Thanks in advance
Paulo

body:
I assume you refer to a circuit like this:

<!-- Begin schematic: In order to preserve an editable schematic, please
     don't edit this section directly.
     Click the "edit" link below the image in the preview instead. -->

![schematic](https://i.stack.imgur.com/gJpj1.png)

<!-- End schematic -->

The "reference" you speak of is not a reference - it is a *virtual ground*. A ground reference that is at a different potential to the Arduino - in this case 2.5V higher.

Since it is just the ground for the circuit you can use the same one for all the current transformers without problems.

If the offset voltage were applied to the output (as is often done for active devices that create an AC waveform, such as audio signals) then you would require a separate offset voltage for each one, since otherwise you would be connecting all the outputs together, which would be bad.

You can also "reverse" your thinking. The "offset" voltage you apply is ground, and the Arduino's "ground" is 2.5V *below* that. It's all relative.


message:
Can't flash ESP8266-01 with Sparkfun FTDI basic - wrong direction/command

Connections:
    RX -> TX
    TX -> RX
    GND -> GND
    VCC -> 3.3v
    CH_PD -> 3.3v
    GPIO0 -> GND (flash mode)

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

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

**Click the picture to make it larger/more readable.**

I am trying to flash an ESP8266-01 using a Sparkfun FTDI Basic. Above is my diagram. I am using a 16v max in to 3.3v out to handle the drop from my FTDI (5v) to the ESP8266 (3.3v). I am using a logic converter to change the 5v to 3.3v for the Rx/Tx. I have done this successfully (but with spotty results), flashing the ESP8266 with an Arduino Uno. Then I tried to reprogram the ESP8266 with my Arduino Uno and it kept giving me an error that ends with:

    warning: espcomm_sync failed
    error: espcomm_open failed
    error: espcomm_upload_mem failed
    error: espcomm_upload_mem failed

So I decided to troubleshoot by seeing if the problem was with my Uno, because it is fairly old - and I got an FTDI Basic - with the basic I get a little further - the whole output when I try to upload is:

    Archiving built core (caching) in: /var/folders/lv/lj7d61jn61x_8knqdhghk_pc0000gn/T/arduino_cache_244685/core/core_esp8266_esp8266_generic_CpuFrequency_80,FlashFreq_40,FlashMode_dio,UploadSpeed_115200,FlashSize_1M64,ResetMethod_ck,Debug_Disabled,DebugLevel_None_____4d67f8743716b2ecc4b09162f2cdb6e3.a
    Sketch uses 241193 bytes (25%) of program storage space. Maximum is 958448 bytes.
    Global variables use 35476 bytes (43%) of dynamic memory, leaving 46444 bytes for local variables. Maximum is 81920 bytes.
    /Users/eamonwhite/Library/Arduino15/packages/esp8266/tools/esptool/0.4.9/esptool -vv -cd ck -cb 115200 -cp /dev/cu.usbserial-AL034FJS -ca 0x00000 -cf /var/folders/lv/lj7d61jn61x_8knqdhghk_pc0000gn/T/arduino_build_545013/esp8266arest.ino.bin
    esptool v0.4.9 - (c) 2014 Ch. Klippel <ck@atelier-klippel.de>
     setting board to ck
     setting baudrate from 115200 to 115200
     setting port from /dev/tty.usbserial to /dev/cu.usbserial-AL034FJS
     setting address from 0x00000000 to 0x00000000
     espcomm_upload_file
     espcomm_upload_mem
    opening port /dev/cu.usbserial-AL034FJS at 115200
     tcgetattr
     tcsetattr
     serial open
    opening bootloader
    resetting board
    trying to connect
     espcomm_send_command: sending command header
     espcomm_send_command: sending command payload
    trying to connect
     espcomm_send_command: sending command header
     espcomm_send_command: sending command payload
     espcomm_send_command: receiving 2 bytes of data
     espcomm_send_command: receiving 2 bytes of data
    An error occurred while uploading the sketch
     espcomm_send_command: receiving 2 bytes of data
     espcomm_send_command: receiving 2 bytes of data
     espcomm_send_command: receiving 2 bytes of data
     espcomm_send_command: receiving 2 bytes of data
     espcomm_send_command: receiving 2 bytes of data
     espcomm_send_command: receiving 2 bytes of data
    Uploading 245344 bytes from /var/folders/lv/lj7d61jn61x_8knqdhghk_pc0000gn/T/arduino_build_545013/esp8266arest.ino.bin to flash at 0x00000000
     erasing flash
     size: 03be60 address: 000000
     first_sector_index: 0
     total_sector_count: 60
     head_sector_count: 16
     adjusted_sector_count: 44
     erase_size: 02c000
     espcomm_send_command: sending command header
     espcomm_send_command: sending command payload
     setting timeout 15000
     setting timeout 100
     espcomm_send_command: receiving 2 bytes of data
     writing flash
    warning: espcomm_send_command: didn't receive command response
    warning: espcomm_send_command(FLASH_DOWNLOAD_DATA) failed
    warning: espcomm_send_command: wrong direction/command: 0x01 0x03, expected 0x01 0x04
    closing bootloader
    error: espcomm_upload_mem failed

Can anyone explain this line in detail?

    warning: espcomm_send_command: wrong direction/command: 0x01 0x03, expected 0x01 0x04

Before, when flashing it with my Uno, it would work well enough. This used to happen, and then I would unplug it and plug it in (reset) and try again, until it eventually worked. However, now it happens every time. I have 4 different ESP8266 that are functional and they all respond the same way, with the error above. This leads me to believe that is something with the circuit, or with my settings, which are:

    Board - Generic ESP8266
    Flash mode - DIO
    Flash freq. - 40hz
    CPU freq. - 80hz
    Flash size - 1M(64k SPIFFS)
    Debug Level - none
    Upload Speed - 115200

I have tried messing with the SPIFFS (what are those? packet size?) as well as changing the CPU frequency to 160 Hz, and I tried 80 Hz for the flash frequency.

I used this same system to program the ESP before with an Arduino Uno and I was successful. Why is it so finicky, and what does the response with the `0x01 0x03 instead of 0x01 0x04` trying to say?

body:
Instead of using `Arduino IDE` to upload (I compiled with it), I used `esptool` standalone. After messing with it for a few minutes...this worked without a hitch:

    esptool.py -c esp8266 --port /dev/cu.usbserial-AL034FJS -b 115200 write_flash --flash_freq 40m --flash_size 1MB 0x00000 /var/folders/lv/lj7d61jn61x_8knqdhghk_pc0000gn/T/arduino_build_545013/esp8266arest.ino.bin

I decided to try this after seeing that maybe the `esptool` that `Arduino IDE` uses is outdated - it has `0.4.9` where as the latest version is `2.1`.


message:
Error when trying flash bootloader into Arduino Pro Mini 328P 8MHz 3.3V

I tried flash [bootloader][1] into Arduino Pro Mini 328P 8MHz/3.3V clone, but got error.

First I did test:

    ~$ avrdude -c usbasp -p m328p

    avrdude: AVR device initialized and ready to accept instructions

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

    avrdude: Device signature = 0x1e950f (probably m328p)

    avrdude: safemode: Fuses OK (E:FD, H:D9, L:E2)

    avrdude done.  Thank you.

-------------------------------

    ~$ avrdude -c usbasp -p m328p -v -U flash:w:optiboot_atmega328_pro_8MHz.hex

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

             System wide configuration file is "/etc/avrdude.conf"
             User configuration file is "/home/combox/.avrduderc"
             User configuration file does not exist or is not a regular file, skipping

             Using Port                    : usb
             Using Programmer              : usbasp
             AVR Part                      : ATmega328P
             Chip Erase delay              : 9000 us
             PAGEL                         : PD7
             BS2                           : PC2
             RESET disposition             : dedicated
             RETRY pulse                   : SCK
             serial program mode           : yes
             parallel program mode         : yes
             Timeout                       : 200
             StabDelay                     : 100
             CmdexeDelay                   : 25
             SyncLoops                     : 32
             ByteDelay                     : 0
             PollIndex                     : 3
             PollValue                     : 0x53
             Memory Detail                 :

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

             Programmer Type : usbasp
             Description     : USBasp, http://www.fischl.de/usbasp/

    avrdude: auto set sck period (because given equals null)
    avrdude: AVR device initialized and ready to accept instructions

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

    avrdude: Device signature = 0x1e950f (probably m328p)
    avrdude: safemode: hfuse reads as D9
    avrdude: safemode: efuse reads as FD
    avrdude: NOTE: "flash" memory has been specified, an erase cycle will be performed
             To disable this feature, specify the -D option.
    avrdude: erasing chip
    avrdude: auto set sck period (because given equals null)
    avrdude: reading input file "optiboot_atmega328_pro_8MHz.hex"
    avrdude: error opening optiboot_atmega328_pro_8MHz.hex: No such file or directory
    avrdude: can't determine file format for optiboot_atmega328_pro_8MHz.hex, specify explicitly
    avrdude: read from file 'optiboot_atmega328_pro_8MHz.hex' failed

    avrdude: safemode: hfuse reads as D9
    avrdude: safemode: efuse reads as FD
    avrdude: safemode: Fuses OK (E:FD, H:D9, L:E2)

    avrdude done.  Thank you.

    @combox:~$ cd Downloads
    @combox:~/Downloads$ cd Arduino
    @combox:~/Downloads/Arduino$ avrdude -c usbasp -p m328p -v -U flash:w:optiboot_atmega328_pro_8MHz.hex

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

             System wide configuration file is "/etc/avrdude.conf"
             User configuration file is "/home/combox/.avrduderc"
             User configuration file does not exist or is not a regular file, skipping

             Using Port                    : usb
             Using Programmer              : usbasp
             AVR Part                      : ATmega328P
             Chip Erase delay              : 9000 us
             PAGEL                         : PD7
             BS2                           : PC2
             RESET disposition             : dedicated
             RETRY pulse                   : SCK
             serial program mode           : yes
             parallel program mode         : yes
             Timeout                       : 200
             StabDelay                     : 100
             CmdexeDelay                   : 25
             SyncLoops                     : 32
             ByteDelay                     : 0
             PollIndex                     : 3
             PollValue                     : 0x53
             Memory Detail                 :

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

             Programmer Type : usbasp
             Description     : USBasp, http://www.fischl.de/usbasp/

    avrdude: auto set sck period (because given equals null)
    avrdude: AVR device initialized and ready to accept instructions

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

    avrdude: Device signature = 0x1e950f (probably m328p)
    avrdude: safemode: hfuse reads as D9
    avrdude: safemode: efuse reads as FD
    avrdude: NOTE: "flash" memory has been specified, an erase cycle will be performed
             To disable this feature, specify the -D option.
    avrdude: erasing chip
    avrdude: auto set sck period (because given equals null)
    avrdude: reading input file "optiboot_atmega328_pro_8MHz.hex"
    avrdude: input file optiboot_atmega328_pro_8MHz.hex auto detected as Intel Hex
    avrdude: writing flash (32768 bytes):

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

    avrdude: 32768 bytes of flash written
    avrdude: verifying flash memory against optiboot_atmega328_pro_8MHz.hex:
    avrdude: load data flash data from input file optiboot_atmega328_pro_8MHz.hex:
    avrdude: input file optiboot_atmega328_pro_8MHz.hex auto detected as Intel Hex
    avrdude: input file optiboot_atmega328_pro_8MHz.hex contains 32768 bytes
    avrdude: reading on-chip flash data:

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

    avrdude: verifying ...
    avrdude: verification error, first mismatch at byte 0x7e00
             0x00 != 0x11
    avrdude: verification error; content mismatch

    avrdude: safemode: hfuse reads as 0
    avrdude: safemode: efuse reads as FE
    avrdude: safemode: lfuse changed! Was e2, and is now fe
    Would you like this fuse to be changed back? [y/n]

How to solve this?
  [1]: https://raw.githubusercontent.com/Optiboot/optiboot/master/optiboot/bootloaders/optiboot/optiboot_atmega328_pro_8MHz.hex

body:
It is locked/blown. Looks like you tried to flash it previously as an Arduino Nano or Uno.
Now the lock bits are set. Even in highVoltage programming mode you cannot discover it. Buy a new one.


body:
First, I put the voltage jumper on USBASP programmer to 5V, to increase voltage.
Then I set correct **default fuse bits values** for this board:

    Arduino Pro or Pro Mini (3.3V, 8 MHz) w/ ATmega328

    Low Fuse:  0xFF
    High Fuse:  0xDA
    Extended Fuse:  0x05

    avrdude -c usbasp -p m328p -v -u -U lock:w:0x3f:m -U efuse:w:0xFD:m
    avrdude -c usbasp -p m328p -v -u -U lock:w:0x3f:m -U hfuse:w:0xDA:m
    avrdude -c usbasp -p m328p -v -u -U lock:w:0x3f:m -U lfuse:w:0xFF:m

Note, that I used option **-u** when modifying the fuse bits, this switch tell avrdude we really mean modify it. It disables the default behaviour of reading out the fuses three times before programming, then verifying at the end of programming that the fuses have not changed. I put **0xFD** value for Extended Fuse Byte in place of **0x05**, due to a bug in avrdude. (0xFD and 0x05 are the same value)

After that I flashed correct bootloader:

    avrdude -c usbasp -p m328p -v -U flash:w:optiboot_atmega328_pro_8MHz.hex -U lock:w:0x0f:m

Now it fully fixed and works.


message:
Controlling a stepper with MATLAB

I am trying to control a 28BYJ-48 stepper motor + [ULN2003 motor driver module][1]  (this is a [picture][2]) using MATLAB.

I tried to follow the instructions on [this page][3], but these instructions are specific to Adafruit MotorShield, and I couldn't understand how to modify the code to fit my motor/driver.

Specifically:

 1. How do I wire my motor/driver/Arduino?
 2. How do I modify this command:

        shield = addon(a, 'Adafruit\MotorShieldV2')

 3. Do I need to flash my Arduino with any libraries?

  [1]: https://www.gearbest.com/sensors/pp_599743.html?vip=2665035&gclid=Cj0KCQiAuZXQBRDKARIsAMwpUeROrehL2AfI3oWRb8Yw7jRadlRIDHFX0nwG455NeteX9R43xRfrP58aAlx_EALw_wcB
  [2]: https://cdn.instructables.com/F41/07VI/HMMF4YXL/F4107VIHMMF4YXL.MEDIUM.jpg
  [3]: https://www.mathworks.com/help/supportpkg/arduinoio/ug/control-motors-using-adafruit-motor-shield-v2.html?searchHighlight=shield&s_tid=doc_srchtitle

body:
[Adafruit Motor Shield V2][1] itself generates signals that are required for motor control.

[ULN2003 motor driver module][2] requires signals at the input. This is a significant difference.

[Example][3] of use this driver with MATLAB. Not need to flash Arduino any libraries.

    a=arduino('com3','uno);

    pins={'D8', 'D9', 'D10', 'D11'};
    steps={'1100', '0110', '0011','1001'};

    steps_size=size(steps,2);                        %steps = 4

    for i = 1:50

        step = steps{mod(i,steps_size)+1};      % step=1,2,3,4

        for j=1:4
            writeDigitalPin(a, pins{j}, str2double(step(j)));
        end

        %pause(0.01);

    end

Wiring example (Copied from [CheapStepper v0.2][4])
![Copied from [CheapStepper v0.2]][5]

  [1]: https://cdn-learn.adafruit.com/assets/assets/000/009/536/original/adafruit_products_mshieldv2schem.png?1396892649
  [2]: http://www.ti.com/lit/ds/slrs027o/slrs027o.pdf
  [3]: http://forum.arduino.cc/index.php?topic=357907.0
  [4]: https://github.com/tyhenry/CheapStepper
  [5]: https://i.stack.imgur.com/HohPT.png


message:
Arduino UNO dead with CNC shield

I have an Arduino UNO with a CNC shield. The Arduino is almost certainly a clone.

I installed GRBL with no issue and I have assembled a jig with CD-ROM motors. My first attempt to control this with UGS worked no problem.

I powered down to change the stepping with the jumpers and powered back up and was presented with a very hot smell after a few moments.

I removed the power quickly but now I can no longer program the UNO. It gets recognized in my devices but I can't send any code, even blink.

The jumpers were set like many examples I have seen on the web so I don't think this was the issue.

I am wondering if the way I powered it up was the issue? I am supplying the UNO with 12V 2A supply and I can't recall what order I plugged them in but I get the feeling it must have been supplying 12V to the Arduino.

I have now removed the shield and powering the unit solely from the USB and still can't communicate.

I have resigned to the fact this board is now toasted. Is it important which order you plug in the Arduino? USB first? Do you think it will be possible to recover this Arduino.

body:
This sounds as the ATmega328p processor of the UNO was fried. As the UNO has a second processor (ATmega16U2) which is simply a USB-to-serial converter you only see the presence of this in the list of USB devices but it cannot communicate with the board's main processor anymore.

The plug-in order is not that important with the UNO board only but depending on the components you have attached it may be important. especially if the circuit does not have protection against induction current, p.e. fly-back diodes.


body: Genuine Arduino's have an input limit of 20v and a recommended voltage of 7-12v. I naively assumed that the same would be for the clone but it has a max input voltage of 9v. Supplying 12v to the unit worked for a short time but the regulator must have melted and cooked the main processor.


body:
The same exact thing happened to me. I was using A4988 on a CNC shield which was mounted onto my arduino uno by rexqualis. A couple days ago it was working (inconsistently) to move my NEMA 17 motors. Today, I adjusted the potentiometers on the A4988 to try to improve consistency when my arduino would no longer connect to the serial port. I took the shield off and realized the arduino was very hot. Now it gets hot anytime I plug it even with no inputs or outputs. It will still not connect to the serial port.

I was using 12V of power going into the CNC shield. This and 9v seemed to work a couple days ago. I am not sure of how to avoid this problem in the future, but I am thinking that I need to put the potentiometers where they were before.


message:
Arduino millis() fuction execution problem

I am new to Arduino development. I want to use `millis` function instead of `delay` because delay is blocking further execution of program.

Program description: In this code I want to control 2 solenoid valves with DS3231 RTC alarm and also with infrared remote control button pressed.
But when I press one button for valve ON program does not turn valve on.

Please check this program and correct my mistake.

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

    #include <DS3231.h>
    #include <IRremote.h>
    #include <IRremoteInt.h>
    #include "IRremote.h"
    #define LED1 2
    int receiver = 6;
    IRrecv irrecv(receiver);     // create instance of 'irrecv'
    decode_results results;      // create instance of 'decode_results'
    #define VALVE1 7
    #define VALVE2 12
    DS3231  rtc(SDA, SCL);
    Time  t;
    //-------------millis timer----------------------------------
    unsigned long last1 = millis();

    void setup()
    {
      irrecv.enableIRIn(); // Start the receiver
      rtc.begin();
      Serial.begin(9600);
      pinMode(VALVE1, OUTPUT);
      pinMode(VALVE2, OUTPUT);
    }

    void loop()
    {
      t = rtc.getTime();   // Get data from the DS3231
      delay(200);
      if (irrecv.decode(&results)) // have we received an IR signal?
      {
        translateIR();
        irrecv.resume(); // receive the next value
      }

      //------ALARM FOR AUTO WATERING GARDEN----
      //MORNING Routine FOR VALVE========
      if (t.hour == 16 && t.min == 15 && t.sec == 00)  //Open valve1 8AM morning
      {
        void G_valve1On();
      }

      if (t.hour == 16 && t.min == 20 && t.sec == 00)  //close valve1 8:10AM morning
      {
        void G_valve1Off();
      }

      //---------FUNCTIONS-----------------------------
      //IR COMMAND FUNCTIONS
      void translateIR()
      {
        switch (results.value)
        {
          case 0x843509F6:         //valve 1 turn on for 10minute delay
            if (millis() - last1 > 600000) //when remote button pressed valve turn on for 10min
            { G_valve1On();
              Serial.println("valve ON");
            }
            G_valve1Off();
            Serial.println("valve off");
            delay(250);
            break;
          case 0x84350AF5:                 //2nd button for 15 min delay
            G_valve2On();

            //Serial.println("valve on 15minutes...");
            //Help me to use MILLS FUNCTION.

            G_valve2Off();
            //Serial.println("valve off");
            delay(250);
            break;
        }
        delay(300);
      }
    }

      //----VALVES- FUNCTION------

      void G_valve1On()
      {
        digitalWrite(VALVE1, HIGH);
        Serial.println("...turning valve1 on...");
      }
      void G_valve1Off()
      {
        digitalWrite(VALVE1, LOW);
        Serial.println("...turningvalve1 off...");
      }
      void G_valve2On()
      {
        digitalWrite(VALVE2, HIGH);
        Serial.println("...turning valve1 on...");
      }
      void G_valve2Off()
      {
        digitalWrite(VALVE2, LOW);
        Serial.println("...turningvalve1 off...");
      }

***UPDATE:***

Thanks for the replies. I have made some changes in the program that user ratchet freak provided below, but it is giving error.

Program:

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

    #include <DS3231.h>
    #include <boarddefs.h>
    #include <IRremote.h>
    #include <IRremoteInt.h>
    #include <ir_Lego_PF_BitStreamEncoder.h>
    #include "IRremote.h"
    #define LED1 2
    int receiver = 6;
    IRrecv irrecv(receiver);     // create instance of 'irrecv'
    decode_results results;      // create instance of 'decode_results'
    #define valve1 13
    #define valve2 12
    DS3231  rtc(SDA, SCL);
    Time  t;

    struct valve_state {
      bool on;
      unsigned long on_timestamp;
      unsigned long on_time;
    }
    valve_state valve1;
    valve_state valve2;
    void setup()
    {
      irrecv.enableIRIn(); // Start the receiver
      rtc.begin();
      Serial.begin(9600);
      pinMode(valve2, OUTPUT);
      pinMode(valve1, OUTPUT);
    }

    void loop() {
      t = rtc.getTime();

      //read ir
      //read rtc
      if (irrecv.decode(&results))
      {
        if (ir.value == 0x843509F6 ||                              //VALVE 1ON OFF
            (rtc.hour == 16 && rtc.min == 15 && rtc.sec == 00)) {
          valve1.on = true;
          valve1.on_timestamp = millis();

          valve1.on_time = 10 * 60 * 1000;
        }
        if (valve1.on && (millis() - valve1.on_timestamp > valve1.on_time)) {
          valve1.on = false;
          digitalWrite(valve1, LOW);

          if (ir.value == 0x843509F6 ||                                      //VALVE 2 ON OFF
              (rtc.hour == 16 && rtc.min == 15 && rtc.sec == 00)) {
            valve2.on = true;
            valve2.on_timestamp = millis();
            digitalWrite(valve2, HIGH);
            valve1.on_time = 10 * 20 * 1000;
          }
          if (valve2.on && (millis() - valve2.on_timestamp > valve2.on_time)) {
            valve1.on = false;
            digitalWrite(valve2, LOW);

          }

But the Arduino IDE gives following errors:

<!-- language: lang-none -->

    :\Users\ABHI's\AppData\Local\Temp\arduino_2447f9e2b3111c537660c536aa9c2330\sketch_nov11a.ino:23:13: note: in expansion of macro 'valve1'

     valve_state valve1;

                 ^

    sketch_nov11a:12: error: expected unqualified-id before numeric constant

     #define valve2 12

                    ^

    C:\Users\ABHI's\AppData\Local\Temp\arduino_2447f9e2b3111c537660c536aa9c2330\sketch_nov11a.ino:24:13: note: in expansion of macro 'valve2'

     valve_state valve2;

                 ^

    C:\Users\ABHI's\AppData\Local\Temp\arduino_2447f9e2b3111c537660c536aa9c2330\sketch_nov11a.ino: In function 'void loop()':

    sketch_nov11a:43: error: 'ir' was not declared in this scope

         if(ir.value == 0x843509F6 ||
    sketch_nov11a:44: error: 'class DS3231' has no member named 'hour'

        (rtc.hour == 16 && rtc.min == 15 && rtc.sec == 00)){

    sketch_nov11a:44: error: 'class DS3231' has no member named 'min'

            (rtc.hour == 16 && rtc.min == 15 && rtc.sec == 00)){
                                ^
    sketch_nov11a:44: error: 'class DS3231' has no member named 'sec'

            (rtc.hour == 16 && rtc.min == 15 && rtc.sec == 00)){

    sketch_nov11a:45: error: request for member 'on' in '13', which is of non-class type 'int'

             valve1.on = true;

    sketch_nov11a:46: error: request for member 'on_timestamp' in '13', which is of non-class type 'int'

             valve1.on_timestamp = millis();                ^

    sketch_nov11a:55: error: request for member 'on_time' in '13', which is of non-class type 'int'

             valve1.on_time = 10*60*1000;

    sketch_nov11a:57: error: request for member 'on' in '13', which is of non-class type 'int'

         if(valve1.on && (millis() - valve1.on_timestamp > valve1.on_time)){

    sketch_nov11a:57: error: request for member 'on_timestamp' in '13', which is of non-class type 'int'
         if(valve1.on && (millis() - valve1.on_timestamp > valve1.on_time)){

    sketch_nov11a:57: error: request for member 'on_time' in '13', which is of non-class type 'int'

         if(valve1.on && (millis() - valve1.on_timestamp > valve1.on_time)){                                                              ^

    sketch_nov11a:58: error: request for member 'on' in '13', which is of non-class type 'int'

             valve1.on = false;                ^

    sketch_nov11a:69: error: 'ir' was not declared in this scope

          if(ir.value == 0x843509F6 ||          ^

    sketch_nov11a:70: error: 'class DS3231' has no member named 'hour'

            (rtc.hour == 16 && rtc.min == 15 && rtc.sec == 00)){             ^

    sketch_nov11a:70: error: 'class DS3231' has no member named 'min'

            (rtc.hour == 16 && rtc.min == 15 && rtc.sec == 00)){                              ^
    sketch_nov11a:70: error: 'class DS3231' has no member named 'sec'

            (rtc.hour == 16 && rtc.min == 15 && rtc.sec == 00)){                                                ^

    sketch_nov11a:71: error: request for member 'on' in '12', which is of non-class type 'int'
             valve2.on = true;                ^

    sketch_nov11a:72: error: request for member 'on_timestamp' in '12', which is of non-class type 'int'

             valve2.on_timestamp = millis();

                    ^

    sketch_nov11a:81: error: request for member 'on_time' in '13', which is of non-class type 'int'

             valve1.on_time = 10*20*1000;                ^

    sketch_nov11a:83: error: request for member 'on' in '12', which is of non-class type 'int'

         if(valve2.on && (millis() - valve2.on_timestamp > valve2.on_time)){
                   ^

    sketch_nov11a:83: error: request for member 'on_timestamp' in '12', which is of non-class type 'int'

         if(valve2.on && (millis() - valve2.on_timestamp > valve2.on_time)){                                        ^

    sketch_nov11a:83: error: request for member 'on_time' in '12', which is of non-class type 'int'

         if(valve2.on && (millis() - valve2.on_timestamp > valve2.on_time)){                                                            ^

    sketch_nov11a:84: error: request for member 'on' in '13', which is of non-class type 'int'

             valve1.on = false;                ^

    sketch_nov11a:97: error: expected '}' at end of input
     }

    exit status 1
    expected initializer before numeric constant

Can you please reconstruct complete program for me?

body:
The code you posted doesn't compile. I fixed the missing brace and used the auto-format command of the IDE to fix the mess in indentation.
I then inserted the necessary code for the two buttons.

    #include <DS3231.h>
    #include <IRremote.h>
    #include <IRremoteInt.h>
    #include "IRremote.h"
    #define LED1 2
    int receiver = 6;
    IRrecv irrecv(receiver);     // create instance of 'irrecv'
    decode_results results;      // create instance of 'decode_results'
    #define VALVE1 7
    #define VALVE2 12
    DS3231  rtc(SDA, SCL);
    Time  t;
    //-------------millis timer----------------------------------
    unsigned long last1 = 0;
    unsigned long last2 = 0;
    void setup()
    {
      irrecv.enableIRIn(); // Start the receiver
      rtc.begin();
      Serial.begin(9600);
      pinMode(VALVE1, OUTPUT);
      pinMode(VALVE2, OUTPUT);
    }

    void loop()
    {
      t = rtc.getTime();   // Get data from the DS3231
      if (irrecv.decode(&results)) // have we received an IR signal?
      {
        translateIR();
        irrecv.resume(); // receive the next value
      }

      // turn of valves if they are on for enough time
      if (last1 && millis() - last1 > 600000)
      {
        G_valve1Off();
        Serial.println("valve off");
        last1 = 0;
      }
      if (last2 && millis() - last2 > 900000)
      {
        G_valve2Off();
        last2 = 0;
      }

      //------ALARM FOR AUTO WATERING GARDEN----
      //MORNING Routine FOR VALVE========
      if (t.hour == 16 && t.min == 15 && t.sec == 00)  //Open valve1 8AM morning
      {
        void G_valve1On();
      }

      if (t.hour == 16 && t.min == 20 && t.sec == 00)  //close valve1 8:10AM morning
      {
        void G_valve1Off();
      }
    }

    //---------FUNCTIONS-----------------------------
    //IR COMMAND FUNCTIONS
    void translateIR()
    {
      switch (results.value)
      {
        case 0x843509F6:         //valve 1 turn on for 10minute delay

          G_valve1On();
          Serial.println("valve ON");
          last1 = millis();
          break;

        case 0x84350AF5:                 //2nd button for 15 min delay
          G_valve2On();
          last2 = millis();
          break;
      }
      delay(300);
    }

    //----VALVES- FUNCTION------

    void G_valve1On()
    {
      digitalWrite(VALVE1, HIGH);
      Serial.println("...turning valve1 on...");
    }
    void G_valve1Off()
    {
      digitalWrite(VALVE1, LOW);
      Serial.println("...turningvalve1 off...");
    }
    void G_valve2On()
    {
      digitalWrite(VALVE2, HIGH);
      Serial.println("...turning valve1 on...");
    }
    void G_valve2Off()
    {
      digitalWrite(VALVE2, LOW);
      Serial.println("...turningvalve1 off...");
    }


body:
The best way to handle this kind of thing is by state machine. Each valve is its own state machine and is handled one at a time.

The state machine for the valve seems to be trigger valve on based on RTC or remote. Turn off when timeout triggers

So you handle each event based on the current state:

    struct valve_state{
        bool on;
        unsigned long on_timestamp;
        unsigned long on_time;
    }

    valve_state valve1;
    valve_state valve2;

    void loop(){

        //read ir
        //read rtc

        if(ir.value == 0x843509F6 ||
           (rtc.hour == 16 && rtc.min == 15 && rtc.sec == 00)){
            valve1.on = true;
            valve1.on_timestamp = millis();
            digitalWrite(VALVE1,HIGH);
            valve1.on_time = 10*60*1000;
        }
        if(valve1.on && (millis() - valve1.on_timestamp > valve1.on_time)){
            valve1.on = false;
            digitalWrite(VALVE1,LOW);
        }

        //repeat for valve2
    }


message:
Splitting Integers

I have bluetooth (HC-05) connected on Serial port of Arduino Mega and two TM1637, I am receiving Strings from an Android phone with an app with two Time picker (Fajar and Zohar)[![see attachment][1]][1]
I am sending time which is set by time picker in a formatted way.

The format is <IDHHMM>

**<** : Start of number delimiter.

**ID** : is the number 1 or 2 (1 for Fajar and 2 for Zohar), it indicates from which time picker the data has come.

**HH** : Hours, set from time picker.

**MM** : Minutes, set from time picker.

**>** : End of number delimiter.

 [![See incoming raw data from Bluetooth][2]][2]

Here in the example, first data which comes in is **<10320>** , which is starting delimiter "<" first digit "1" is the ID from Fajar time picker,03 Hours and 20 minutes and ending delimiter ">". Second data is **<21830>**, which is from Zohar time picker and vice versa.

I am parsing the incoming string and converting them into integers using the code found on Arduino Forum.

    const char startOfNumberDelimiter = '<';
    const char endOfNumberDelimiter   = '>';

    void setup ()
     {
     Serial.begin (9600);
     Serial.println ("Starting ...");
     } // end of setup

    void processNumber (const long n)
     {
     Serial.println (n);
     }  // end of processNumber

    void processInput ()
     {
     static long receivedNumber = 0;
     static boolean negative = false;

     byte c = Serial.read ();

     switch (c)
       {

       case endOfNumberDelimiter:
         if (negative)
           processNumber (- receivedNumber);
         else
           processNumber (receivedNumber);

       // fall through to start a new number
       case startOfNumberDelimiter:
         receivedNumber = 0;
         negative = false;
         break;

       case '0' ... '9':
         receivedNumber *= 10;
         receivedNumber += c - '0';
         break;

       case '-':
         negative = true;
         break;

       } // end of switch
     }  // end of processInput

    void loop ()
     {

     if (Serial.available ())
       processInput ();

     // do other stuff here
     } // end of loop
with the code above, i can convert string to integers and remove delimiters.

See output of the code in serial monitor.
[![finished data][3]][3]

**Problem is** : I have to separate ID and Hours and Minutes from that integer and wrap Hours and Minutes that up in

    int8_t Digits [] = {1, 2 , 3 , 4 };

Here {1,2,3,4} is {H,H,M,M} Hours and Minutes which displays digits on one of the TM1637.

and also ID with "1" should change the digits on one of the TM167 and the ID with "2" should change digits on another TM1637.

Here is my full code :

    #include "TM1637.h"

    #define CLK1 2
    #define DIO1 3

    #define CLK2 4
    #define DIO2 5

    TM1637 Display1 (CLK1, DIO1);

    TM1637 Display2 (CLK2, DIO2);

    const char startOfNumberDelimiter = '<';
    const char endOfNumberDelimiter   = '>';

    void setup ()
    {
      Display1.set ();
      Display1.init ();

      Display2.set();
      Display2.init();

      Serial.begin(9600);
      Serial.println ("Starting ...");
    }

    void loop ()
    {
      if (Serial.available ())
        processInput ();
      fajar();
      zohar();
    }

    void processNumber (const long n)
    {
      Serial.println (n);
    }  // end of processNumber

    void processInput ()
    {
      static long receivedNumber = 0;
      static boolean negative = false;

      byte c = Serial.read ();

      switch (c)
      {

        case endOfNumberDelimiter:
          if (negative)
            processNumber (- receivedNumber);
          else
            processNumber (receivedNumber);

        // fall through to start a new number
        case startOfNumberDelimiter:
          receivedNumber = 0;
          negative = false;
          break;

        case '0' ... '9':
          receivedNumber *= 10;
          receivedNumber += c - '0';
          break;

        case '-':
          negative = true;
          break;

      } // end of switch
    }  // end of processInput

    void fajar ()
    {
      int8_t Digits [] = {1, 2 , 3 , 4 };
      Display1.display (Digits);
      Display1.point(POINT_ON);
    }

    void zohar ()
    {
      int8_t Digits [] = {1, 2 , 3 , 4 };
      Display2.display (Digits);
      Display2.point(POINT_ON);
    }

  [1]: https://i.stack.imgur.com/r3XaJ.png
  [2]: https://i.stack.imgur.com/QH1HS.png
  [3]: https://i.stack.imgur.com/6W6V9.png

Please Help

**EDIT** : Here is my edited code with Majenko shown technique.

    #include "TM1637.h"

    #define CLK1 2
    #define DIO1 3

    #define CLK2 4
    #define DIO2 5

    uint8_t fajar[4];
    uint8_t zohar[4];

    uint8_t address = 0;
    uint8_t ptr = 0;

    TM1637 Display1 (CLK1, DIO1);

    TM1637 Display2 (CLK2, DIO2);
    void setup ()
    {
      Display1.set ();
      Display1.init ();

      Display2.set();
      Display2.init();

      Serial.begin(9600);
    }

    void loop ()
    {
      int c = Serial.read();
      switch (c) {
        case '<': // Start of string - reset everything
          address = 0;
          ptr = 0;
          break;
        case '>': // End of string

           fajartime (); // Edited
           zohartime (); // Edited

          break;
        default:
          if ((c >= '0') && (c <= '9')) {
            if (address == 0) {
              address = c - '0';
            } else if (ptr < 4) {
              switch (address) {
                case 1:
                  fajar[ptr] = c - '0';
                  break;
                case 2:
                  zohar[ptr] = c - '0';
                  break;
              }
              ptr++;
            }
          }
      }
    }

    void fajartime ()
    {

      Display1.display (fajar);
      Display1.point(POINT_ON);
    }

    void zohartime ()
    {

      Display2.display (zohar);
      Display2.point(POINT_ON);
    }

Thank you

body:
I'm not sure I know what you need help with.  You have code that reads a 5 character string from between <iHHMM>.

 - If i == 1 you pass the remaining 4 characters to fajar.
 - If i == 2 you pass the remaining 4 characters to zohar.

You then need a function to convert the 4 characters into 4 separate integers.  You might need to map these integers onto a code that displays the correct lights or you might have a library to do this already.  (You already have the code for this function).  All you need to do then is push the number to the display.  That might be the problem you have, but how you do that depends on you library and connections.

    TM1637 Displays[2] = {(CLK1, DIO1), (CLK2, DIO2)};
    void loop()
    {
        char buffer[1 + 5 + 1 + 1];
        buffer = readNumber (buffer);
        if (buffer[0] == '1')          // Treating as a character not a number.
            fajar(&(buffer[1]));
        else
            zohar(&(buffer[1]));
    }
    void fajar(char const* buffer) { displayValue(1, buffer);}
    void zohar(char const* buffer) { displayValue(2, buffer);}
    void displayValue (const int& displayID, char const* buffer)
    {
        int numericValues[4];
        convertToNumbers (buffer, numericValues);  // The code in the switch statement.
        Display[displayID].display (numericValues);
        Display[displayID]..point(POINT_ON);
    }

The above code is only a guide, never compiled and it is riddled with issues that could, if bad data was received, cause a major problem.  You are going to have to add error and bounds checking before you do anything more than dev test it, but it should work :)


body:
You're thinking the wrong way. At the moment you are receiving individual characters, then combining them into a single integer, and then you want to split that integer back into individual characters. But you *start* with individual characters already. You don't need, nor want, to convert the string into an integer to then split it again.

If you take each character as it comes in as a separate number and store it separately you have no need for splitting.

For instance, you could have two 4-byte arrays for the two times. You don't need to store the first byte, since it's just an indicator of destination (we can call it a register address if you like).

A simple Finite State Machine for receiving in the correct way will make things easier:

    uint8_t fajar[4];
    uint8_t zohar[4];
    uint8_t address = 0;
    uint8_t ptr = 0;

    int c = Serial.read();
    switch (c) {
        case '<': // Start of string - reset everything
            address = 0;
            ptr = 0;
            break;
        case '>': // End of string
            // Do whatever with the data here
            break;
        default:
            if ((c >= '0') && (c <= '9')) {
                if (address == 0) {
                    address = c - '0';
                } else if (ptr < 4) {
                    switch (address) {
                        case 1:
                            fajar[ptr] = c - '0';
                            break;
                        case 2:
                            zohar[ptr] = c - '0';
                            break;
                    }
                    ptr++;
                }
            }
    }

You could simplify things by combining zohar and fajar into a single 2D array keyed on the address (though take care that `address` never gets an invalid value in that case), or you can reduce memory usage by only having one 4-byte array if you don't care about keeping the data separate at all times (you use it and throw it away as soon as it's arrived).


message:
Arduino & RPi communication via GPIO

so I'm working on communication between arduino and RPi via GPIO pin.
It's basically connecting them by using a cable jumper. So I have a 2 channel relay shield attached to my arduino, and I've been wondered how do I connect them to RPi. I need help for this problem, any advice would be appriciated. I'll post the GPIO pin below.
Thankyou
[![2 relay channel shield][1]][1]

[![RPi GPIO pin][2]][2]

  [1]: https://i.stack.imgur.com/OEriE.jpg
  [2]: https://i.stack.imgur.com/RqLY6.png

body: I assume you are using Arduino UNO. Pi's digital logic is at 3.3 V and that of Arduino Uno is at 5 V. Anyway to send data from Pi to UNO, you can connect the pins directly. UNO can recognise both the logic levels of Pi's output. But to receive data from UNO to Pi, make sure you build a voltage divider using resistors, that brings 5V output from UNO's pin to 3.3 V. Also the grounds of both Pi and UNO should be connected to each other.


body:
What you are asking really makes no sense at all.

You are starting from the mid-point of your project and wondering how to communicate using bare GPIOs without really knowing *what it is you want to communicate* and *what you want to do with that data* - or at least you haven't made any of that clear to us.

It is unclear what you want to do with the shield from the Pi. Do you want to control the relays on it by sending instructions from the Pi? Do you want the Pi to send and receive data through the XBee? Either way the Arduino is pretty redundant in the system and in fact gets in the way more than is useful.

If it's just relays you want then it would be far simpler to wire cheap relay modules direct to the GPIOs of the Pi - then you don't have to worry about "how to communicate" - you just turn the relays on and off.

If you want to communicate with the XBee there are far simpler shields available that will plug directly into a Pi. Indeed, there are some good shields around for the Pi ("Hats" I think they call them) which give you an Arduino footprint and an XBee socket together.

The Arduino is completely pointless in this system. And anyway, if you wanted to make the two systems communicate there are far easier ways than with bare GPIO pins. Serial, for a start. The simplest ever method is to just plug the Arduino into the Pi's USB. That way it gets power and data all in one go. Just like using it with a computer.


message:
Does old/low charge battery affects internal clock?

Totally newbie in eletronics here, but could not find the answer for this one.

When a battery is nearly-exhausted, it's voltage and or amperage dims, right?

My question is if this kind of scenario (running low battery) would affect the arduino internal clock using only it.

I'm using arduino to a device that will operate remotely (with a 9V battery), and also logs intervals using the time function.

If battery is near-exhausted, then will this skew the numbers I get?

body:
Let's assume by "internal clock" you mean the internal oscillator, as the arduino's processor does not have a built-in real-time clock (something that is meant to keep track of real time like seconds/minutes/hours.)

The arduino is not like a motor where it runs slower if a lower voltage is applied. If the voltage goes too low, the arduino will just reset. Once it resets, the program running in it just starts over again, unless the battery voltage is so low it can't even start up.

If you're feeding it with a 9V battery, you're going through the 5V linear regulator on-board, which is not very energy efficient. Keep that in mind if your goal is to create a project that is meant to run a long time on the 9V battery. See the notes at [http://www.gammon.com.au/power][1] for tips on reducing the power used by an arduino and/or ATMega-based project.

  [1]: http://www.gammon.com.au/power


body:
Microprocessor clock crystal frequencies can vary a few parts per million when microprocessor supply voltages vary significantly.  For example, a [Czechoslovakian blog article](http://www.zirafoviny.cz/modules/news/article.php?storyid=218) (which was mentioned in [avrfreaks.net](http://www.avrfreaks.net/forum/crystal-oscillator-frequency-vs-supply-voltage) and is shown in automatic-translated form at [translate.google.com](https://translate.google.com/translate?sl=cs&tl=en&js=y&prev=_t&hl=en&ie=UTF-8&u=http://www.zirafoviny.cz/modules/news/article.php?storyid=218&edit-text=)) shows a nearly-negligible drop of about 14 PPM as supply voltage for an Atmel ATtiny2313 rises from 2.4 V to 3.5 V or drops from 5 V to 3.5 V.  In the results, crystal frequency was about 4000000 Hz near 2.4 V and 5 V, and drops to 3999945 Hz near 3.5 V.

I refer to that 14 PPM frequency change as nearly negligible because typical inexpensive crystals have ±50 PPM or worse accuracy and stability specifications, and ±50 PPM or worse allowance over temperature changes of a few degrees, and somewhat larger allowances as the crystal's load capacitance varies by a few pF.  Thus, crystal frequency changes due to supply voltage changes are negligible compared to changes due to other causes.


message:
Non intrusive current sensor with unreliable (strange) readings

I have a project where I will mount 6 non intrusive current sensor model SCT013 (100A/50mA) manufactured by [yhdc.com][1] on an Arduino Mega.

Virtual ground and Burden resistors are 1% tolerance.

To start testing I mounted 2 sensors using the principles of connection found at (http://www.homautomation.org/2013/09/17/current-monitoring-with-non-invasive-sensor-and-arduino/). Code below.

    #include "EmonLib.h"                   // Include Emon Library
    EnergyMonitor emon0;                   // Create an instance
    EnergyMonitor emon1;                   // Create an instance

    int Calib = 60;

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

      emon0.current(A0, Calib);             // Current: input pin, calibration.
      emon1.current(A1, Calib);             // Current: input pin, calibration.

       }

       void loop(){

    double Irms0 = emon0.calcIrms(1480);
    double Irms1 = emon1.calcIrms(1480);

    Serial.print("Sensor0: ");
    Serial.print(Irms0);
    Serial.print(" Amps ");

    Serial.print("Sensor1: ");
    Serial.print(Irms1);
    Serial.println(" Amps ");

    }
    //------------end------------

The code I found is for UNO and a single sensor and I just added a second, it works fine and sensors do independent readings well.

Both sensors are mounted on the same test live wire so I have to get more or less the same readings most of the times and it is precisely the case with readings floating between sensors on the order of 100s of miliamps.

My problems are:

 1. Even with no load I get, on both sensors, a reading that varies from 270 to 320mA

 2. When I connect a hair dryer that consumes in one mode 10A and in
    another mode 5A the readings are a lot closer to the expected (I am
    also checking with a clamp meter)

The problem seems to be the no load condition and the imprecise readings at low currents.
I could exclude readings under a certain value on my code to solve the no load problem but them I would be ignoring real electrical measurement situations.

  [1]: http://yhdc.com

body:
Every time you use a real clamp meter, you should zero it out before measuring.

The hall effect sensors you describe are the same way. There's magnetic pull from the earth and other sources that need to be corrected for. When you draw 5 or 10 amps, that noise is masked out. They are likely still apart roughly the same # of ma as the baseline reading.

Once you subtract the no-load load from each, maybe on startup, you should get a lot better readings in terms of accuracy and precision.


message:
How to calculate step delay?

I'm struggling with get suitable step delay while driving a stepper motor.

How to calculate exact step delay for 1.8deg/step stepper motor?
Give some example calculation.

body:
- Convert the RPM of the motor to RPS.
- Take reciprocal to get seconds per revolution.
- Divide it by 360 to get seconds per degree.
- Multiply by 1.8 to get seconds per step.


body:
> How to calculate exact step delay for 1.8deg/step stepper motor?

each rpm = 360 degrees * rpm / 60 second.

So the time, between each step, is resolution / (60 * rpm), where resolution = 1.8deg/step in your case.


message:
How to correctly use functions that return pointers to multiple typedef'ed types in Arduino IDE?

I have a program that typedef's two structs. Each one has a corresponding function that returns a pointer to it....

    typedef struct {
      int x1;
    } x;

    x *a;

    x *f(void) {
      return a;
    }

    typedef struct {
        int  y1;
    } y;

    y *b;

    y *g(void) {
      return b;
    }

    void loop(void) {

    }

    void setup(void) {

    }

This program produces the following error when compiled under the Arduino IDE...

    sketch_nov10a:18: error: 'y' does not name a type

     y *g(void)

If we copy/paste to switch the order of the two blocks like so...

    typedef struct {
        int  y1;
    } y;

    y *b;

    y *g(void) {
      return b;
    }

    typedef struct {
      int x1;
    } x;

    x *a;

    x *f(void) {
      return a;
    }

    void loop(void) {

    }

    void setup(void) {

    }

...then we instead get the following error...

    sketch_nov10a:18: error: 'x' does not name a type

    x *f(void)

...so apparently the Arduino IDE only supports functions that return pointers to the first typedef'ed type defined in the file?

Is there a rational to this? How would you implement the above code to get it to compile under the Arduino IDE (it works fine in `gcc`).

body:
The Arduino IDE, rather annoyingly, tries to "help" you by generating function prototypes for functions, something it sometimes fails to do.

You can make your code compile by adding one yourself:

    typedef struct {
      int x1;
    } x;

    x *a;

    x *f(void) {
      return a;
    }

    typedef struct {
        int  y1;
    } y;

    y *b;

    y *g(void);    // <------------------ ADD THIS
    y *g(void) {
      return b;
    }

    void loop(void) {

    }

    void setup(void) {

    }

I have a [post about how to avoid the quirks in the IDE](http://www.gammon.com.au/forum/?id=12625) which may help you.

If you just move your code into a separate .CPP file and leave the main sketch blank, it will compile, if you add this line to the start of the .CPP file:

    #include <Arduino.h>

The Arduino IDE uses gcc, so it isn't a problem with the compiler exactly, it is a problem with how it "helps" you.


body:
bigjosh, Thank you for a small and working sketch that shows the problem !

It is probably a bug of the Arduino preprocessing before handing it over to the compiler, as @nick-gammon wrote.

When I rewrite the code in my own way (in a normal sketch, a *.ino file), the error message is gone. I use a more modern style of the struct typedefs, and I declare first the typedefs and after that the variables and after that the functions.
I suppose that when multiple include files are used, then this might not be possible.

    // declare the typedefs.
    struct x {
      int x1;
    };

    struct y {
      int  y1;
    };

    // create variables (pointers)
    x *a;
    y *b;

    // Arduino functions
    void loop(void) {
    }

    void setup(void) {
    }

    // Your own functions
    x *f(void) {
      return a;
    }

    y *g(void) {
      return b;
    }

I hope the data of the struct is located somewhere, because the sketch has only pointers and no valid memory location that they can point to.


body:
# Cause

Ok, I've pinned down the root of this issue.

The `arduino-builder` program is responsible for mangling the sketch INO file into a cpp file to be fed into `gcc`. Among other things,  it scans the file for function definitions and then adds prototypes for all the found functions.

The prototypes are added as a block just before the first function declaration in the file.

Unfortunately this strategy fails any time there is the following sequence....

1. a function definition
2. a type definition
3. a function definition that depends on the type defined in #2

...since the prototype for the function defined in #3 ends up being added before the type definition in #2 on which it depends, creating the compilation error.

The code responsible for this behavior is here...

https://github.com/arduino/arduino-builder/blob/b91cea8c8a42803b0b40dcdde2d1165c4e225457/src/arduino.cc/builder/ctags_runner.go#L83

A more robust strategy would be to add each function prototype before the first function definition that calls the function being prototyped.

# Workaround

In the meantime, a workaround is to move all type definitions to be before the first function definition in the source code.

Rearranging the above example program like so...

    typedef struct {
      int x1;
    } x;

    typedef struct {
        int  y1;
    } y;

    x *a;

    x *f(void) {
      return a;
    }

    y *b;

    y *g(void) {
      return b;
    }

    void loop(void) {

    }

    void setup(void) {

    }

...resolves the error, at the expense of code clarity.


message:
Send events to Azure IoT Hub combined with deep sleep mode

I use a Node MCU ESP8266. I have a working C app sending temperature and humidity sensor data to Azure IoT Hub continuously. I see events/messages coming in at Azure.

Now I'd like the app to only send data every minute or so. So I implemented a deep sleep scenario. The problem is my messages are queued but not sent.

My suspicion is that the IoTHubClient_LL_DoWork() does not send the data immediately before the device is going into deep sleep. But I don't know enough about C or the AzureIoT SDK. Here is my code:

    #include <ESP8266WiFi.h>
    #include <WiFiClientSecure.h>
    #include <WiFiUdp.h>

    #include <stdlib.h>
    #include <stdio.h>
    #include <stdint.h>
    #include <time.h>
    #include <sys/time.h>

    #include <AzureIoTHub.h>
    #include <AzureIoTProtocol_MQTT.h>

    #include <ArduinoJson.h>

    #define IOT_CONFIG_CONNECTION_STRING "CONNSTRING"

    #define DEVICE_ID "NodeMcu"

    #define WIFI_SSID "SSID"
    #define WIFI_PW "PW"

    #define MESSAGE_MAX_LEN 256

    static bool messagePending = false;
    static bool messageSending = true;

    static int messageCount = 1;

    static IOTHUB_CLIENT_LL_HANDLE iotHubClientHandle;

    void setup()
    {
        delay(1000);

        Serial.begin(115200);

        connect();
        initTime();

        iotHubClientHandle = IoTHubClient_LL_CreateFromConnectionString(IOT_CONFIG_CONNECTION_STRING, MQTT_Protocol);
        if (iotHubClientHandle == NULL)
        {
            Serial.println("Failed on IoTHubClient_CreateFromConnectionString.");
            while (1);
        }

        //IoTHubClient_LL_SetOption(iotHubClientHandle, "product_info", "HappyPath_AdafruitFeatherHuzzah-C");
        //IoTHubClient_LL_SetMessageCallback(iotHubClientHandle, receiveMessageCallback, NULL);
        //IoTHubClient_LL_SetDeviceMethodCallback(iotHubClientHandle, deviceMethodCallback, NULL);
        //IoTHubClient_LL_SetDeviceTwinCallback(iotHubClientHandle, twinCallback, NULL);
    }

    void loop()
    {
        if (!messagePending && messageSending)
        {
            char messagePayload[MESSAGE_MAX_LEN];
            readMessage(messageCount, messagePayload);
            sendMessage(iotHubClientHandle, messagePayload);
            messageCount++;
            delay(5000);
        }

        IoTHubClient_LL_DoWork(iotHubClientHandle);
        delay(10);
    }

    void connect()
    {
        delay(10);

        if (WiFi.status() == WL_CONNECTED)
        {
            Serial.println("Already connected...");
            return;
        }

        // Connect to WiFi network
        Serial.println();
        Serial.println();
        Serial.print("Connecting to ");
        Serial.println(WIFI_SSID);

        WiFi.begin(WIFI_SSID, WIFI_PW);

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

    void initTime() {
        time_t epochTime;

        configTime(0, 0, "pool.ntp.org", "time.nist.gov");

        while (true) {
            epochTime = time(NULL);

            if (epochTime == 0) {
                Serial.println("Fetching NTP epoch time failed! Waiting 2 seconds to retry.");
                delay(2000);
            } else {
                Serial.print("Fetched NTP epoch time is: ");
                Serial.println(epochTime);
                break;
            }
        }
    }

    void readMessage(int messageId, char *payload)
    {
        float temperature = readTemperature();
        float humidity = readHumidity();
        StaticJsonBuffer<MESSAGE_MAX_LEN> jsonBuffer;
        JsonObject &root = jsonBuffer.createObject();
        root["deviceId"] = DEVICE_ID;
        root["messageId"] = messageId;

        // NAN is not the valid json, change it to NULL
        if (std::isnan(temperature))
        {
            root["temperature"] = NULL;
        }
        else
        {
            root["temperature"] = temperature;
        }

        if (std::isnan(humidity))
        {
            root["humidity"] = NULL;
        }
        else
        {
            root["humidity"] = humidity;
        }

        root.printTo(payload, MESSAGE_MAX_LEN);
    }

    float readTemperature()
    {
        return random(20, 30);
    }

    float readHumidity()
    {
        return random(30, 40);
    }

    static void sendMessage(IOTHUB_CLIENT_LL_HANDLE iotHubClientHandle, char *buffer)
    {
        IOTHUB_MESSAGE_HANDLE messageHandle = IoTHubMessage_CreateFromByteArray((const unsigned char *)buffer, strlen(buffer));
        if (messageHandle == NULL)
        {
            Serial.println("Unable to create a new IoTHubMessage.");
        }
        else
        {
            //MAP_HANDLE properties = IoTHubMessage_Properties(messageHandle);
            //Map_Add(properties, "temperatureAlert", temperatureAlert ? "true" : "false");
            Serial.printf("Sending message: %s.\r\n", buffer);
            if (IoTHubClient_LL_SendEventAsync(iotHubClientHandle, messageHandle, sendCallback, NULL) != IOTHUB_CLIENT_OK)
            {
                Serial.println("Failed to hand over the message to IoTHubClient.");
            }
            else
            {
                messagePending = true;
                Serial.println("IoTHubClient accepted the message for delivery.");
            }

            IoTHubMessage_Destroy(messageHandle);
        }
    }

    static void sendCallback(IOTHUB_CLIENT_CONFIRMATION_RESULT result, void *userContextCallback)
    {
        if (IOTHUB_CLIENT_CONFIRMATION_OK == result)
        {
            Serial.println("Message sent to Azure IoT Hub");
        }
        else
        {
            Serial.println("Failed to send message to Azure IoT Hub");
        }
        messagePending = false;
    }

body:
You need to call IoTHubClient_LL_DoWork until all messages are processed and only after that you can go to sleep.

Check the following code:

    void IoTHubFullSendReceive()
    {
      IOTHUB_CLIENT_STATUS Status;

      while ((IoTHubClient_LL_GetSendStatus(IoTHubClientHandle, &Status) == IOTHUB_CLIENT_OK) && (Status == IOTHUB_CLIENT_SEND_STATUS_BUSY))
      {
          IoTHubClient_LL_DoWork(IoTHubClientHandle);
          ThreadAPI_Sleep(50);
      }
    }


message:
Arduino due temperature reading shows random temperatures

I am using an Arduino Due board to read three temperatures from three separate smt160-30 digital sensors but the program is behaving very randomly. the code I am using is one I got from arduino official site and changed the structure to get three temp readings and display them on a 16x2 lcd. The problem is when I use one sensor the output is reasonable but when I use all three the temperature showing are all off by 4 degrees. also I tried removing the line `lcd.print(temperature1, 1)` and the output temperatures changed. Is this odd behavior because of SRAM issues ? if so how can I find out about it and fix it ?

    #include <LiquidCrystal.h>
    LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

    unsigned long now;
    unsigned long lastSample;
    unsigned int sampleSize;

    unsigned int highCount1;
    unsigned int highCount2;
    unsigned int highCount3;

    unsigned long lastOutput;

    float temperature1;
    float temperature2;
    float temperature3;
    float hcf1, hcf2, hcf3;
    float ssf;

    int sensorPin1 = 23;
    int sensorPin2 = 24;
    int sensorPin3 = 26;

    void setup(){

        pinMode(sensorPin1, INPUT);
        pinMode(sensorPin2, INPUT);
        pinMode(sensorPin3, INPUT);

        digitalWrite(sensorPin1, LOW);
        digitalWrite(sensorPin2, LOW);
        digitalWrite(sensorPin3, LOW);

        lastSample = 0;
        sampleSize = 0;

        highCount1 = 0;
        highCount2 = 0;
        highCount3 = 0;

        temperature1 = 0;
        temperature2 = 0;
        temperature3 = 0;

        lastOutput = 0;

        delay(2000);
        lcd.setCursor(0, 0);

    }

    void loop() {
        now = micros();
        if (now - lastOutput > 3000000) {
            lcd.clear();

            hcf1 = highCount1;
            hcf2 = highCount2;
            hcf3 = highCount3;

            ssf = sampleSize;

            temperature1 = ((hcf1 / ssf) -0.32)/0.0047;
            temperature2 = ((hcf2 / ssf) -0.32)/0.0047;
            temperature3 = ((hcf3 / ssf) -0.32)/0.0047;

            lastOutput = now;
            sampleSize = 0;

            highCount1 = 0;
            highCount2 = 0;
            highCount3 = 0;

            lcd.print(temperature1, 1);
            lcd.print(" ");

            lcd.print(temperature2, 1);
            lcd.print(" ");

            lcd.print(temperature3, 1);

        }
        if (now - lastSample > 50) {
            sampleSize++;
            highCount1 = highCount1 + digitalRead(sensorPin1);
            highCount2 = highCount2 + digitalRead(sensorPin2);
            highCount3 = highCount3 + digitalRead(sensorPin3);
            lastSample = now;
        } else {
            delayMicroseconds(10);
        }
    }

Thank you!

body:
Did you read about this smt160 sensor ? It relies on the calculation of duty cycle of the square wave output from the sensor, to calculate the temparature.

> **temperature = (dutyCycle) -0.32)/0.0047**

The square wave output has to be sampled at 8KHz or at 125us for no loss of information. This block samples that data.

> if (now - lastSample > 50) {
>
sampleSize++;
>
highCount1 = highCount1 + digitalRead(sensorPin1);
>
 highCount2 = highCount2 + digitalRead(sensorPin2);
>
highCount3 = highCount3 + digitalRead(sensorPin3);
>
 lastSample = now;
>     }

> else {
>         delayMicroseconds(10);
>     }

when you increased the number of code lines , information loss also increased, cz more number of instructions have to be executed now , till reaching the corresponding digital reads.


message:
Smart way to map digital pins to a for loop over analogue pins

First post here and I have very little Arduino/c programming knowledge so forgive me my ignorance.

I am processing 18650 cells for a little powerwall project. I am using an Arduino pro mini atmega328p(5v) to read battery slot voltages and to turn on/off the tp4506 when the voltage reaches 3.85 volts for long term storage.

I am getting good voltage readings and after some trouble having a common ground with the tp4506 I think I have isolated it with a couple diodes.

I am using a 30N06L n channel mosfet to switch the tp4506's on and off, shutting them off to get the reading then back on till next voltage reading. I am learning a lot and having fun with it.

My problem stems from me not really having firm grasp of terminology or Arduino C. I cannot find my solution from search engine results after a few hours searching on and off.

I am using a for loop over 3(for now) analogue pins to get my voltage readings. What I can't figure out is how to map those pins to the digital pins controlling the mosfets from the loop. I have a few different versions of this project just trying to get a feel for what is the most efficient way to do it(I like the loop). How do I map or correlate AO with D2 and so forth. It's very frustrating not being able to type what I want out in a way that get's me some code I can learn from so I hope another human can understand my issue.

    const int aRefVoltage = 5.00;
    float voltage         = 0;

    void setup() {
      // put your setup code here, to run once:
      pinMode(2, OUTPUT);
      Serial.begin(9600);
    }

    void loop() {
    // put your main code here, to run repeatedly:
    // read the input on analog pin 0-2

      for (int i = 0; i < 3; i++) {
        int sensorValue = analogRead(i);
        delay(700);

    // float voltage = sensorValue * (aRefVoltage / 1024.0);
        voltage = sensorValue*aRefVoltage/1024.0;
    // print out the value you read:
        Serial.print( F("  Slot-") );
        Serial.print(i + 1); // +1 to match slot number
        Serial.print( F(" = ") );
        Serial.print(voltage);
        Serial.print( F(" Volts") );

        if (i == 2) Serial.println("     ");
        Serial.println( F("") );
      }

    }

What is the smartest way to map analogue "i[0]" to the digital pin 2 to turn on that slots mosfet while using the for loop? Switch case? I hope I was clear enough in my question.

Thank you

edit: inb4 I get chewed out.

I am not looking for the answer to be handed to me. I would like a link to a tutorial that will show me how to use i[1] either in or out of the loop so I can use it....or how to use it.  An explanation from my would be hero would be nice too.

My searches all got me very rudimentary for loop examples and endless tutorials on how to turn analogue pins into digital pins. Surprising amount of tutorials on how to do that out there.

----------

edit 2

A ce pin? That sounds handy I will have to look into that. I am sure my use of diodes would make an engineer shake his head. I have limited supplies on hand and this is really my first project where I have a use for my tinkering.

On each analogue pin I have two 10k resistors. One to pull down and the other to prevent the batteries from sending juice back through the analogue pin.

I spent several hours trying to use the 1.1 volt internal reference but even after calculating what my 1.1 actually was my results were not as accurate and it just seemed like slapping a dmm across the rail and dialing the knob on the buck converter was practical.

https://provideyourown.com/2012/secret-arduino-voltmeter-measure-battery-voltage/
and
    internal1.1Ref = 1.1 * Vcc1 (per voltmeter) / Vcc2 (per readVcc() function)

For diodes I have a 1N4001 between the battery negative on tp4506 chip and  ground. If I did not have it there power was flowing back through the chip. I was also playing with a 3v zener on the positive side to block .5 volts to my analogue reading when no battery present in slot.

I have no doubt I am doing it incorrectly I wasn't expecting those issues and was just trying to hack a solution together, luckily my aim is not charging to 4.2 or I would be up a creek.

Thank you again for taking the time to show me the code I needed. I should be able to figure it out from here. As long as I am moving forward I am content. I had been at it for ten hours by the time I broke down and made this post. I was pretty burnt out and knew if I could just see an example I would be good to go.

----------
edit 3

    const int aRefVoltage        = 5.00;
    const int readVoltagePins[3] = { A0, A1, A2 };
    const int chargePin[3]       = { 2, 3, 4 };
    const int hysteresis         = 0.10;
    float voltage                = 0;

    void setup() {
      // put your setup code here, to run once:
      for (int i = 0; i < 3; i++) {
        pinMode(chargePin[i], OUTPUT);
      }
      Serial.begin(9600);
    }

    void loop() {
      // put your main code here, to run repeatedly:
      // read the input on analog pin 0-2

      for (int i = 0; i < 3; i++) {
        digitalWrite(chargePin[i], LOW);
        delay(1500);
        int sensorValue = analogRead(readVoltagePins[i]);
        float voltage = (float) sensorValue * (5.0 / 1024.0);

        // Write here code to turn on the digital pin on (once) if the voltage
        // is too low and off (once) with hysteresis.
        // The digital pin is: chargePin[i]

        if (voltage <= 1.50) {
          digitalWrite(chargePin[i], LOW);
          Serial.print( F("  Slot-") );
          Serial.print(i + 1); // +1 to match slot number
          Serial.println( F(" = NFG || Empty ") );
          break;
        }

        else if (voltage <= (3.85 - hysteresis)) {
          digitalWrite(chargePin[i], HIGH);
          Serial.print( F("  Slot-") );
          Serial.print(i + 1); // +1 to match slot number
          Serial.print( F(" = ") );
          Serial.print(voltage);
          Serial.println( F(" Volts & Charging") );
        }

        else if (voltage >= (3.85 + hysteresis)) {
          digitalWrite(chargePin[i], LOW);
          Serial.print( F("  Slot-") );
          Serial.print(i + 1); // +1 to match slot number
          Serial.print( F(" = ") );
          Serial.print(voltage);
          Serial.println( F(" Volts & !Charging") );
        }

      }
      delay(5000); // increase later
      for (int i = 0; i < 3; i++) {
          if (i == 2)
          Serial.println("     ");
      }
    }

This is what I have for code for now. I am just leaving the b- disconnected on the cloned charging boards. Let me know what you think @Jot

body:
Is the programming code for A0 to D2 the same as for the other pins ? Then you could put the pin numbers in an array and run them in a for loop.

The TP4056 has a CE pin, why don't you use that to turn then on and off ?

The accuracy of reading a voltage with an Arduino depends on the accuracy of the voltage reference. You use the VCC 5V as reference. Is your 5V a stable and accurate 5.00V ? Did you measure the 5V pin of the Arduino board ?

Did you protect the analog inputs with a resistor ?

What did you do with the diodes ? Can you show a schematic (it can be a photo of a drawing) ?

An array with analog pins and digital pins:

    const int readVoltagePins[3] = { A0, A1, A2 };
    const int chargePins[3] = { 2, 3, 4 };

In the setup, set the digital pins as outputs:

    for (int i=0; i<3; i++)
    {
      pinMode (chargePins[i], OUTPUT);
    }

In the loop, use a similar for-loop. I declare the locally used variables locally.

    for (int i=0; i<3; i++)
    {
      int sensorValue = analogRead(readVoltagePins[i]);
      float voltage = (float) sensorValue * (5.0 / 1024.0);

      // Write here code to turn on the digital pin on (once) if the voltage
      // is too low and off (once) with hysteresis.
      // The digital pin is: chargePins[i]
    }

**Reaction to edit 3**

The idea of StackExchange is to have a question with an answer. Both the question and the answer can be polished along the way to create something that is helpful for others.
Developing a Arduino sketch is something else. I don't know either what the best way is to reply.

What about taking the average value of about 30 (5 to 1000) samples ? If the voltages are not steady, then averaging will help a lot.

The internal voltage reference of 1.1V is not bad, but the actual voltage can be between 1.0 and 1.2V. It is different for each Arduino board. You can measure the AREF pin with a multimeter after setting the 1.1V reference and put the measured voltage in the sketch in the calculation.
If the power to the Arduino board is a good 5.0V and the Arduino is always at the same room temperature, then the internal voltage of 1.1V can be used to measure a battery with 20mV accuracy, and perhaps 5mV with a lot averaging.

You use a delay to slow down the sketch. It is okay to do a digitalWrite over and over again during charging or during idle. In the comment I wrote to do that once, because I was anticipating to use millis instead of delays.

Because of the delay, the if_else_if_else_if is nice and straightforward code.

An integer can not be 5.0 or 0.10. Please check your whole sketch for 'float' versus 'int'. If floating point is needed, then use floating point. The voltage is a 'float', therefor it is best to use 'float' everywhere the voltage is used, for example the hysteresis.

I still don't understand the diodes. Can you make a schematic ?
Using a mosfet is probably okay, but I have to see the schematic.


body:
> What I can't figure out is how to map those pins to the digital pins controlling the mosfets from the loop.

you probably will have to do a better job articulating what "mapping" an analog pin to digital pins means.

If the issue is "associating" an analog pin with a digital pin, a struct would do, like this:

    typedef struct {
      uint8_t apin; //analog pin
      uint8_t dpin; //digital pin associated with the analog pin
    } PIN_TYPE;

    PIN_TYPE pins1, pins2; //two sets of pins

     ...
     if (analogRead(pins1.apin) < BAT_THRESLOW) turn_on(pins1.dpin); //if voltage is too low, start charging it
     if (analogRead(pins2.apin) > BAT_THRESHIGH) turn_off(pins2.dpin); //if voltage is too high, stop charging.

Obviously, the logic should be more comprehensive to avoid oscillation.


message:
Whats wrong with my code?

Basically what i am trying to do is use an ir remote to turn an rgb on/off and have a few preset colors as well as being able to increase/decrease red/green/blue independently. I don't know much about C/C++ so this is really hard to troubleshoot.

<!-- language: lang-c++ -->

    #include <IRremote.h>

    int rbright;
    int gbright;
    int bbright;
    int before;
    int RECV_PIN=12; //data out of IR receiver connects to pin 12
    int redPin=11;
    int greenPin=10;
    int bluePin=9;
    int steps=5;
    IRrecv irrecv(RECV_PIN);
    decode_results results;

    //uncomment this line if using a Common Anode LED
    #define COMMON_ANODE

    void setup()
    {
        before=0;
        rbright=80;
        gbright=0;
        bbright=80;
        irrecv.enableIRIn(); // start the receiver
        pinMode(redPin, OUTPUT);
        pinMode(greenPin, OUTPUT);
        pinMode(bluePin, OUTPUT);
    }

    void loop()
    {
        if (irrecv.decode(&results)) {
            if (results.value==B54A3AC5){ //Code to turn the LED ON/OFF
                if(before==0){ // if the LED was turned off, then we turn it on
                    digitalWrite(redpin,HIGH);
                    digitalWrite(greenpin,HIGH);
                    digitalWrite(bluepin,HIGH);
                    before=1; //LED is now turned on
                }
                else{
                    digitalWrite(redpin,LOW);
                    digitalWrite(greenpin,LOW);
                    digitalWrite(bluepin,LOW); //if the LED was turned on, then we turn it off
                    before=0;
                }
            }
            if (results.value==B54A8A75 && before==1){ //Code to decrease the red
                if(rbright-255/steps<0){
                    analogWrite(redpin,rbright);
                }
                else{
                    rbright=rbright-255/steps;
                    analogWrite(redpin,rbright);
                }
            }
            if (results.value==B54A7A85 && before==1){ //Code to increase the red
                if(rbright+255/steps>255){
                    analogWrite(redpin,rbright);
                }
                else{
                    rbright=rbright+255/steps;
                    analogWrite(redpin,rbright);
                }
            }
            if (results.value==B54AB24D && before==1){ //Code to decrease the green
                if(gbright-255/steps<0){
                    analogWrite(greenpin,gbright);
                }
                else{
                    gbright=gbright-255/steps;
                    analogWrite(greenpin,gbright);
                }
            }
            if (results.value==B54A32CD && before==1){ //Code to increase the green
                if(gbright+255/steps>255){
                    analogWrite(greenpin,gbright);
                }
                else{
                    gbright=gbright+255/steps;
                    analogWrite(greenpin,gbright);
                }
            }
            if (results.value==B54A0AF5 && before==1){ //Code to decrease the blue
                if(bbright-255/steps<0){
                    analogWrite(bluepin,bbright);
                }
                else{
                    bbright=bbright-255/steps;
                    analogWrite(bluepin,bbright);
                }
            }
            if (results.value==B54ACA35 && before==1){ //Code to increase the blue
                if(bbright+255/steps>255){
                    analogWrite(bluepin,bbright);
                }
                else{
                    bbright=bbright+255/steps;
                    analogWrite(bluepin,bbright);
                }
            }
            if (results.value==B54AA956 && before==1){ //Code yellow
                setColor(255, 255, 0);
            }
            if (results.value==B54A2AD5 && before==1){ //Code purple
                setColor(80, 0, 80);
            }
            if (results.value==B54AEA15 && before==1){ //Code aqua
                setColor(0, 255, 255);
            }
            irrecv.resume();
        }

    void setColor(int red, int green, int blue)
    {
    #ifdef COMMON_ANODE
        red = 255 - red;
        green = 255 - green;
        blue = 255 - blue;
    #endif
        analogWrite(redPin, red);
        analogWrite(greenPin, green);
        analogWrite(bluePin, blue);
    }

The errors i get are

> rgbcontrolir_ino.ino: In function ‘void loop()’:
rgbcontrolir_ino.ino:35:24: error: ‘B54A3AC5’ was not declared in this scope
rgbcontrolir_ino.ino:37:20: error: ‘redpin’ was not declared in this scope
rgbcontrolir_ino.ino:38:20: error: ‘greenpin’ was not declared in this scope
rgbcontrolir_ino.ino:39:20: error: ‘bluepin’ was not declared in this scope
rgbcontrolir_ino.ino:43:20: error: ‘redpin’ was not declared in this scope
rgbcontrolir_ino.ino:44:20: error: ‘greenpin’ was not declared in this scope
rgbcontrolir_ino.ino:45:20: error: ‘bluepin’ was not declared in this scope
rgbcontrolir_ino.ino:48:22: error: ‘B54A8A75’ was not declared in this scope
rgbcontrolir_ino.ino:50:19: error: ‘redpin’ was not declared in this scope
rgbcontrolir_ino.ino:54:17: error: ‘redpin’ was not declared in this scope
rgbcontrolir_ino.ino:56:22: error: ‘B54A7A85’ was not declared in this scope
rgbcontrolir_ino.ino:58:19: error: ‘redpin’ was not declared in this scope
rgbcontrolir_ino.ino:62:17: error: ‘redpin’ was not declared in this scope
rgbcontrolir_ino.ino:64:22: error: ‘B54AB24D’ was not declared in this scope
rgbcontrolir_ino.ino:66:19: error: ‘greenpin’ was not declared in this scope
rgbcontrolir_ino.ino:70:17: error: ‘greenpin’ was not declared in this scope
rgbcontrolir_ino.ino:72:22: error: ‘B54A32CD’ was not declared in this scope
rgbcontrolir_ino.ino:74:19: error: ‘greenpin’ was not declared in this scope
rgbcontrolir_ino.ino:78:17: error: ‘greenpin’ was not declared in this scope
rgbcontrolir_ino.ino:80:22: error: ‘B54A0AF5’ was not declared in this scope
rgbcontrolir_ino.ino:82:19: error: ‘bluepin’ was not declared in this scope
rgbcontrolir_ino.ino:86:17: error: ‘bluepin’ was not declared in this scope
rgbcontrolir_ino.ino:88:22: error: ‘B54ACA35’ was not declared in this scope
rgbcontrolir_ino.ino:90:19: error: ‘bluepin’ was not declared in this scope
rgbcontrolir_ino.ino:94:17: error: ‘bluepin’ was not declared in this scope
rgbcontrolir_ino.ino:96:22: error: ‘B54AA956’ was not declared in this scope
rgbcontrolir_ino.ino:100:24: error: ‘B54A2AD5’ was not declared in this scope
rgbcontrolir_ino.ino:104:24: error: ‘B54AEA15’ was not declared in this scope
rgbcontrolir_ino.ino:112:5: error: a function-definition is not allowed here before ‘{’ token
rgbcontrolir_ino.ino:121:5: error: expected ‘}’ at end of input

body:
The errors are self-explanatory. You just have to read them carefully.

> ‘B54A3AC5’ was not declared in this scope

The compiler doesn't know what "B54A3AC5" means. Nor do I, but I _gess_
you may mean an hexadecimal 32-bit value. If that's the case, write it
with the prefix "0x", as in `0xb54a3ac5`.

> ‘redpin’ was not declared in this scope

Same thing, it doesn't know what "redpin" is. Oh, wait, you have
declared a variable named `redPin`. Maybe that is what you meant:
"redPin", with an uppercase "P".

> a function-definition is not allowed here before ‘{’ token

You tried to define `setColor()` _within_ the `loop()` function. You
cannot define a function within a function in C++ (well, you can have
lambdas, but that's irrelevant to your problem).

Had you tried to indent your code properly (like I did in my edit), the
error would have been obvious: there is no closing brace to match the
opening one at the start of `loop()`.

> expected ‘}’ at end of input

Another symptom of the problem above.

------------------------------------------------------------------------

**Edit**: After reading your code, I have a few suggestions for making
it clearer are more efficient:

1. Declare all the constants with the `const` keyword, at the beginning
   of your program. A common convention is to write them in all caps
   with underscores, to distinguish them from variables.
2. Avoid "magic numbers" within your code (e.g. the IR codes), and use
   properly named constants instead.
3. `before` is hard to understand, give it a name that makes sense. I
   suggest `leds_are_on`. And make it a `bool`, because it can only be
   either `true` or `false`.
4. One way to avoid deeply nested loops is to use `return` statements to
   get out of `loop()` as soon as you know you have nothing to do.

With these suggestions, I would start the program like this:

<!-- language-all: lang-c++ -->

    #include <IRremote.h>

    // Pinout.
    const int RECV_PIN  = 12;  // data out of IR receiver
    const int RED_PIN   = 11;
    const int GREEN_PIN = 10;
    const int BLUE_PIN  = 9;

    // Number of steps between black and full brightness.
    const int STEPS     = 5;

    // IR codes.
    const uint32_t CODE_ON_OFF     = 0xb54a3ac5;
    const uint32_t CODE_LESS_RED   = 0xb54a8a75;
    const uint32_t CODE_MORE_RED   = 0xb54a7a85;
    const uint32_t CODE_LESS_GREEN = 0xb54ab24d;
    const uint32_t CODE_MORE_GREEN = 0xb54a32cd;
    const uint32_t CODE_LESS_BLUE  = 0xb54a0af5;
    const uint32_t CODE_MORE_BLUE  = 0xb54aca35;
    const uint32_t CODE_YELLOW     = 0xb54aa956;
    const uint32_t CODE_PURPLE     = 0xb54a2ad5;
    const uint32_t CODE_AQUA       = 0xb54aea15;

    bool leds_are_on;
    int r_bright;
    int g_bright;
    int b_bright;
    IRrecv irrecv(RECV_PIN);

and the `loop()` would be like this:

    void loop()
    {
        decode_results results;
        if (!irrecv.decode(&results))
            return;

        // If the LEDs are OFF, the only valid action is to turn them
        // ON.
        if (!leds_are_on) {
            if (results.value == CODE_ON_OFF) {
                digitalWrite(RED_PIN,   HIGH);
                digitalWrite(GREEN_PIN, HIGH);
                digitalWrite(BLUE_PIN,  HIGH);
                leds_are_on = true;
            }
            irrecv.resume();
            return;
        }

        // The LEDs are ON: all codes are valid.
        switch (results.value) {
            case CODE_ON_OFF:  // turn OFF
                digitalWrite(RED_PIN,   LOW);
                digitalWrite(GREEN_PIN, LOW);
                digitalWrite(BLUE_PIN,  LOW);
                leds_are_on = false;
                break;
            case CODE_LESS_RED:
                r_bright = constrain(r_bright - 255/steps, 0, 255);
                analogWrite(RED_PIN, r_bright);
                break;
            case CODE_MORE_RED:
                r_bright = constrain(r_bright + 255/steps, 0, 255);
                analogWrite(RED_PIN, r_bright);
                break;
            // etc...
        }
        irrecv.resume();
    }


body:
1) You are missing the braces for void loop()

2) Oops !! You have to double check - red**p**in and red**P**in etc. Case sensitive !


message:
L and ON keeps blinking

I am not sure why the `ON` LED and the `L` LED keeps blinking on my Arduino.

I was just trying to implement a simple circuit using breadboard, and everything worked fine until I unplugged one wire with the power turned on. I accidentally made the wire touch something in the Arduino, and the LED in the breadboard became extremely bright. Then the `ON` LED and the `L` LED in the Arduino started to keep blinking, and I cannot download code to Arduino anymore. I am using IAR and IAR says `AT91SAM3 reset: Communication breakdown after resetting target. Abort debug session?`.

I think maybe there is a short cut when the wire touched the Arduino... But how can I determine what the problem is? Thank you very much, I am totally new to Arduino and has very limited knowledge about hardware...

body:
You should split your problem in pieces. Like you cannot get communication with your Arduino again, so check first:

- If you plug in the Arduino / USB, do you get a message on your computer?
- Is it visible in the systems manager?
- Is it visible by the IDE?
- If you connect an adapter (12 or 9V), does it make a difference?
- If you try another Arduino, does it work like it should be?

If you are a beginner, always make sure:

- Never change any wiring with the Arduino on
- Never have dangling wires, if you do not need a wire for the time being, either remove it completely or put it in a breadboard hole that is not used
- Never change components with the Arduino on
- After rewiring/adding/changing components, double check first

Update for comment below because it does not fit as comment:
To buy a cheap/fake (but working) Arduino uno, e.g.
[Arduino Uno from Aliexpress][1]

  [1]: https://www.aliexpress.com/item/Free-shipping-UNO-R3-MEGA328P-with-usb-cable-for-Arduino-Compatible-Dropshipping/32241237838.html?spm=2114.search0104.3.17.u1gbjG&ws_ab_test=searchweb0_0,searchweb201602_4_10152_10065_10151_10344_10068_10345_10342_10343_10340_10341_10541_10562_10084_10083_10304_10307_10301_10177_10060_10155_5680017_10154_10056_10055_10539_10537_10312_10536_10059_10313_10314_10534_10533_100031_10103_10073_10102_10557_10142_10107,searchweb201603_25,ppcSwitch_7&btsid=74489aca-62ba-4565-b712-838d7fb5f5d1&algo_expid=4aeaf1be-d6ec-4fc5-8988-7534ccd34d9b-2&algo_pvid=4aeaf1be-d6ec-4fc5-8988-7534ccd34d9b


message:
How to refine ultrasonic readings

I am trying to filter ultrasonic readings using averaging technique. I've also used `millis()` to measure time from start so that I can calculate readings up to 1 second and average them. I've re-initialized the `elapsedTime` variable each time to zero in the loop but again when the program execution hits this code the time starts from the time it was before. Is there any way to solve this problem?

This is the code:

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

    NewPing sonar(TRIGGER_PIN, ECHO_PIN, MAX_DISTANCE); // NewPing setup of pins and maximum distance.

    int dist, ctr, filteredDist;
    long rawValue = 0;
    unsigned long StartTime = millis();

    void setup() {
      Serial.begin(115200); // Open serial monitor at 115200 baud to see ping results.
    }
    //********************************************************************************************************************
    void loop() {
      delay(500);
      unsigned long elapsedTime = StartTime;

      while (elapsedTime < 1000) {
        ctr++;
        dist = sonar.ping_cm();
        rawValue += dist;
        elapsedTime = millis();
      }
      filteredDist = rawValue / ctr;
      Serial.println(filteredDist);
    }

body:
`elapsedTime=millis();` sets `elapsedTime` equal to the current value of `millis()`, which in the sketch above is the total time since the Uno powered up.  Thus  `elapsedTime` will exceed 1000 any time after the first second of execution, in which case the `while` won't do anything.

Instead say `elapsedTime=millis() - StartTime;` within the loop.  Whenever you want to start the averaging cycle again, say `StartTime = millis();`.

If your only use of `elapsedTime` is to control the `while` loop, get rid of that variable; instead of  `while(elapsedTime < 1000)`, say `while(millis()-StartTime < 1000)`.


message:
NodeMCU and expected ';' before wrong ' " '

I am creating a home weather station but the Arduino IDE shows

    "expected ';' before 'viewport'".

It detects wrong quotation marks. My code:

         String message2 = "<!DOCTYPE html>";
      message2 += "";
      message2 +=  "<title>Bootstrap Example</title>";
      message2 += " <meta name="viewport" content="width=device-width, initial-scale=1">";
      message2 += "<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">";
      message2 +=  "";
      message2 +=  "";
      message2 += "";
      message2 += "";
      message2 += "
";
      message2 +=  "
Teplotná Stanica
";
      message2 +=  "
Teplota:";
      message2 +=  dht.readTemperature();
      message2 +=  "
";

      server.send(200, "text/html", message2);}

Can someone tell me what´s wrong?
I am using Arduino IDE

body:
In C you can not use quotation marks inside quotation marks (thus nested).

Replace

    message2 += " <meta name="viewport" content="width=device-width, initial-scale=1">";

to

    message2 += " <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">";

By using the escape character \  it means that \" is a character (")  instead of the beginning or start of a string.