body:
A series resistor is needed to prevent excess current thru the LED or thru the IO pin. 270 ohm to 1K ohm works well.

<!-- 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/z4sx1.png)

<!-- End schematic -->

The internal pullup in the Arduino processer is 30-50K ohm. The external resistor is a current limit resistor. (5V - Vf-led)/resistor = current.
(5V - 2.2V)/270 ohm = 10.3mA. Vf of the LED will vary by color from say 2.2V for a Red to 3.5V for a blue or white.  Insert values if known, or use a 270 to 1K resistor and measure Vf across the LED, then adjust resistor as needed for desired brightness (more current = brighter).


sender: user

message:
Do I need a pull-up/down resistor for button LED circuit?

When reading up on how to make a circuit that turns an LED on when a button is held down, I keep finding people saying a pull up or down resistor must be involved, to avoid the flickering state of the LED seen with a floating pin. There's also code being implemented, where the state of a pin is read and monitored as the button is pressed down or left raised. What I don't understand, is why this is all necessary. Surely it isn't, considering the circuit below allows the button to be pressed with the LED turning on/off depending on the state of the button.

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

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

I made this circuit before drawing it online, and it works exactly as intended. No need for a pull up/down resistor or any code. I must be missing something here, can anyone please explain? It works perfectly with a buzzer as well.

Many thanks.

sender: assistant

body:
No, you don't.

The thing to remember is that you don't put a pulldown (or pullup) resistor on the *button* - you actually put it on the *input*.

And since you aren't using an input there is nowhere to put the resistor.

A pullup or pulldown resistor is used to set an input to a pre-defined state. The button or switch is then used to override that pre-defined state.  With your circuit you are just controlling the flow of electrons around a simple loop, from power, through resistor, through LED and back to power. The button just completes that circuit.  There is no "input" to place into a pre-defined state. Hence no pullup or pulldown resistor.


message:
Need help with the syntax for a function that takes a closure

My C++ is very out-of-date. (20+ years, before C++ *had* closures).

I'm a senior SW engineer, and I spent several hours yesterday trying to figure this out, but I could not work it out.

**The background:**

I'm trying to create a class, `ClosureButton`, that is a subclass of another class, `ArduinoObject`. (An `ArduinoObject` has `setup()`, `start()`, `stop()`, and `loop()` methods so that the main program can invoke it.)

(C++ uses the terms closure and lambda to mean different things. In other languages the terms are interchangeable. Forgive me if I'm not using the correct term.)

A ClosureButton's constructor would take a pin number, and a closure with a bool parameter (`pressed`). I would save that closure to a member variable. When the button's state changed, it would invoke the closure and pass the new button state to the closure.

**The question:**

I need help with the syntax for the constructor, as well as how to declare the instance variable that would hold the closure.

The constructor would look something like this:

    ClosureButton::ClosureButton(uint8_t pin, _unkonwn_syntax_ closure);

(Where I need help with the `_unkonwn_syntax_` bit.)

Then I need to declare a member variable on my ClosureButton to hold the closure:

    class ClosureButton: ArduinoObject {
      //other stuff
      _other_unkonwn_syntax_ closure;
    }

Again, I need help with the syntax to declare a member variable `closure` of type "closure that takes a bool parameter". (The `_other_unkonwn_syntax_` bit.) At this point I don't think my closure will capture variables from its enclosing scope, but at some future date I might need to do that, so help with that would be appreciated as well.)

body:
There is no difference using a function pointer or a simple (non-capturing) lambda (C++ calls them lambdas).  The only difference is that you provide a lambda instead of a function pointer.

For example:

    void (*func)(bool b);

    void setup() {
     func = [](bool b) {
      Serial.println(b);
     };

     Serial.begin(115200);
    }

    void loop() {
     func(digitalRead(0));
    }

It's just a normal function pointer, but instead of assigning a function pointer to it you assign a lambda to it - which is just an anonymous function pointer.

To make life easier you can make a typedef for your function pointer variable type:

    typedef void (*buttonCallback)(bool);

Then your functions would look like:

    ClosureButton::ClosureButton(uint8_t pin, buttonCallback closure);

and:

    class ClosureButton: ArduinoObject {
      //other stuff
      buttonCallback closure;
    }

The basic syntax of a lambda is quite straight forward:

    [](bool foo, int bar) { ... }
    ^  ^                    ^
    |  |                    +- Function body
    |  +- Normal parameter list
    +- Empty capture list

If you want to return a value and you don't want to rely on the function being an "auto" return type you can specify the return type after the parameter list:

    [](bool foo, int bar)->int { ... }
    ^  ^                   ^     ^
    |  |                   |     +- Function body
    |  |                   +- Return type
    |  +- Normal parameter list
    +- Empty capture list

If you don't specify the return type it is inferred from the type of variable/value that is used with `return` (as if the function were `auto`).

----

Here's a full example passing the lambda to a class which stores the pointer to it in a variable to call later:

    typedef int (*callback)(bool b);

    class MyClass {
     private:
      callback func;
      int pin;

     public:
      MyClass(int pinno, callback myfunc) {
       func = myfunc;
       pin = pinno;
      }

      void doit() {
       Serial.println(func(digitalRead(pin)));
      }
    };

    MyClass foo(3, [](bool b)->int {
      Serial.println(b);
      return rand();
    });

    void setup() {
     pinMode(3, INPUT_PULLUP);
     Serial.begin(115200);
    }

    void loop() {
     foo.doit();
     delay(100);
    }

----

If you want to do capturing with your lambdas then I'm afraid you're out of luck.

The data type for that kind has to be `std::function<void>` but unfortunately the cut-down C library AVR-LIBC doesn't support that. The STL is generally not included for small microcontrollers since it uses far too many resources to be practical.


body:
I suggested in a comment that a functor may be a viable alternative to a
capturing lambda. This answer is mostly meant to answer the OP's request
to elaborate on that suggestion.

Let's define a `ButtonCallback` as an object that can be called like a
function taking a single boolean parameter:

    class ButtonCallback {
    public:
        virtual void operator()(bool) = 0;
    };

To break down the syntax:

* `void operator()(bool)` declares a method that allows the object to be
  called as if it were a function taking a `bool` argument and returning
  nothing. In other words, if you issue a call such as
  `my_object(true)`, that method will be called.
* `virtual _method_declaration_ = 0;` says that the method is not going
  to be defined for this class (it's a “pure virtual method”), but it
  can be defined by derived classes. A class with such a method is
  called an “abstract class”: it defines an interface, it cannot be
  instantiated, and it's meant to be used as a parent for classes that
  do implement the missing methods.

Now the `Button` class can be defined like this:

    class Button {
    public:
        Button(uint8_t pin, ButtonCallback &callback)
        : pin(pin), callback(callback) {}
        void push() {  // for testing only
            Serial.print("press: ");   callback(true);
            Serial.print("release: "); callback(false);
        }
    private:
        uint8_t pin;
        ButtonCallback &callback;
    };

Notice that the callback is stored as a _reference_ to a
`ButtonCallback` object. The object itself cannot be stored because it
has an abstract type. Alternatively, a pointer could be used, which
would practically be equivalent.

For using this class, you first have to create the callback as a
concrete class that inherits from from `ButtonCallback`. Any data you
wish to capture should be stored as class data:

    class CapturingLambda : public ButtonCallback {
    public:
        CapturingLambda(int data) : some_data(data) {}
        virtual void operator()(bool pressed) {
            if (pressed)
                Serial.println(some_data);
            else
                Serial.println(0);
        }
    private:
        int some_data;
    };

With all this in place, the following test:

    void setup() {
        Serial.begin(9600);
        int data_to_capture = 42;
        CapturingLambda callback(data_to_capture);
        Button the_button(2, callback);
        the_button.push();
    }

    void loop(){}

outputs:

    press: 42
    release: 0

Did you said you “find the syntax of C++ pretty obtuse”? I can only
concur with you!

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

**Addendum**: Another alternative is to define the callback using the
good old C idiom: a “lambda” is the combination of a function pointer
and a generic data pointer. The function pointer looks like this:

    typedef void (*ButtonCallback)(bool, void *);

The second argument is used to provide the callback whatever data it is
supposed to have “captured”. It is a generic pointer (a `void *`)
because the library does not know what kind of data its client may need.
Now the `Button` class has to store _both_ the function pointer and the
data pointer, and always provide the data pointer to the callback:

    class Button {
    public:
        Button(uint8_t pin, ButtonCallback callback, void *callback_data)
        : pin(pin), callback(callback), callback_data(callback_data) {}
        void push() {  // for testing only
            Serial.print("press: ");   callback(true, callback_data);
            Serial.print("release: "); callback(false, callback_data);
        }
    private:
        uint8_t pin;
        ButtonCallback callback;
        void *callback_data;
    };

The user would have to decide what kind of data it needs, and do
explicit pointer casts to/from the proper pointer type and `void *`. For
example, assuming we need an `int`, the callback may be:

    void callback(bool pressed, void *data) {
        int *actual_data = (int *) data;
        if (pressed)
            Serial.println(*actual_data);
        else
            Serial.println(0);
    }

Here is the test, with the exact same output as before:

    void setup() {
        Serial.begin(9600);
        int data_to_capture = 42;
        Button the_button(2, callback, (void *) &data_to_capture);
        the_button.push();
    }

    void loop(){}

Notice that, syntactic differences apart, this solution does essentially
the same as the previous one. The main difference is that the data is
given to the callback as an explicit pointer instead of the implicit
`this` pointer. If you have to choose between these two solutions, I
would suggest going for whichever syntax _you_ find easier to work with.

Beware also that in both cases it is the programmer's responsibility to
manage the storage of the callback data and make sure the corresponding
reference (or pointer) remains valid throughout the lifetime of the
`Button` object.


message:
Need some help on a very small project

Apologies for the simple question, I really couldn’t find any help online with this as when I kept searching, the results had lights that had way too much voltage compared to what I need.

So I have a simple light decoration that requires around 3v and comes with a battery pack to power it (2AA batteries) and I took it apart and was able to connect them via a breadboard to test if is all working.

How do incorporate the Arduino into it so that I can switch the lights on through the Arduino? A lot of the small voltage videos I saw were just simple connecting 1 LED through a digital pin but that’s not enough current for the lights I have and I’m not experienced enough to find myself a solution so help would be greatly appreciated.

For little more info, the 3.3v and 5v pins my Arduino (uno) are already taken up.

Also, I’ll be turning the lights on and off with an IR Remote which I’ve already programmed to a servo that’s powered through the USB supply (5v) and the IR Sensor is connected to the 3.3V.

Sorry if the question was badly worded.

body:
I think I managed to make a little circuit that should prevent you from burning up your Arduino.

[![Safely driving MOSFET from Arduino][1]][1]

From what I read you shouldn't connect MOSFET directly to Arduino. Imagine that MOSFET has a little capacitor inside it, and in the beginning that capacitor can take such high current that actually can burn the Arduino pin. Instead you use a simple NPN transistor (with 100kohm resistor) as a "switch". The NPN can survive much higher current, and it will not strain the Arduino pin.

When I simulated this setup using the default "blink" sketch the light bulb was lit when PIN13 was HIGH. Just note that there always is a small voltage drop (think of it as a resistor inside the MOSFET) and it can make the MOSFET get a little warm. In your setup it should not be a problem, but in some cases it's nice to screw a radiator on the MOSFET.

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


message:
Arduino IDE / Specified folder/zip file does not contain a valid library

I trying to add library here but it doesn't seem to work https://github.com/esp8266/Arduino

This happens
"Specified folder/zip file does not contain a valid library"

This problem make me no longer upload any library. any solution about this??
Manual installation does not either.

body:
You don't install that repository as a Arduino library.

**Read the [README file][1] in that repo**. It explains how to install it using the Arduino IDE Board manager. That's the correct way to install it.

  [1]: https://github.com/esp8266/Arduino/blob/master/README.md


message:
Arduino hangs after some time

I am using Atmega328p with 5V power supply,
My Arduino getting hangs [or auto restarts] after some times.

I am using libraries:

- Wire.h
- CRC32.h
- EEPROM.h
- Arduino.h
- TimerOne.h
- RtcDS3231.h
- SoftwareSerial.h
- Adafruit_NeoPixel.h
- avr/wdt.h

I have tried to search, some people are deny to use software serial library.

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

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

body:
Not sure if this will fix your problem, but this is a major error:

      char buf1[8], buf2[6];
      sprintf(buf1, "lu", myvote.mydate);
      sprintf(buf2, "lu", myvote.mytime);

Take a look at [sprintf function reference][1]

> A terminating null character is automatically appended after the content.

So, the text buffers are too small. It should be at least:

    char buf1[9], buf2[7];

  [1]: http://www.cplusplus.com/reference/cstdio/sprintf/


message:
About Wemos D1 WiFi

I bought the Wemos D1 WiFi and I am wondering how to operate this. So, inside the Arduino IDE, I downloaded ESP8266 boards, I see WeMos D1 mini, WeMos D1 R1, and WeMos mini Pro/Lite.

Why in the world don't I see Wemos D1?

How can I operate this board without the D1 board to select in the Arduino IDE?

Is there a way to add, or anyways to operate it?

I don't mind using other software besides the Arduino IDE if it's the only way to work with D1.

Board:

[![WeMos D1][1]][1]

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

I get this Error when trying to upload D1 R1:

    C:\...\ArduinoData\packages\esp8266\tools\esptool\2.5.0-3-20ed2b9/esptool.exe -vv -cd nodemcu -cb 115200 -cp COM6 -ca 0x00000 -cf
    C:\...\Temp\arduino_build_179604/sketch_jan15a.ino.bin
    esptool v0.4.13-1-gf80ae31 - (c) 2014 Ch. Klippel <ck@atelier-klippel.de>
 setting board to nodemcu
 setting baudrate from 115200 to 115200
 setting port from COM1 to COM6
 setting address from 0x00000000 to 0x00000000
 espcomm_upload_file
 espcomm_upload_mem
 setting serial port timeouts to 1000 ms
    opening bootloader
    resetting board
    trying to connect
 flush start
    An error occurred while uploading the sketch
 setting serial port timeouts to 1 ms
 setting serial port timeouts to 1000 ms
 flush complete
 espcomm_send_command: sending command header
 espcomm_send_command: sending command payload
 read 0, requested 1
    trying to connect
 flush start
 setting serial port timeouts to 1 ms
 setting serial port timeouts to 1000 ms
 flush complete
 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
 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 287488 bytes from
    C:\...\arduino_build_179604/sketch_jan15a.ino.bin to flash at 0x00000000
 erasing flash
 size: 046300 address: 000000
 first_sector_index: 0
 total_sector_count: 71
 head_sector_count: 16
 adjusted_sector_count: 55
 erase_size: 037000
 espcomm_send_command: sending command header
 espcomm_send_command: sending command payload
 setting serial port timeouts to 15000 ms
 read 0, requested 1
 setting serial port timeouts to 1000 ms
    warning: espcomm_send_command: didn't receive command response
    warning: espcomm_send_command(FLASH_DOWNLOAD_BEGIN) failed
    closing bootloader
 flush start
 setting serial port timeouts to 1 ms
 setting serial port timeouts to 1000 ms
 flush complete
    error: espcomm_upload_mem failed

body:
Your board is a WeMos D1 R1. You need to select **Tools > Board > WeMos D1 R1** in the Arduino IDE.

Here's a good comparison of the difference between the WeMos D1 R1 and the WeMos D1 R2:
https://github.com/arendst/Sonoff-Tasmota/wiki/Wemos-D1-R1-&-R2


message:
iBus transmission and read it in Arduino

I am using an Arduino Uno and I want to transmit data from FSi6 to FS-iA6B and read received data in an Arduino. After searching, I found the below link which is **iBUStelemetry**.

[iBustelemetry][1]

I am not able to make out how to get the data from this library and print it on the serial monitor.

I have hooked up receiver ground and power pins to ground and power pins of Arduino. Signal from the receiver is connected to D2.

The author has included an example, but I am not much clear how data is read and printed on the serial monitor.

Can someone please help by telling how do I read data from receiver using this library?

  [1]: https://github.com/Hrastovc/iBUStelemetry

body:
If I understand correctly, the code should look like this.

    #include <iBUStelemetry.h>
    iBUStelemetry telemetry(4);
    byte i;

    void setup(){
     Serial.begin(115200);
     telemetry.begin(115200);
     telemetry.addSensor(2);
    }

    void loop(){
     telemetry.setSensorMeasurement(1, i++);
     delay(1000);
     Serial.println(telemetry);
     //or
     Serial.println(telemetry.setSensorMeasurement(1, i++));
    }


message:
Split up Arduino code into multiple files using Arduino IDE

I am working on a very long code that requires multiple functions defined. I want to split the code into two files as main code ("Feeder_Control" in the screenshot) and functions ("connections" in the screenshot) How to import the second file into main code to use its functions?

PS: In C/C++ same thing is done with #include "connections.h". How is it done in Arduino IDE.

[![look here][1]][1].

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

body:
There is no need to use an `#include` directive for the additional .ino file.

Before compilation starts, the Arduino IDE concatenates all .ino files in your sketch into a single file, starting with the .ino file that matches the sketch folder name, followed by the rest of the .ino files in alphabetical order. So there is no difference between one massive .ino file and breaking the same code among multiple .ino files, other than the greater ease of navigating the code via tabs. After a bit more processing, this file is compiled as C++.

Reference:
https://arduino.github.io/arduino-cli/latest/sketch-build-process/#pre-processing


message:
Error code board and boards.txt? Formatting error? cannot verify alarm.txt or any

Arduino: 1.8.8 (Windows 10), Board: "Arduino/Genuino Uno"

Error reading file (E:\arduino\arduino-1.8.8\hardware\arduino\avr**\boards.txt:0**): **Invalid line format, should be 'key=value'**

Error compiling for board Arduino/Genuino Uno.[/b]

This report would have more information with
"Show verbose output during compilation"
option enabled in File -> Preferences.

I was trying to do this experiment: http://wirebeings.com/arduino-intruder-alarm.html

but with Arduino Uno + geeetech iduino yun shield setup.

http://www.geeetech.com/wiki/index.php/Iduino_Yun_Shield

Please help (also short do you short the two pins properly?)

this is the board.txt file:

    unoyun.name=Arduino Uno --Iduino Yún
    unoyun.upload.via_ssh=true
    unoyun.vid.0=0x2341
    unoyun.pid.0=0x0043
    unoyun.vid.1=0x2341
    unoyun.pid.1=0x0001
    unoyun.upload.tool=avrdude
    unoyun.upload.protocol=arduino
    unoyun.upload.maximum_size=32256
    unoyun.upload.maximum_data_size=2048
    unoyun.upload.speed=57600
    unoyun.upload.disable_flushing=true
    unoyun.upload.use_1200bps_touch=true
    unoyun.upload.wait_for_upload_port=true
    unoyun.bootloader.tool=avrdude
    unoyun.bootloader.low_fuses=0xff
    unoyun.bootloader.high_fuses=0xde
    unoyun.bootloader.extended_fuses=0x05
    unoyun.bootloader.file=optiboot/optiboot_atmega328.hex
    unoyun.bootloader.unlock_bits=0x3F
    unoyun.bootloader.lock_bits=0x0F
    unoyun.build.mcu=atmega328p
    unoyun.build.f_cpu=16000000L
    unoyun.build.board=AVR_YUN
    unoyun.build.core=arduino
    unoyun.build.variant=standard

and this is the boards.txt file:

    # See: http://code.google.com/p/arduino/wiki/Platforms

    menu.cpu=Processor

    ##############################################################

    yun.name=Arduino Yún
    yun.upload.via_ssh=true

    yun.vid.0=0x2341
    yun.pid.0=0x0041
    yun.vid.1=0x2341
    yun.pid.1=0x8041
    yun.vid.2=0x2A03
    yun.pid.2=0x0041
    yun.vid.3=0x2A03
    yun.pid.3=0x8041

    yun.upload.tool=avrdude
    yun.upload.protocol=avr109
    yun.upload.maximum_size=28672
    yun.upload.maximum_data_size=2560
    yun.upload.speed=57600
    yun.upload.disable_flushing=true
    yun.upload.use_1200bps_touch=true
    yun.upload.wait_for_upload_port=true

    yun.bootloader.tool=avrdude
    yun.bootloader.low_fuses=0xff
    yun.bootloader.high_fuses=0xd8
    yun.bootloader.extended_fuses=0xfb
    yun.bootloader.file=caterina/Caterina-Yun.hex
    yun.bootloader.noblink=caterina/Caterina-Yun-noblink.hex
    yun.bootloader.unlock_bits=0x3F
    yun.bootloader.lock_bits=0x2F

    yun.build.mcu=atmega32u4
    yun.build.f_cpu=16000000L
    yun.build.vid=0x2341
    yun.build.pid=0x8041
    yun.build.usb_product="Arduino Yun"
    yun.build.board=AVR_YUN
    yun.build.core=arduino
    yun.build.variant=yun
    yun.build.extra_flags={build.usb_flags}

    ##############################################################

    uno.name=Arduino/Genuino Uno

    uno.vid.0=0x2341
    uno.pid.0=0x0043
    uno.vid.1=0x2341
    uno.pid.1=0x0001
    uno.vid.2=0x2A03
    uno.pid.2=0x0043
    uno.vid.3=0x2341
    uno.pid.3=0x0243

    uno.upload.tool=avrdude
    uno.upload.protocol=arduino
    uno.upload.maximum_size=32256
    uno.upload.maximum_data_size=2048
    uno.upload.speed=115200

    uno.bootloader.tool=avrdude
    uno.bootloader.low_fuses=0xFF
    uno.bootloader.high_fuses=0xDE
    uno.bootloader.extended_fuses=0xFD
    uno.bootloader.unlock_bits=0x3F
    uno.bootloader.lock_bits=0x0F
    uno.bootloader.file=optiboot/optiboot_atmega328.hex

    uno.build.mcu=atmega328p
    uno.build.f_cpu=16000000L
    uno.build.board=AVR_UNO
    uno.build.core=arduino
    uno.build.variant=standard

    ##############################################################

    diecimila.name=Arduino Duemilanove or Diecimila

    diecimila.upload.tool=avrdude
    diecimila.upload.protocol=arduino

    diecimila.bootloader.tool=avrdude
    diecimila.bootloader.low_fuses=0xFF
    diecimila.bootloader.unlock_bits=0x3F
    diecimila.bootloader.lock_bits=0x0F

    diecimila.build.f_cpu=16000000L
    diecimila.build.board=AVR_DUEMILANOVE
    diecimila.build.core=arduino
    diecimila.build.variant=standard

body:
nvm, apparently some guys suggesting utf-8 bom encoding change or something because I saw 1 question related to this

(it didn't work)

then I changed it to utf-8 encoding

(both done through notepad++)

it worked.


body:
John Doe, thanks for the tip about utf-8.

I just ran into this exact problem.  boards.txt had been hand-edited in Windows Notepad and saved as utf-8 and was throwing this error.

    Arduino: 1.8.10 (Windows 10), Board: "Arduino/Genuino Uno"
    loading hardware from C:\Program Files (x86)\Arduino\hardware:
    loading package arduino: loading platform release:
    Error reading file (C:\Program Files (x86)\Arduino
    \hardware\arduino\avr\boards.txt:0):
    Invalid line format, should be 'key=value'

I changed the text file format to ANSI and saved, and that fixed the problem, able to compile.  At this point, guessing that maybe changing format merely cleaned up a defect, I saved again to utf-8, but it broke again.  Thus back to ANSI.


message:
Serial not declared in this scope, newbie mistake most likely

Ok, newguy with a little VBA coding experience going to pull hair out soon. It is probably a simple thing I have missed but I would like someone to point out where I went wrong. I modified a sketch that used an lcd to use the serial monitor instead but I sometimes run into this "not declared in this scope" issue. Doing something wrong, please point me in the correct direction.

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

    RTC_DS3231 rtc;
    DateTime now;
    char daysOfTheWeek[7][12] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};

    void showDate(void);
    void showTime(void);
    void showDay(void);

    void showDate()
    {
      serial.print(now.day());
      serial.print('/');
      serial.print(now.month());
      serial.print('/');
      serial.print(now.year());
    }

    void showDay()
    {
      serial.print(daysOfTheWeek[now.dayOfTheWeek()]);
    }

    void showTime()
    {
      serial.print("Time:");
      serial.print(now.hour());
      serial.print(':');
      serial.print(now.minute());
      serial.print(':');
      serial.print(now.second());
      serial.print("    ");
    }

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

      serial.println("working....")
      //wire.begin();
      //delay(2000);
      if (! rtc.begin())
      {
        Serial.println("Couldn't find RTC Module");
        while (1);
      }

      if (rtc.lostPower())
      {
        Serial.println("RTC lost power, lets set the time!");
        rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
      }
      rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
    }

    void loop ()
    {
      now = rtc.now();
      showDate();
      showDay();
      showTime();
    }

body: Case matters in C/C++. You should write `Serial` rather than `serial`.


message:
Failsafe Arduino

I want to read an RFID tag using an Arduino, which controls some relais. This is easy.

For me the more complex part is to build it fault-tolerant. So I thought I could use the watchdog. The tricky part is, my relais module should keep a certain state (change of state is rare), no matter what happens to the Arduino.

My first thought was to put some condensators to the relais. Calculate the RC component so it can last the watchdog timeout plus booting up.

Now there is the problem, that the relais module is keeping its state while booting. I guess I can't use a pull up/down resistor, since the state of the relais can be low or high at random.

My second thought was using a latch relay. But this has the disadvantage, that it probably can hide problems. For example if the arduino died, and the latch relay holds a certain state, it masks the problem. In that case it's not possible to notice a faulty Arduino.

1. Those are the reasons I tend to think condensators are better?

2. Are those ideas feasible? Are there easier ways to accomplish this?

3. Are there more problems to think about?

(I was already reading about millis at [gammon's page][1]. Apparently it's not a problem after all.)

  [1]: http://gammon.com.au/millis

body:
Consider constraining your design with clear requirements.  As it is highly unlikely any design can protect its self for all situations.

>my relais module should keep a certain state (change of state is rare), no matter what happens to the arduino

Consider latching relays where there is a set coil and a reset coil.  Such as  [this one][1].  Such a device does not need to be continuously powered.  Only pulsed to set and a pulsed to reset.

>So I thought I could use the watchdog.

Watchdog timers are fine if your program can get stuck waiting for an event that may never happen.  Like waiting to read the data from and RFID chip.  If you think this might happen, then add the watchdog timer to your design.

>Now there is the problem, that the relais module is keeping its state while booting.

Most embedded processors with bi-directional GPIO pins force those pins to be inputs when booting up.  This appears as high impedance to the outside world.  Consider using pull ups or pull downs on these pins to prevent them from floating to a state which may change the relays during booting of the processor.

  [1]: http://wiki.seeedstudio.com/Grove-2-Coil_Latching_Relay/


message:
Analog output gives a close range of values

I try to get a good range of values from **VMA309 sound sensor**.

However, when I connect it properly it gives me a range of values  +/-5 like below. The documentation says it should give numbers between 0 and 1024.

I turned the potentiometer both sides all the way and that only changed the number, but it keeps gives number in a range of 5 numbers:

An example:

    626
    623
    624
    624
    624
    624
    623
    624
    624

My code:

    int sensorPin = A5;
    int sensorValue = 0;
    void setup ()

    {
      Serial.begin (9600)  ;
    }

    void loop()
    {
      sensorValue = analogRead(sensorPin);
      delay (500);
      Serial.println (sensorValue, DEC);
    }

What am I doing wrong here?

An image of the wires:
I also tried the wiring directly without a breadboard. But that gave the same results.
[![][1]][1]

I used the code as given from the [VMA 309 documentation][2].

  [1]: https://i.stack.imgur.com/ILDiA.jpg
  [2]: http://www.produktinfo.conrad.com/datenblaetter/1600000-1699999/001612740-an-01-en-MF_ARDUINOR_COMPATIBLE_MICROPHONE_SOUND.PDF

body:
Arduino is a lot of fun, but you better stay away from such modules.

The module is a resistor and a electret microphone. There is also a comparator for the digital output. When you have an electret microphone, and add a resistor of 4k7 or 10k, then you have the same.

The signal from the microphone is not amplified and the Arduino only gets the analog value of the audio. The module does not measure how loud the audio is.

I think Velleman makes them: [www.velleman.eu/products/view/?id=435532][1]
They are so kind to have a schematic available: [vma309_scheme.pdf][2]

Can you move on and use the Arduino for something else?
This module with this microphone is probably not going to work.
If you want to measure the sound level, then perhaps you can make a circuit yourself or buy a better module.

The "[Sound Pressure][3]" is how loud audio is.
The most used standard is called "Sound Pressure Level" or "SPL" and is measured in dB (deciBell).

  [1]: https://www.velleman.eu/products/view/?id=435532
  [2]: https://www.velleman.eu/downloads/29/infosheets/vma309_scheme.pdf
  [3]: https://en.wikipedia.org/wiki/Sound_pressure


body:
I have had a smimilar issue extracting the data to ardino module.
-with 5V power supply the counts were varying from 1009~1023.
-with 3.3V power supply the counts were in the range of 610~640

I connected an scope and found out the MIC module gives an AC outputput of 340mV max sitting over DC signal of 3.3(at 5V supply) and 1.7(at 3.3Vsupply).

On thing was very clear that However the MIC is giving and out put, we need to consider the analoag ref. voltage, for an ADC the input can never be higher than Vref. i.e. 2.56V.So 5V suppy is not going to work. Also if 1.1 Vref is selected the ADC  will remain saturaed alaways at 1023 and won't work.
Also consider a need to subtruct and offset of 1.7V while working with 3.3V supply.

As a summary,
1- Set Vref of Arduino ADC module to 2.56V
2- Use 3.3V supply for **VMA309 sound sensor**
3- Consider a DC offset of 640 counts approx and the actual voice signal will be sitting on this offset value. May need to decouple in a software code.
4- Set a **VMA309 sound sensor module** threshold at a reasonable point to capture the full spectrum of voice.
5- The delay(ms) in a code shall be removed to get max capture rate or Set an ADC in a free running mode to caputure at max sampling rate(15KSPS for ATmega2560).


message:
How to convert jpeg byte stream into jpeg image and display on 1.8 inch TFT display

I have an ESP32 having a cam and it is transmitting compressed JPEG stream.

- TTGO T-Journal ESP32
- Camera Development Board
- OV2640
- SMA WiFi
- 3dbi Antenna
- 0.91 OLED Camera Board

I have an ESP32 having a 1.8 inch TFT screen and a SD card slot which act as receiver.

- ESP32 TS V1.2
- MPU9250
- 1.8 Inch TFT
- Bluetooth
- Wifi
- MicroSD Card Slot
- Speakers Module

On Chrome browser, I get a display of the JPEG images as a continuous image after image (video).

I can see the incoming compressed JPEG stream and i print it on serial monitor .
But I need to decode/ decompress the JPEGstream at receiving end and paint pixel of TFT screen .

Which steps am I missing? Can anybody suggest code of JPEG image rendering on TFT screen?

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

Sketch of transmitter:

    #include "OV2640.h"
    #include <WiFi.h>
    #include <WebServer.h>
    #include <WiFiClient.h>

    #define ENABLE_OLED //if want use oled ,turn on thi macro

    #ifdef ENABLE_OLED
    #include "SSD1306.h"
    #define OLED_ADDRESS 0x3c
    #define I2C_SDA 14
    #define I2C_SCL 13
    SSD1306Wire display(OLED_ADDRESS, I2C_SDA, I2C_SCL, GEOMETRY_128_32);
    #endif

    OV2640 cam;
    WebServer server(80);

    IPAddress apIP = IPAddress(192, 168, 1, 1);

    void handle_jpg_stream(void)
    {
        WiFiClient client = server.client();
        String response = "HTTP/1.1 200 OK\r\n";
    response += "Content-Type: multipart/x-mixed-replace; boundary=frame\r\n\r\n";
    server.sendContent(response);

    while (1)
    {
        cam.run();
        if (!client.connected())
            break;
        response = "--frame\r\n";
        response += "Content-Type: image/jpeg\r\n\r\n";
        server.sendContent(response);

        client.write((char *)cam.getfb(), cam.getSize());
        server.sendContent("\r\n");
        if (!client.connected())
            break;
        }
    }

    void handle_jpg(void)
    {
        WiFiClient client = server.client();

        cam.run();
        if (!client.connected())
        {
            return;
        }
         String response = "HTTP/1.1 200 OK\r\n";
         response += "Content-disposition: inline; filename=capture.jpg\r\n";
        response += "Content-type: image/jpeg\r\n\r\n";
        server.sendContent(response);
        client.write((char *)cam.getfb(), cam.getSize());
    }

    void handleNotFound()
    {
        String message = "Server is running!\n\n";
        message += "URI: ";
        message += server.uri();
        message += "\nMethod: ";
        message += (server.method() == HTTP_GET) ? "GET" : "POST";
       message += "\nArguments: ";
       message += server.args();
       message += "\n";
       server.send(200, "text/plain", message);
    }

    void setup()
    {
        Serial.begin(115200);
        while (!Serial)
        {
            ;
         }
    camera_config_t camera_config;
    camera_config.ledc_channel = LEDC_CHANNEL_0;
    camera_config.ledc_timer = LEDC_TIMER_0;
    camera_config.pin_d0 = 17;
    camera_config.pin_d1 = 35;
    camera_config.pin_d2 = 34;
    camera_config.pin_d3 = 5;
    camera_config.pin_d4 = 39;
    camera_config.pin_d5 = 18;
    camera_config.pin_d6 = 36;
    camera_config.pin_d7 = 19;
    camera_config.pin_xclk = 27;
    camera_config.pin_pclk = 21;
    camera_config.pin_vsync = 22;
    camera_config.pin_href = 26;
    camera_config.pin_sscb_sda = 25;
    camera_config.pin_sscb_scl = 23;
    camera_config.pin_reset = 15;
    camera_config.xclk_freq_hz = 20000000;
    camera_config.pixel_format = CAMERA_PF_JPEG;
    camera_config.frame_size = CAMERA_FS_SVGA;

    cam.init(camera_config);

    WiFi.mode(WIFI_AP);
    WiFi.softAPConfig(apIP, apIP, IPAddress(255, 255, 255, 0));
    bool result = WiFi.softAP("TTGO-CAMERA", "12345678", 1, 0);
    if (!result)
    {
        Serial.println("AP Config failed.");
        return;
    }
    else
    {
        Serial.println("AP Config Success.");
        Serial.print("AP MAC: ");
        Serial.println(WiFi.softAPmacAddress());
    }

    #ifdef ENABLE_OLED
    display.init();
    display.flipScreenVertically();
    display.setFont(ArialMT_Plain_16);
    display.setTextAlignment(TEXT_ALIGN_CENTER);
    display.drawString(128 / 2, 32 / 2, WiFi.softAPIP().toString());
    display.display();
    #endif

    server.on("/", HTTP_GET, handle_jpg_stream);
    server.on("/jpg", HTTP_GET, handle_jpg);
    server.onNotFound(handleNotFound);
    server.begin();
    }

    void loop()
    {
        server.handleClient();
    }

Sketch of receiver:

    #include <WiFi.h>
    #include "FS.h"
    #include "SD.h"
    #include "SPI.h"
    #include <Adafruit_GFX.h>    // Core graphics library
    #include <Adafruit_ST7735.h> // Hardware-specific library
    #include <Adafruit_ImageReader.h> // Image-reading functions
    //#include <Adafruit_TFTLCD.h> // Hardware-specific library
    #include <SPI.h>
    #include "WiFi.h"
    #include <JPEGDecoder.h>
    //#include <FileIO.h>

    // For the breakout, you can use any 2 or 3 pins
    // These pins will also work for the 1.8" TFT shield
    #define TFT_CS 16
    #define TFT_RST 9  // you can also connect this to the Arduino reset
                      // in which case, set this #define pin to -1!
    #define TFT_DC 17

    // Option 2: use any pins but a little slower!
    #define TFT_SCLK 5   // set these to be whatever pins you like!
    #define TFT_MOSI 23   // set these to be whatever pins you like!
    #define PIN_NUM_MISO 2
    #define PIN_NUM_MOSI 15
    #define PIN_NUM_CLK  14
    #define PIN_NUM_CS   13

    Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_MOSI, TFT_SCLK,     TFT_RST);

    String text="";

    const char* ssid     = "TTGO-CAMERA";
    const char* password = "12345678";
    const char* host     = "192.168.1.1";
    const char* url      = "/";

    IPAddress local_IP(192, 168, 1, 3);
    IPAddress gateway(192, 168, 1, 1);
    IPAddress subnet(255, 255, 255, 0);
    IPAddress primaryDNS(8, 8, 8, 8); //optional
    IPAddress secondaryDNS(8, 8, 4, 4); //optional

    //PImage logo;

    #define BUFFPIXEL 20
      int      bmpWidth, bmpHeight;   // W+H in pixels
      uint8_t  bmpDepth;              // Bit depth (currently must be 24)
      uint32_t bmpImageoffset;        // Start of image data in file
      uint32_t rowSize;               // Not always = bmpWidth; may have     padding
      uint8_t  sdbuffer[3*BUFFPIXEL]; // pixel buffer (R+G+B per pixel)
      uint8_t  buffidx = sizeof(sdbuffer); // Current position in sdbuffer
      boolean  goodBmp = false;       // Set to true on valid header parse
      boolean  flip    = true;        // BMP is stored bottom-to-top
      int      w, h, row, col;
      uint8_t  r, g, b;               // pixel color for tft
      File     bmpFile; File     bmpFile1;
      uint32_t pos = 0, startTime ;
      uint8_t xx=0; uint16_t yy=0; int ww=0; int hh=0;
      int bmpfilepos;

    //How to use -
    //tft.fillScreen(ST7735_BLACK);
    //testdrawtext(2,3,ST7735_GREEN,text);

    void testdrawtext( int leftoffset , int topoffset , uint16_t color ,  String text ) {
      tft.setCursor(leftoffset, topoffset);  // (offset from left margin , offset from top margin. )
      tft.setTextColor(color);
      tft.setTextWrap(true);
      tft.setTextSize(1);
      tft.print(text  );
        }

    void jpegbytesdisplay()
    {
     // Create a buffer for the packet
        char dataBuff[240];

        delay(5000);

      Serial.print("connecting to ");
      Serial.println(host);

      // Use WiFiClient class to create TCP connections
      WiFiClient client;
      const int httpPort = 80;
      int cnt=0;

      if (!client.connect(host, httpPort)) {
        Serial.println("connection failed");
        return;
      }

      Serial.print("Requesting URL: ");
      Serial.println(url);

      // This will send the request to the cam server
      client.print(String("GET ") + url + " HTTP/1.1\r\n" +
               "Host: " + host + "\r\n" +
               "Connection: close\r\n\r\n");
      unsigned long timeout = millis();

      while (client.available() == 0)
      {
        if (millis() - timeout > 5000)
        {
          Serial.println(">>> Client Timeout !");
          client.stop();
          return;
        }
      }

       int max_y=200;
       int ypos =200;
       int max_x=0 ;
       int xpos =0;

      // Read all the lines of the reply from server and print them to Serial

      ImageReturnCode stat;
      while (client.available())
      {
        //================================
       // String line = client.readStringUntil('\r');
       // Serial.print(line);

        //================================
        //bytes put into char[len] databuffer.
        size_t len=client.available();
        unsigned char buf[len];
        client.readBytes(buf, len);

        Serial.println("------------------------");
        Serial.println(len);
        //Serial.write(buf);

         //================================
         // bufffer to tft screen pixel rendering

          int col=0;
   int buffidx =0;
   cnt++;

        tft.fillScreen(ST7735_BLACK);
        tft.startWrite();
        tft.setAddrWindow(0, 0, 500, 500);

    String fname="/image2" + String(cnt) + ".jpg";
    File myFile = SD.open(fname, FILE_WRITE);
    myFile.write(buf,len);
    myFile.close();

         for (col=0; col<len; col++)
           {
              Serial.print(buf[col]);
           }
        Serial.println();
        Serial.println("------------------------");

          // For each pixel...
      for (col=0; col<len; col++)
      {
             if (buffidx >= sizeof(buf))
         {
              buffidx = 0; // Set index to beginning
           break;
            }

            b = buf[buffidx++]; //          [B]
            g = buf[buffidx++]; //     [G]
            r = buf[buffidx++]; //   [R]

            tft.pushColor(tft.color565(r,g,b));
                                 // Display pixel on tft screen one after another.

       } // end pixel loop.

        //================================

       delay(1000);
        tft.endWrite();
      }

        }

     void setupNormal()
    {

       Serial.begin(115200);

       // Use this initializer if you're using a 1.8" TFT
      tft.initR(INITR_BLACKTAB);   // initialize a ST7735S chip, black tab

      Serial.println("Initialized");

      if (!WiFi.config(local_IP, gateway, subnet, primaryDNS, secondaryDNS)) {
        Serial.println("STA Failed to configure");
      }

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

      WiFi.begin(ssid, password);

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

      tft.fillScreen(ST7735_BLACK);

    }

    void setup()
    {

        setupNormal();
        jpegbytesdisplay();

          }

    void loop()
    {

    }

  [1]: https://i.stack.imgur.com/QZAuF.png
  [2]: https://i.stack.imgur.com/7rTHV.png

body:
Here is what i found for JPEG image file display on any TFT -

 i used JPEGDecoder library and instead of tft.pushColor , i used tft.drawPixel  method.

      for (int jj  =mcu_y;jj<mcu_y + win_h;jj++)
         {
            for (int ii=mcu_x;ii<mcu_x + win_w ;ii++)
            {
                // TFTscreen.drawPixel(ii,jj,tft.color565(255,0,0));
                 TFTscreen.drawPixel(ii,jj,*pImg++ );
            }
         }

For BMP , we need rgb values to render each pixel on TFT screen.

But in case of JPG , first  we need to decode and create MCU tiles on TFT.
Then we paint those MCU tiles by color which we receive from JPEG stream decoder.
Here *pImg is the pointer which hold the color information.
As we increment *pImg++ array , each time we receive new color code of type uInt8_t type . Within MCU tiles , these color have to be injected .
Each MCU tile is colored and drawn in the given sequence by considering where the border line of TFT screen is.

It automatically create a JPEG image .

    //////////////////////////////////////////////////////////////
    #include <Adafruit_GFX.h>    // Core graphics library
    #include <Adafruit_ST7735.h> // Hardware-specific library
    #include <Adafruit_ImageReader.h> // Image-reading functions

    // For the breakout, you can use any 2 or 3 pins
    // These pins will also work for the 1.8" TFT shield
    #define TFT_CS 16
    #define TFT_RST 9  // you can also connect this to the Arduino reset
                          // set these to be whatever pins you like!
    // in which case, set this #define pin to -1!
    #define TFT_DC 17

    // Option 2: use any pins but a little slower!
    #define TFT_SCLK 5   // set these to be whatever pins you like!
    #define TFT_MOSI 23

    Adafruit_ST7735 TFTscreen = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_MOSI, TFT_SCLK, TFT_RST);

    //////////////////////////////////////////////////////////////

    #include <JPEGDecoder.h>  // JPEG decoder library

    //////////////////////////////////////////////////////////////
    // include the necessary libraries
    #include <SPI.h>
    #include <SD.h>
    //////////////////////////////////////////////////////////////

    // pin definition for the Mega
    #define sd_cs  53
    #define lcd_cs 49
    #define dc     48
    #define rst    47

    #define TFT_WHITE 0xFFFF
    #define TFT_BLACK 0x0000
    #define TFT_RED   0xF800

     //////////////////////////////////////////////////////////////

     #define PIN_NUM_MISO 2
    #define PIN_NUM_MOSI 15
    #define PIN_NUM_CLK  14
    #define PIN_NUM_CS   13

      Adafruit_ImageReader reader;
        ///////////////////////////////////////////////////////

    String text="";

    // this function determines the minimum of two numbers
    #define minimum(a,b)     (((a) < (b)) ? (a) : (b))

      //====================================================================================
        //   setup
        //====================================================================================

    void setup() {
      // initialize the GLCD and show a message
      // asking the user to open the serial line
      //////////////////////////////////////////////////////////////////
       // Use this initializer if you're using a 1.8" TFT
      TFTscreen.initR(INITR_BLACKTAB);   // initialize a ST7735S chip, black tab
    //////////////////////////////////////////////////////////////////

      TFTscreen.fillScreen(TFT_WHITE); // Alternative:

    TFTscreen.background(255, 255, 255);

    TFTscreen.setTextColor(TFT_RED); // Alternative: TFTscreen.stroke(0, 0, 255);
      TFTscreen.println();
      TFTscreen.println(F("Arduino TFT Jpeg Example"));

      TFTscreen.setTextColor(TFT_BLACK); // Alternative: TFTscreen.stroke(0, 0, 0);
      TFTscreen.println(F("Open serial monitor"));
      TFTscreen.println(F("to run the sketch"));

      // initialize the serial port: it will be used to
      // print some diagnostic info
      Serial.begin(115200);
      while (!Serial) {
        // wait for serial port to connect. Needed for native USB port only
      }

      // clear the GLCD screen before starting
    //  TFTscreen.background(255, 255, 255);
      TFTscreen.fillScreen(TFT_WHITE);

      // try to access the SD card. If that fails (e.g.
      // no card present), the setup process will stop.
      Serial.print(F("Initializing SD card..."));

    //////////////////////////////////////////////////////////////////

      SPI.begin(PIN_NUM_CLK, PIN_NUM_MISO, PIN_NUM_MOSI, PIN_NUM_CS);

      if (!SD.begin(PIN_NUM_CS)) {
        Serial.println(F("failed!"));
        while (1); // SD initialisation failed so wait here
      }
      Serial.println(F("OK!"));
    //////////////////////////////////////////////////////////////////

      // initialize and clear the GLCD screen
     // TFTscreen.begin();
      TFTscreen.fillScreen(TFT_WHITE); // Alternative: TFTscreen.background(255, 255, 255);

      // now that the SD card can be accessed, check the
      // image file exists.
      if (SD.exists("/EagleEye.jpg")) {
        Serial.println("EagleEye.jpg found on SD card.");
      } else {
        Serial.println("EagleEye.jpg not found on SD card.");
        while (1); // Image file missing so stay here
      }

    }

    //====================================================================================
    //   Main loop
    //====================================================================================
    void loop() {

      // open the image file
      File jpgFile = SD.open( "/EagleEye.jpg", FILE_READ);

      // initialise the decoder to give access to image information
      JpegDec.decodeSdFile(jpgFile);

      // print information about the image to the serial port
      jpegInfo();

      // render the image onto the screen at coordinate 0,0
      renderJPEG(0, 0);

      // wait a little bit before clearing the screen to random color and drawing again
      delay(4000);

      // clear screen
      TFTscreen.fillScreen(random(0xFFFF));  // Alternative: TFTscreen.background(255, 255, 255);
    }

    //====================================================================================
    //   Print information about the image
    //====================================================================================

    void jpegInfo() {
      Serial.println(F("==============="));
      Serial.println(F("JPEG image info"));
      Serial.println(F("==============="));
      Serial.print(F(  "Width      :")); Serial.println(JpegDec.width);
      Serial.print(F(  "Height     :")); Serial.println(JpegDec.height);
      Serial.print(F(  "Components :")); Serial.println(JpegDec.comps);
      Serial.print(F(  "MCU / row  :")); Serial.println(JpegDec.MCUSPerRow);
      Serial.print(F(  "MCU / col  :")); Serial.println(JpegDec.MCUSPerCol);
      Serial.print(F(  "Scan type  :")); Serial.println(JpegDec.scanType);
      Serial.print(F(  "MCU width  :")); Serial.println(JpegDec.MCUWidth);
      Serial.print(F(  "MCU height :")); Serial.println(JpegDec.MCUHeight);
      Serial.println(F("==============="));
    }

    //====================================================================================
    //   Decode and paint onto the TFT screen
    //====================================================================================
    void renderJPEG(int xpos, int ypos) {

      // retrieve infomration about the image
      uint16_t *pImg;
      uint16_t mcu_w = JpegDec.MCUWidth;
      uint16_t mcu_h = JpegDec.MCUHeight;
      uint32_t max_x = JpegDec.width;
      uint32_t max_y = JpegDec.height;

      // Jpeg images are draw as a set of image block (tiles) called Minimum Coding Units (MCUs)
      // Typically these MCUs are 16x16 pixel blocks
      // Determine the width and height of the right and bottom edge image blocks
      uint32_t min_w = minimum(mcu_w, max_x % mcu_w);
      uint32_t min_h = minimum(mcu_h, max_y % mcu_h);

      // save the current image block size
      uint32_t win_w = mcu_w;
      uint32_t win_h = mcu_h;

      // record the current time so we can measure how long it takes to draw an image
      uint32_t drawTime = millis();

      // save the coordinate of the right and bottom edges to assist image cropping
      // to the screen size
      max_x += xpos;
      max_y += ypos;

       char str[100];
      // read each MCU block until there are no more
      while ( JpegDec.read()) {

        // save a pointer to the image block
        pImg = JpegDec.pImage;

        // calculate where the image block should be drawn on the screen
        int mcu_x = JpegDec.MCUx * mcu_w + xpos;
        int mcu_y = JpegDec.MCUy * mcu_h + ypos;

        // check if the image block size needs to be changed for the right and bottom edges
        if (mcu_x + mcu_w <= max_x) win_w = mcu_w;
        else win_w = min_w;
        if (mcu_y + mcu_h <= max_y) win_h = mcu_h;
        else win_h = min_h;

        // calculate how many pixels must be drawn
        uint32_t mcu_pixels = win_w * win_h;

        // draw image block if it will fit on the screen
        if ( ( mcu_x + win_w) <= TFTscreen.width() && ( mcu_y + win_h) <= TFTscreen.height()) {
          // open a window onto the screen to paint the pixels into
          //TFTscreen.setAddrWindow(mcu_x, mcu_y, mcu_x + win_w - 1, mcu_y + win_h - 1);
          //TFTscreen.setAddrWindow(mcu_x, mcu_y, mcu_x + win_w - 1, mcu_y + win_h - 1);
          // push all the image block pixels to the screen

     ////////////////////////////////////////////////////////

     // while (mcu_pixels--)
     // {
     // TFTscreen.pushColor(*pImg++);
     // } // Send to TFT 16 bits at a time

     ////////////////////////////////////////////////////////

     //  Write all MCU pixels to the TFT window

      for (int jj=mcu_y;jj<mcu_y + win_h;jj++)
         {
            for (int ii=mcu_x;ii<mcu_x + win_w ;ii++)
            {
                // TFTscreen.drawPixel(ii,jj,tft.color565(255,0,0));
                 TFTscreen.drawPixel(ii,jj,*pImg++ );
            }
         }

     ////////////////////////////////////////////////////////

        }

        // stop drawing blocks if the bottom of the screen has been reached
        // the abort function will close the file
        else if ( ( mcu_y + win_h) >= TFTscreen.height()) JpegDec.abort();

      }

      // calculate how long it took to draw the image
      drawTime = millis() - drawTime; // Calculate the time it took

     // print the results to the serial port
      Serial.print  ("Total render time was    : "); Serial.print(drawTime); Serial.println(" ms");
      Serial.println("=====================================");

    }


message:
Trying to power multiple servos at once using a Arduino Mega

Recently I have been trying to do a project for my end of year project, it involved making a humanoid arm.

I am still a newbie at these things, I usually have my friend do the wiring, but since he is away for the moment can anyone help me with it?

I am currently using 6X MG996R Servos for each finger and 1 for the wrist. I am also using a Arduino Mega with a Adafruit 16-Channel 12-bit PWM/Servo Shield - I2C interface.

I have already searched through the web for the best way to power it but I only found people trying to power it with a 5v adaptor, my problem is I'm trying to make the hand mobile so I need to use a battery. I have tried 2x UltraFire 18650 3000mAh 3.7V rechargeable battery in series (still doesn't work only 1 servo moved), also using a 9v battery (Only moved 2 servos).

So i have been wondering if I could utilise the Adafruit 16-Channel 12-bit PWM/Servo Shield - I2C interface..

body:
Here is a [spec-sheet for the MG996R servos][1]. Notice at the top of the 2d page, they require a supply of 4.8 - 7.2 volts, and can draw .5 - .9 Amps running and 2.5 Amps when stalled.

You'll need a supply of 6 volts (+/-) that can handle that current, times however many servos you need to operate simultaneously. The 3.7 volt batteries don't even meet the minimum voltage for the servos (unless you have two of them in series, but then they're slightly over the maximum).

You need to figure out your power budget first, then how your are going to meet it. You might be able to use a lighter supply than the worst case (6 stalled motors) would require or even than 6 motors at full operating torque (0.9 Amp each), if you monitor the current on each motor and shut down the or sequence the one(s) with the highest draw. You might even try monitoring just the battery-pack voltage, which won't tell you which motor(s) are stressing, but will let you know that you're unable to supply the total requirement for that present move.

If it were me, I'd use battery voltage sensing first (easier, simpler) to see if I have a problem that I can't solve by sequencing the motors. I might find I don't need to measure each motor's current.

Update:
> So its either i use 3.7 bat or 9v. Or.can you suggest any other power
> source?

A single 3.7v battery won't work well) for a motor that needs 4.8v minimum. Two of them in series will be slightly over the max voltage spec (7.4v vs. 7.2v). Will that slight overage damage or overheat the motor? Will be OK for intermittent use? Maybe, if you're careful to shut down a stalled motor quickly. The alternative is to build a voltage regulator that will drop the 7.4 to around 6v, but the regulator must also be able to meet your power budget, too.

A 9v supply is definitely too high and will need to regulated to within the motors' spec. (I assume you're not considering the four or five cm high ones with snap-on connectors, usually used in smoke-detectors? They have very little capability to deliver current and will be totally unsuitable for your application.)

My first try would be to experiment with 1 motor at 7.4v with a typical (for your project) mechanical forces on it, and see if it overheats and how soon, with how much load. You'd be taking a bit of a risk with that motor but the potential advantage is you might save yourself having to build a high-current voltage regulator.

Update2:

> NiMH AA cells are 1.2V

Good call. Just know that Nickle-based batteries have the twin disadvantages of long charge cycles (or degradation of capacity with faster charging) and higher self-discharge rate of about 1%/day. Their advantage to you is that it's easier to make a battery pack whose voltage falls within the motor spec. If this is a one-time project, this may well be more important to you than their disadvantages.

  [1]: https://www.electronicoscaldas.com/datasheet/MG996R_Tower-Pro.pdf


message:
Does Arduino C++ support dynamic arrays of objects

My C++ is seriously out-of-date, and I'm working on a project that will be juggling multiple timed actions at the same time, with a menu system to manage the interface and control those timed actions (A multi-channel power outlet controller.)

To do the control I'm planning to have an array of objects that get serviced every time through the event loop. I'm currently using a static C array of objects, but I'd like to use a dynamic C++ array where I can add and remove objects as needed.

I know that some features of the C++ standard library are not supported on Arduino. I think C++ calls smart arrays vectors, and believe vectors are part of the standard library, which isn't supported/fully supported on Arduino. Is there some sort of dynamic array class available?

body:
Even if it would be possible to use dynamic arrays, I would not recommend it, especially not on an Arduino Uno/Mega with only 2 or 8 KB memory.

Instead, create a static data element (e.g. array) that has a (reasonable) maximum number of created elements. This also has the benefit that the constructor will not be called after initialization, thus no variance in execution time (construction of objects can take time).

To manage multiple items within this data element, you can:

- Using a ring buffer, this is the normal way to store items on one side, and process them from the other (so-called FIFO, first in first out).
- Using a stack (for LIFO, last in last out).
- For arrays, keep one variable that holds the number of elements currently filled.


message:
Can Serial be safely used in an SPI interrupt routine

I have anecdotal experience that using Serial.print inside a slave's SPI interrupt routine (ISR) causes issues with transmission. It also seems that interrupts may be called more than once before the main loop can react, so it is difficult to print info from all interrupts. Is this because Serial is inherently unsafe, or too slow? Can Serial be used safely inside the ISR routine?

body: Serial should be avoided in ISRs because interrupts are disabled inside ISRs, and Serial transmission uses interrupts to operate. Better to have the ISR set a flag that is read in the next iteration of `loop()` to print the desired info.


body:
Hardware Serial write(byte) function in Arduino AVR core will work in interrupt. It checks if interrupts are disabled and if yes and the buffer is full, it executes directly the interrupt function, which pushes bytes from buffer to output.

(All write and print functions of hardware Serial use the write(byte) function to send data.)

It depends on other factors if a long time spent in interrupt handler will disturb things.


body: In general, [interrupts should run as fast as possible](http://users.ece.utexas.edu/~valvano/Volume1/E-Book/C12_Interrupts.htm). This is especially true when using SPI, since in the slave's ISR, the slave needs to put a byte in the SPI Data Register (SPDR) *before* the next transfer occurs. Thus it is good practice to avoid Serial transmission entirely in an interrupt, since in simple interrupts it can be by far the slowest portion of the interrupt.


message:
Dynamically modifying the call stack using pointers

In a C++ Arduino library, can we modify the call stack from inside a function by intentionally decrementing a pointer to a stack variable so that it's out of range? Like this:

```
void FooBar()
{
  char a;
  char *ptr = &a;
  ptr -= 4;
  // Can we edit the call stack with ptr now?
}
```

Can we use this to, for example, change what function is "calling" `FooBar()` by replacing the function pointer of the calling function on the call stack to another function? Or can we change the values of function variables in the calling function in mischievous fashion?

body:
I am answering in the context of the AVR calling conventions, as they
are the only ones I know well enough to be able to answer here.

> Can we use this to, for example, change what function is "calling"
> `FooBar()` by replacing the function pointer of the calling function
> on the call stack to another function?

That will probably be impossible in C++. Let's say you have the
following call chain: `main()` → `f()` → `FooBar()`. In the body of
`FooBar()`, the stack will look like this (oldest stuff at top):

<!-- language: none -->

    return address from f() to main()
    registers saved by the f() prologue
    return address from FooBar() to f()
    registers saved by the FooBar() prologue

Getting the stack pointer is easy. No need to declare a dummy variable,
just:

    char *stack_pointer = (char *) SP;

Now, to change the required return address, you need to skip over the
registers saved by the `FooBar()` prologue. And this is the big problem:
you do not know how many registers were saved there. Function prologues
are written by the compiler, and whatever they save depends on how many
registers are needed within the function, which in turn depends on the
complexity of that function. Even minor changes to the function can
modify the number of registers its prologue saves.

The only solution to this problem I can imagine is to forego the
compiler-generated prologue and write `FooBar()` in assembly. If you
wish to do it within a C++ file, you can attach the "naked" attribute to
the function and write its body using inline assembly.

> Or can we change the values of function variables in the calling
> function in mischievous fashion?

No need to tamper with the stack for this. The compiler strives to store
as many local variable as possible in CPU registers rather than the
stack. The caller's local variables are most likely still in those
registers and you can modify them at will (in assembly). That's why you
have this register-saving prologue and register-restoring epilogue in
the first place. Indeed, if you make the function "naked" and don't do
the saving/restoring yourself, you will very likely end up corrupting
the caller's locals.


message:
How do I use a 5v/120v relay that is not mounted on a board

I bought an arduino kit, and it came with, amongst other things, a 5v relay to control 120-220v.

The relay is only that, there is only the 5 pin relay, and it's not on a board on which one can screw in the leads

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

I was wondering how I can use it..  i.e. how do I mount it somehow (especially since the leads are metric and most perf board is standard (or vice-versa)).

I don't mind soldering the 5v control leads from the arduino, but I'm not so sure about soldering or connecting 110v straight on the relay.  i'm worried about long term longevity.

I have soldered longer leads just to be able to fit it on a board for tests, but those are tiny, and aren't safe for higher voltage/current.

Any suggestions?
Thanks, Seb.

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

body:
What I did with a similar looking 'module' (An AC/DC converter), was to use a protoboard/perfboard. Some holes fitted in the existing holes, others I drilled with a small drill.

On the back you can solder the wires you need, so for the 110V wires you might use thicker wires than for the controls.

Than if you want to make it fancy, you add some terminal blocks to connect the external wires too. Terminal blocks looks like this:

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

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


message:
'inet_addr_to_ipaddr' was not declared in this scope

I am using ESP32 Ping from this page: [https://github.com/pbecchi/ESP32_ping][1]

It works fine on ESP32, no compiler error.

Because something wrong on my PC, I did fresh install Windows 10 and Arduino IDE 1.8.8.

After fresh install, ESP32 Ping doesn't work anymore.

Arduino IDE Compiler error in Ping.cpp:

    //Ping.cpp

    #include <Arduino.h>

    #include <math.h>
    #include <float.h>
    #include <signal.h>
    #include <stdint.h>
    #include <string.h>
    #include <errno.h>

    #include "ping.h"

    #include "lwip/inet_chksum.h"
    #include "lwip/ip.h"
    #include "lwip/ip4.h"
    #include "lwip/err.h"
    #include "lwip/icmp.h"
    #include "lwip/sockets.h"
    #include "lwip/sys.h"
    #include "lwip/netdb.h"
    #include "lwip/dns.h"

    static uint16_t ping_seq_num;
    static uint8_t stopped = 0;

    /*
    * Statistics
    */
    static uint32_t transmitted = 0;
    static uint32_t received = 0;
    static float min_time = 0;
    static float max_time = 0;
    static float mean_time = 0;
    static float last_mean_time = 0;
    static float var_time = 0;

    #define PING_ID 0xAFAF

    #define PING_DEFAULT_COUNT    10
    #define PING_DEFAULT_INTERVAL  1
    #define PING_DEFAULT_SIZE     32
    #define PING_DEFAULT_TIMEOUT   1

    /*
    * Helper functions
    *
    */
    static void ping_prepare_echo(struct icmp_echo_hdr *iecho, uint16_t len) {
     size_t i;
     size_t data_len = len - sizeof(struct icmp_echo_hdr);

     ICMPH_TYPE_SET(iecho, ICMP_ECHO);
     ICMPH_CODE_SET(iecho, 0);
     iecho->chksum = 0;
     iecho->id = PING_ID;
     iecho->seqno = htons(++ping_seq_num);

     /* fill the additional data buffer with some data */
     for (i = 0; i < data_len; i++) {
      ((char*)iecho)[sizeof(struct icmp_echo_hdr) + i] = (char)i;
     }

     iecho->chksum = inet_chksum(iecho, len);
    }

    static err_t ping_send(int s, ip4_addr_t *addr, int size) {
     struct icmp_echo_hdr *iecho;
     struct sockaddr_in to;
     size_t ping_size = sizeof(struct icmp_echo_hdr) + size;
     int err;

     iecho = (struct icmp_echo_hdr *)mem_malloc((mem_size_t)ping_size);
     if (!iecho) {
      return ERR_MEM;
     }

     ping_prepare_echo(iecho, (uint16_t)ping_size);

     to.sin_len = sizeof(to);
     to.sin_family = AF_INET;
     inet_addr_from_ipaddr(&to.sin_addr, addr);

     if ((err = sendto(s, iecho, ping_size, 0, (struct sockaddr*)&to, sizeof(to)))) {
      transmitted++;
     }
     free(iecho)
     return (err ? ERR_OK : ERR_VAL);
    }

    static void ping_recv(int s) {
     char buf[64];
     int fromlen, len;
     struct sockaddr_in from;
     struct ip_hdr *iphdr;
     struct icmp_echo_hdr *iecho = NULL;
     char ipa[16];
     struct timeval begin;
     struct timeval end;
     uint64_t micros_begin;
     uint64_t micros_end;
     float elapsed;

     // Register begin time
     gettimeofday(&begin, NULL);

     // Send
     while ((len = recvfrom(s, buf, sizeof(buf), 0, (struct sockaddr*)&from, (socklen_t*)&fromlen)) > 0) {
      if (len >= (int)(sizeof(struct ip_hdr) + sizeof(struct icmp_echo_hdr))) {
       // Register end time
       gettimeofday(&end, NULL);

       /// Get from IP address
       ip4_addr_t fromaddr;
       inet_addr_to_ipaddr(&fromaddr, &from.sin_addr);

       strcpy(ipa, inet_ntoa(fromaddr));

       // Get echo
       iphdr = (struct ip_hdr *)buf;
       iecho = (struct icmp_echo_hdr *)(buf + (IPH_HL(iphdr) * 4));

       // Print ....
       if ((iecho->id == PING_ID) && (iecho->seqno == htons(ping_seq_num))) {
        received++;

        // Get elapsed time in milliseconds
        micros_begin = begin.tv_sec * 1000000;
        micros_begin += begin.tv_usec;

        micros_end = end.tv_sec * 1000000;
        micros_end += end.tv_usec;

        elapsed = (float)(micros_end - micros_begin) / (float)1000.0;

        // Update statistics
        // Mean and variance are computed in an incremental way
        if (elapsed < min_time) {
         min_time = elapsed;
        }

        if (elapsed > max_time) {
         max_time = elapsed;
        }

        last_mean_time = mean_time;
        mean_time = (((received - 1) * mean_time) + elapsed) / received;

        if (received > 1) {
         var_time = var_time + ((elapsed - last_mean_time) * (elapsed - mean_time));
        }

        // Print ...
        log_d("%d bytes from %s: icmp_seq=%d time=%.3f ms\r\n", len, ipa,
         ntohs(iecho->seqno), elapsed
        );

        return;
       }
       else {
        // TODO
       }
      }
     }

     if (len < 0) {
      log_d("Request timeout for icmp_seq %d\r\n", ping_seq_num);
     }
    }
    /*
    static void stop_action(int i) {
     signal(i, SIG_DFL);
     stopped = 1;
    }
    +/
    /*
    * Operation functions
    *
    */
    void ping(const char *name, int count, int interval, int size, int timeout) {
     // Resolve name
     hostent * target = gethostbyname(name);
     IPAddress adr = *target->h_addr_list[0];
     if (target->h_length == 0) {
      // TODO: error not found target?????
      return;
     }
     ping_start(adr, count, interval, size, timeout);
    }
    bool ping_start(struct ping_option *ping_o) {

     return ping_start(ping_o->ip,ping_o->count,0,0,0);

    }
    bool ping_start(IPAddress adr, int count=0, int interval=0, int size=0, int timeout=0) {
    // driver_error_t *error;
     struct sockaddr_in address;
     ip4_addr_t ping_target;
     int s;
     // Get default values if argument are not provided
     if (count == 0) {
      count = PING_DEFAULT_COUNT;
     }

     if (interval == 0) {
      interval = PING_DEFAULT_INTERVAL;
     }

     if (size == 0) {
      size = PING_DEFAULT_SIZE;
     }

     if (timeout == 0) {
      timeout = PING_DEFAULT_TIMEOUT;
     }

     // Create socket
     if ((s = socket(AF_INET, SOCK_RAW, IP_PROTO_ICMP)) < 0) {
      // TODO: error
      return false;
     }

     address.sin_addr.s_addr = adr;
     ping_target.addr = address.sin_addr.s_addr;

     // Setup socket
     struct timeval tout;

     // Timeout
     tout.tv_sec = timeout;
     tout.tv_usec = 0;

     if (setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &tout, sizeof(tout)) < 0) {
      closesocket(s);
      // TODO: error
      return false;
     }

     stopped = 0;
     transmitted = 0;
     received = 0;
     min_time = 1.E+9;// FLT_MAX;
     max_time = 0.0;
     mean_time = 0.0;
     var_time = 0.0;

     // Register signal for stop ping
     //signal(SIGINT, stop_action);

     // Begin ping ...
     char ipa[16];

     strcpy(ipa, inet_ntoa(ping_target));
     log_i("PING %s: %d data bytes\r\n",  ipa, size);

     ping_seq_num = 0;

     while ((ping_seq_num < count) && (!stopped)) {
      if (ping_send(s, &ping_target, size) == ERR_OK) {
       ping_recv(s);
      }
      delay( interval*1000L);
     }

     closesocket(s);

     log_i("%d packets transmitted, %d packets received, %.1f%% packet loss\r\n",
      transmitted,
      received,
      ((((float)transmitted - (float)received) / (float)transmitted) * 100.0)
     );

     if (received) {
      ping_resp pingresp;
      log_i("round-trip min/avg/max/stddev = %.3f/%.3f/%.3f/%.3f ms\r\n", min_time, mean_time, max_time, sqrt(var_time / received));
      pingresp.total_count = 10;
      pingresp.timeout_count = 10;
      pingresp.total_bytes = 1;
      pingresp.total_time = mean_time;
      pingresp.ping_err = 0;
      return true;
     // ping_o->sent_function(ping_o, (uint8*)&pingresp);
     }
     return false;
    }

    bool ping_regist_recv(struct ping_option *ping_opt, ping_recv_function ping_recv)
    {
     if (ping_opt == NULL)
      return false;

     ping_opt->recv_function = ping_recv;
     return true;
    }

    bool ping_regist_sent(struct ping_option *ping_opt, ping_sent_function ping_sent)
    {
     if (ping_opt == NULL)
      return false;

     ping_opt->sent_function = ping_sent;
     return true;
    }

Arduino IDE 1.8.8. compiler stop in this line:

    inet_addr_from_ipaddr(&to.sin_addr, addr);

The error message: **'inet_addr_to_ipaddr' was not declared in this scope**

According to [this post][2], `inet_addr` need `lwip` library.

So... the conclusion: cause of this issue is broken `lwip` library.

But when ESP32 Ping working fine previously, I didn't install any separate `lwip` library. Maybe ESP32 Ping use `lwip` library from Arduino library - `#include <Arduino.h>`

But why after fresh install, ESP32 Ping doesn't work anymore?

Arduino IDE installation automatically included Arduino library. Also, I didn't change anything on Arduino Sketch & Library folder - `C:\Users\Documents\Arduino`. The folder content as the same as before fresh install.

How to fix this?

Please help...

  [1]: https://github.com/pbecchi/ESP32_ping
  [2]: https://stackoverflow.com/questions/4124074/network-programming-udp-packet

body:
Done this steps:

    1. Uninstall Arduino IDE 1.8.8
    2. Delete C:\Users\AppData\Local\
    3. Rename C:\Users\Documents\Arduino into C:\Users\Documents\Arduino_OLD
    4. Restart the PC
    5. Install Arduino IDE 1.8.8
    6. Install ESP32 Core version 1.0.0 using Boards Manager

Then.... compile my sketch.

And now.... **it WORKS**....  :)  :)  :)

My previous mistake is not installing ESP32 Core version 1.0.0.

I did it by installing version 1.0.1 - the Boards Manager default version - which didn't work.

It seems some change in ESP32 Core version 1.0.1 broke ESP32 Ping library connection.


message:
How to combine strings and text together?

I'm trying to combine two strings (strings/int) together with text in below code:

    int foo = String((char*)payload).indexOf(' ');
    int message1;
    int message2;

    message1 = String((char*)payload).substring(0, foo).toInt();
    Serial.print(message1); // Returns 1

    message2 = String((char*)payload).substring(foo + 1, length).toInt();
    Serial.print(message2); // Returns 0

    client.publish(msg, String(message1 + " " + message2).c_str(), true);
    // published value: 1 0

Instead of publishing "1 0" its publishing some weird values, what am i missing?

body:
I wouldn't use the String class, but instead use the C functions to concatenate strings (like strcat, strncat).

You can use the itoa function to convert an integer to a string, see:
> https://stackoverflow.com/questions/9655202/how-to-convert-integer-to-string-in-c

Or use the sprintf function.

These are all standard C functions which gives you complete control of the buffer sizes to use. Handy because the Arduino Uno has just 2 KB.


message:
How to find the MAC address using NodeMCU when connecting to WiFi?

I am new to using NodeMCU and IOT. I am testing the NodeMCU (ESP8266) so that I can connect with pubnub server. Have taken code from github but there is error saying

    'mac was not declared in this scope'

and some other error too.

Can anyone tell whats the problem?

This code is from pubnub github page - https://github.com/pubnub/arduino

Code:-

    #include <Ethernet.h>

    #include <PubNub.h>

    void setup() {
        /* For debugging, set to speed of your choice */
        Serial.begin(9600);

        /* If you use some other HW, you need to do some other
           initialization of it here... */
        Ethernet.begin();

        /* Start the Pubnub library by giving it a publish and subscribe
           keys */
        PubNub.begin(publisher key, subscriber key);
    }

    void loop() {
        /* Maintain DHCP lease. For other HW, you may need to do
           something else here, or maybe nothing at all. */
        Ethernet.maintain();

        /* Publish message. You could use `auto` here... */
        PubNonSubClient *pclient = PubNub.publish(pubchannel, "\"message\"");
        if (!pclient) return;
        PublishCracker cheez;
        cheez.read_and_parse(pclient);
        /** You're mostly interested in `outcome()`, and,
            if it's "failed", then `description()`.
        */
        Serial.print("Outcome: "); Serial.print(cheez.outcome());
        Serial.print(' '); Serial.println(cheez.to_str(cheez.outcome()));
        Serial.print("description: "); Serial.println(cheez.description());
        Serial.print("timestamp: "); Serial.println(cheez.timestamp());
        Serial.print("state: "); Serial.print(cheez.state());
        Serial.print(' '); Serial.println(cheez.to_str(cheez.state()));
        pclient->stop();

        /* Wait for news. */
        PubSubClient *sclient = PubNub.subscribe(subchannel);
        if (!sclient) return; // error
        String msg;
        SubscribeCracker ritz(sclient);
        while (!ritz.finished()) {
            ritz.get(msg);
            if (msg.length() > 0) {
                Serial.print("Received: "); Serial.println(msg);
            }
        }
        sclient->stop();

        delay(1000);
    }

    error :-
      sketch_jan17a:28:47: error: 'pubchannel' was not declared in this scope

         PubNonSubClient *pclient = PubNub.publish(pubchannel, "\"message\"");

                                                   ^

    sketch_jan17a:44:46: error: 'subchannel' was not declared in this scope

         PubSubClient *sclient = PubNub.subscribe(subchannel);

                                                  ^

    Multiple libraries were found for "Ethernet.h"
     Used: C:\Users\sultan\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.5.0-beta2\libraries\Ethernet
     Not used: C:\Program Files (x86)\Arduino\libraries\Ethernet
    exit status 1
    'mac' was not declared in this scope

body: I don't believe you have an Wiznet Ethernet module connected to your NodeMcu. Ethernet library is for the Wiznet chips for wired LAN. You want to use the WiFi of the NodeMcu. For that the esp8266 core has the ESP8266WiFi library. It has the same API as other WiFi libraries based on Arduino WiFi library. So you can modify the WiFi examples of the Arduino pubnub library. Only change `#include <WiFi101.h>` to `#include <ESP8266WiFi.h>`. (And remove `#include <SPI.h>`.)


message:
Error compiling a sketch to class/library conversion

I'm trying to take a sketch and turn it into a class for a library I'm making, but I'm getting compile issues.

This is not a duplicate as suggested. as i explain in the comment and my answer. Thank you all for your help - as I am new to creating libraries - figured I would attempt something correctly for a change :)

Here is the original sketch: [Gotten here][1]

    #include <ros.h>
    #include <sensor_msgs/BatteryState.h>

    #define K           0.00472199
    #define CELLS       6
    #define MAX_CELLS   12

    double cell_const[MAX_CELLS] =
    {
      1.0000,
      2.1915,
      2.6970,
      4.1111,
      4.7333,
      6.6000,
      6.6000,
      7.8293,
      8.4667,
      9.2353,
      11.0000,
      11.0000
    };

    ros::NodeHandle nh;
    sensor_msgs::BatteryState batt_state;
    ros::Publisher batteryState("battery_state", &batt_state);

    void setup()
    {
      // Initialize the ROS node.
      nh.initNode();
      nh.advertise(batteryState);

      // Populate battery parameters.
      batt_state.design_capacity = 2200;      // mAh
      batt_state.power_supply_status = 2;     // discharging
      batt_state.power_supply_health = 0;     // unknown
      batt_state.power_supply_technology = 3; // LiPo
      batt_state.present = 1;                 // battery present

      batt_state.location = "Crawler";        // unit location
      batt_state.serial_number = "ABC_0001";  // unit serial number
      batt_state.cell_voltage = new float[CELLS];

    }

    void loop()
    {
      // Battery status.
      double battVoltage = 0.0;
      double prevVoltage = 0.0;

      // Populate battery state message.
      for (int i = 0; i < CELLS; i++)
      {
         // Read raw voltage from analog pin.
        double cellVoltage = analogRead(i) * K;

        // Scale reading to full voltage.
        cellVoltage *= cell_const[i];
        double tmp = cellVoltage;

        // Isolate current cell voltage.
        cellVoltage -= prevVoltage;
        battVoltage += cellVoltage;
        prevVoltage = tmp;

        // Set current cell voltage to message.
        batt_state.cell_voltage[i] = (float)cellVoltage;

        // Check if battery is attached.
        if (batt_state.cell_voltage[i] >= 2.0)
          batt_state.present = 1;
        else
          batt_state.present = 0;
      }

      // Update battery health.
      batt_state.voltage = (float)battVoltage;

      if (batt_state.voltage > CELLS * 4.2)
        batt_state.power_supply_health = 4; // overvoltage
      else if (batt_state.voltage < CELLS * 3.0)
        batt_state.power_supply_health = 3; // dead
      else
        batt_state.power_supply_health = 1; // good

      // Publish data to ROSSERIAL.
      batteryState.publish( &batt_state );
      nh.spinOnce();
      delay(1000);

    }

Here is my header file:

    #ifndef battery_h
    #define battery_h

    #if ARDUINO >= 100
    #include "Arduino.h"
    #else
    #include "WProgram.h"
    #endif

    #include <ros.h>
    #include <sensor_msgs/BatteryState.h>

    #define K           0.00472199
    #define CELLS       6
    #define MAX_CELLS   12
    #define CRITICAL    0.30

    double cell_const[MAX_CELLS] =
    {
      1.0000, 2.1915, 2.6970, 4.1111,
      4.7333, 6.6000, 6.6000, 7.8293,
      8.4667, 9.2353, 11.0000, 11.0000
    };

    ros::NodeHandle nh;
    sensor_msgs::BatteryState batt_state;

    ros::Publisher batteryState("/battery/info", &batt_state);

    class Battery
    {
      private:
       void updateBatteryHealth();
       double battVoltage;
       double prevVoltage;
      public:
        void begin();
        void updateBatteryState();
    };

    #endif

This is my cpp file:

    #include "battery.h"

    void Battery::begin(){

      // Launch ROS node and set parameters.
      nh.initNode();

      // Setup publishers/subscribers.
      nh.advertise(batteryState);

      // Populate battery parameters.
      batt_state.design_capacity          = 2200;  // mAh
      batt_state.power_supply_status      = 2;     // discharging
      batt_state.power_supply_health      = 0;     // unknown
      batt_state.power_supply_technology  = 3;     // LiPo
      batt_state.present                  = 1;     // battery present

      batt_state.location      = "Crawler";        // unit location
      batt_state.serial_number = "ABC_0001";       // unit serial number

      batt_state.cell_voltage = new float[CELLS];  // individual cell health

    }

    void Battery::updateBatteryState() {
      battVoltage = 0.0;
      prevVoltage = 0.0;
      // Reset Power Supply Health.
      batt_state.power_supply_health = 0;
        // Populate battery state message.
      for (int i = 0; i < CELLS; i++)
      {
        // Read raw voltage from analog pin.
        double cellVoltage = analogRead(i) * K;

        // Scale reading to full voltage.
        cellVoltage *= cell_const[i];
        double tmp = cellVoltage;

        // Isolate current cell voltage.
        cellVoltage -= prevVoltage;
        battVoltage += cellVoltage;
        prevVoltage = tmp;

        // Set current cell voltage to message.
        batt_state.cell_voltage[i] = (float)cellVoltage;

        // Check if battery is attached.
        if (batt_state.cell_voltage[i] >= 2.0)
        {
          if (batt_state.cell_voltage[i] <= 3.2)
            batt_state.power_supply_health = 5; // Unspecified failure.
          batt_state.present = 1;
        }
        else{
          batt_state.present = 0;
        }
      }
    };

    void Battery::updateBatteryHealth() {
        // Update battery health.
      if (batt_state.present)
      {
        batt_state.voltage = (float)battVoltage;
        float volt = batt_state.voltage;
        float low  = 3.0 * CELLS;
        float high = 4.2 * CELLS;
        batt_state.percentage = constrain((volt - low) / (high - low), 0.0, 1.0);
      }
      else
      {
        batt_state.voltage = 0.0;
        batt_state.percentage = 0.0;
      }

      // Update power supply health if not failed.
      if (batt_state.power_supply_health == 0 && batt_state.present)
      {
        if (batt_state.voltage > CELLS * 4.2)
          batt_state.power_supply_health = 4; // overvoltage
        else if (batt_state.voltage < CELLS * 3.0)
          batt_state.power_supply_health = 3; // dead
        else
          batt_state.power_supply_health = 1; // good
      }
       // Publish data to ROSSERIAL.
      batteryState.publish( &batt_state );
      nh.spinOnce();
    };

this is the error im getting simply by calling the Battery::begin function in my main class:

    libraries/KBROSRobot/KBROSRobot.cpp.o (symbol from plugin): In function `KBROSRobot::KBROSRobot()':
    (.text+0x0): multiple definition of `nh'
    sketch/rob_test.ino.cpp.o (symbol from plugin):(.text+0x0): first defined here
    libraries/KBROSRobot/KBROSRobot.cpp.o (symbol from plugin): In function `KBROSRobot::KBROSRobot()':
    (.text+0x0): multiple definition of `batt_state'
    sketch/rob_test.ino.cpp.o (symbol from plugin):(.text+0x0): first defined here
    libraries/KBROSRobot/KBROSRobot.cpp.o (symbol from plugin): In function `KBROSRobot::KBROSRobot()':
    (.text+0x0): multiple definition of `batteryState'
    sketch/rob_test.ino.cpp.o (symbol from plugin):(.text+0x0): first defined here
    libraries/KBROSRobot/KBROSRobot.cpp.o (symbol from plugin): In function `KBROSRobot::KBROSRobot()':
    (.text+0x0): multiple definition of `cell_const'
    sketch/rob_test.ino.cpp.o (symbol from plugin):(.text+0x0): first defined here
    /var/folders/m4/lq13_j5j23qc0l2wp8dqmt4h0000gp/T//cczNyzqC.ltrans1.ltrans.o: In function `begin':
    /Users/keith.brown/Documents/Arduino/libraries/KBROSRobot/KBROSRobot.cpp:9: undefined reference to `Battery::begin()'
    collect2: error: ld returned 1 exit status
    exit status 1

  [1]: https://www.instructables.com/id/1S-6S-Battery-Voltage-Monitor-ROS/

body:
Don't define your global variables in the header file. Only declare them, using external linkage. Then define them in the implementation file

Header (.h):

    extern ros::NodeHandle nh;

Implementation (.cpp):

    ros::NodeHandle nh;

Try to keep usage of global variables to a minimum. If you don't need them outside of the library, declare them in the implementation file and mark them static.
Or even better: encapsulate them inside of the class.

***

The reason that you are getting these errors is because each implementation file is compiled separately. You have two implementation files that include your header file, so the header file is compiled twice. This results in two global variables with the name `nh`. During the linking stage, the linker tries to combine the compiled version of both `KBROSRobot.cpp` and `rob_test.ino.cpp` (these are called object files, `.o`). The linker has no way of knowing which variable is which, because they are both defined twice, so it throws an error.

Multiple _declarations_ are fine, because it just tells the compiler "there is a definition somewhere", and the linker will find that definition eventually. That's why the declaration with external linkage solves your problem.
Multiple _definitions_ are not allowed (in most cases).


body:
I also found that all other classes in the library have to be in the `utility` folder or the wont compile. Answering my comment above. Thank you @tttapa for your help.

Now I just have to intelligently program the robot, which is unfortunately subjective... ;)


message:
Short battery life concern with Arduino Pro Mini

I am using an Arduino Pro Mini with a L293D H-bridge driver to drive a bi-directional motor. The system takes input from a capacitive sensor which is constantly looking for a trigger. I don't have any low power optimization in the code. I was using Arduino UNO before which lasted for one day with a 9V battery. I switched to Arduino Pro Mini for longer battery life but the battery lasted for one day in that case as well.

Can anyone please help me understand what could be the possible reason for higher power consumption than normal for Arduino Pro Mini?

Thanks in advance for your help!

Niloy

body:
A standard alkaline 9V battery has a capacity rating of around 500mAh (milliAmp-hours). That rating is probably based on a current consumption of around 10mA. However, if the current consumption is higher, the apparent capacity drops. At 100mA, most 9V batteries have a capacity rating of about 300mAh, and at 500mA current draw, the apparent capacity drops down to 170mAh.

This means, if you are drawing 100mA of current constantly, a 9V battery will last (0.3Ah / 0.1A) = 3h.

A typical Arduino pro mini will draw current at around 20mA.

    500mAh / 20mA = 20h

This is not even counting the motor and driver.

A standard alkaline AA battery has a nominal voltage of 1.5V and a capacity of about 2000mAh, and 3 of them will provide a voltage between 4.5V (fully charged `1.5V x 3`) and 2.7V (fully discharged `0.9V x 3`)

With that voltage range, you could operate the Arduino pro mini in 3.3V mode, with no linear regulator, at a reduced clock frequency, such as 8Mhz, which will reduce power consumption even more.

Being able to put the chip in power-saving mode, and periodically check for necessary activity will help even more.

See [http://www.gammon.com.au/power][1] for a description of many practical methods.

That said, the Arduino is going to be a pretty small contributor to power draw compared to a DC motor, so your overall run time will heavily depend on how often the motor is turned on.

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


message:
Issue with analog readings on Arduino atMega with YL-69 moisture sensors

I've connected four YL-69 sensors to my arduino at-mega2560 on analogs pins 0-3. This is combined with four DHT11 sensors that are in digital pins.

The DHT work fine, and I can work one YL-69 moisture sensor that gives correct readings.
But when I connected the others, the readings are just 100% for all. I'm sure I must have made a mistake in my code somewhere, just can't spot it.

I've posted the sketch I use below, and the results from serial monitor.
(BTW i added a short delay of 10ms between each reading thinking that may be the issue, but it had no effect).

**Serial Monitor:**

[![Serial Monitor][1]][1]

**Sketch:**

    #include "DHT.h"
    #include <SPI.h>        // Include SPI library (needed for the SD card)
    #include <SD.h>         // Include SD library

    File dataFile;

    #define DHTPIN0 10     // what pin we're connected to
    #define DHTPIN1 11     // what pin we're connected to
    #define DHTPIN2 12     // what pin we're connected to
    #define DHTPIN3 13     // what pin we're connected to

    // Uncomment whatever type you're using!

    #define DHTTYPE DHT11   // DHT 11
    //#define DHTTYPE DHT22   // DHT 22  (AM2302)
    //#define DHTTYPE DHT21   // DHT 21 (AM2301)

    // How to connect sensors
    // Connect pin 1 (on the left) of the sensor to +5V
    // Connect pin 2 of the sensor to whatever your DHTPIN is
    // Connect pin 4 (on the right) of the sensor to GROUND
    // Connect a 10K resistor from pin 2 (data) to pin 1 (power) of the sensor

    DHT dht0(DHTPIN0, DHTTYPE);
    DHT dht1(DHTPIN1, DHTTYPE);
    DHT dht2(DHTPIN2, DHTTYPE);
    DHT dht3(DHTPIN3, DHTTYPE);

    int output_value ;
    int output_value1 ;
    int output_value2 ;
    int output_value3 ;
    int output_value4 ;

    unsigned long time;

    void setup() {
     Serial.begin(9600);
     while (!Serial)
        ; // wait for serial port to connect. Needed for native USB port only
      Serial.print("Initializing SD card...");
      if (!SD.begin()) {
        Serial.println("initialization failed!");
        while (1);
      }
      Serial.println("initialization done.");
     Serial.println("DHTxx test!");
     dht0.begin();
     dht1.begin();
     dht2.begin();
     dht3.begin();
     delay(2000);
    }

    uint16_t line = 1;

    void loop() {
     // Reading temperature or humidity takes about 250 milliseconds!
     // Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
     float h0 = dht0.readHumidity();
     float h1 = dht1.readHumidity();
     float h2 = dht2.readHumidity();
     float h3 = dht3.readHumidity();
     float t0 = dht0.readTemperature();
     float t1 = dht1.readTemperature();
     float t2 = dht2.readTemperature();
     float t3 = dht3.readTemperature();

     dataFile = SD.open("DHT11Log.csv", FILE_WRITE);
     //  if any result below is NaN (not a number) then something went wrong!
     if (dataFile) {
       output_value= analogRead(A0);
       delay(10);
       output_value1= analogRead(A1);
       delay(10);
       output_value2= analogRead(A2);
       delay(10);
       output_value3= analogRead(A3);
       delay(10);
       output_value4= analogRead(A4);
       output_value = map(output_value,1024,0,0,100);
       output_value1 = map(output_value,1024,0,0,100);
       output_value2 = map(output_value,1024,0,0,100);
       output_value3 = map(output_value,1024,0,0,100);
       output_value4 = map(output_value,1024,0,0,100);
       Serial.print("Moisture : ");
       Serial.print(output_value);
       Serial.println("%");
       Serial.print(output_value1);
       Serial.println("%");
       Serial.print(output_value2);
       Serial.println("%");
       Serial.print(output_value3);
       Serial.println("%");
       Serial.print(output_value4);
       Serial.println("%");
       Serial.print("Humidity  : sensor 0, ");
       Serial.println(h0);
       Serial.print("  sensor 1, ");
       Serial.println(h1);
       Serial.print("  sensor 2, ");
       Serial.println(h2);
       Serial.print("  sensor 3, ");
       Serial.println(h3);
       Serial.println(" %\t");
       Serial.print("temperature  : sensor 0, ");
       Serial.println(t0);
       Serial.print("  sensor 1, ");
       Serial.println(t1);
       Serial.print("  sensor 2, ");
       Serial.println(t2);
       Serial.print("  sensor 3, ");
       Serial.println(t3);
       Serial.println(" %\t");
       dataFile.print(line++);
       dataFile.print(":    Temperature = ");
       dataFile.print(",");
       dataFile.print(t0);
       dataFile.print(",");
       dataFile.print(t1);
       dataFile.print(",");
       dataFile.print(t2);
       dataFile.print(",");
       dataFile.print(t3);
       dataFile.print(",");
       dataFile.print("°C,    Humidity = ");
       dataFile.print(",");
       dataFile.print(h0);
       dataFile.print(",");
       dataFile.print(h1);
       dataFile.print(",");
       dataFile.print(h2);
       dataFile.print(",");
       dataFile.print(h3);
       dataFile.print(",");
       dataFile.println("%");
       dataFile.print(",");
       dataFile.print("Moisture : ");
       dataFile.print(",");
       dataFile.print(output_value);
       dataFile.print(",");
       dataFile.print(output_value1);
       dataFile.print(",");
       dataFile.print(output_value2);
       dataFile.print(",");
       dataFile.print(output_value3);
       dataFile.print(",");
       dataFile.print(output_value4);
       dataFile.close();

      }
      // if the file didn't open, print an error:
      else
        Serial.println("error opening DHT11Log.txt");
        delay(10000);
    }

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

body:
I think that the problem is here:

    output_value = map(output_value,1024,0,0,100);
    output_value1 = map(output_value,1024,0,0,100);
    output_value2 = map(output_value,1024,0,0,100);
    output_value3 = map(output_value,1024,0,0,100);
    output_value4 = map(output_value,1024,0,0,100);

replace them with:

    output_value = map(output_value,1024,0,0,100);
    output_value1 = map(output_value1,1024,0,0,100);
    output_value2 = map(output_value2,1024,0,0,100);
    output_value3 = map(output_value3,1024,0,0,100);
    output_value4 = map(output_value4,1024,0,0,100);