message:
Can I program a 20MHz Attiny85 with the 8MHz Internal Clock option in the Arduino Software?

I'm looking at using the ATTiny85 for a project, but have run into a snag. After following the tutorial found at https://learn.sparkfun.com/tutorials/tiny-avr-programmer-hookup-guide, I've installed the necessary files to be able to program an ATTiny85; however, the options given under "Clock" are 1MHz and 8MHz internal, as well as 8, 10, and 20MHz external.

Normally this wouldn't be a problem, except Digikey has no in-stock 8MHz flavored devices in the package I need (SOIC-8, don't have a reflow setup to use the QFN package).

If I buy the 20MHz version, will I be able to program them with the Arduino IDE set to the "8MHz Internal" clock option?

body:
I think you have the wrong end of the stick here. The Attiny85 is not a chip that comes in different speed versions. The datasheet mentions that it can run at 20 MHz. That doesn't mean you can buy a "20 MHz version". By selecting the appropriate clock option in fuses you can run at 20 MHz (or higher). From the datasheet:

> **High Frequency PLL Clock**
>
>There is an internal PLL that provides nominally 64 MHz clock rate locked to the RC Oscillator for the use of the Peripheral Timer/Counter1 and for the system clock source.

---

>  I believe these to be pre-set from the factory for the various clock options - but will it matter when I try to program them with the Arduino software?

That list is weird, it doesn't specifically say they are pre-set to any speed. Personally I would regard that list as meaning that the higher speed ones are manufactured to better tolerances, if indeed it means anything at all.

Maybe when they manufacture them they do a quick test at various speeds, and ones that don't run at 20 MHz are put into a different batch.

The datasheet specifies the default clock settings, it would be weird if Atmel made them with different settings unless you placed a massive order.

As for programming them, by default they don't come with a bootloader, so you would need to use ICSP programming anyway. You would need (in any case) something like the AVRISP device (which connects via USB to your computer, and the other end goes to your chip to be programmed). Or you can make up something like my [AVR hex programmer](http://www.gammon.com.au/forum/?id=11638) which lets you put a hex file from the IDE onto a MicroSD card, and then use that to program the ATtiny85.

In all of these cases you can change the fuses to do what you want, including the clock options you prefer.

There is a [board you can buy](http://www.crossroadsfencing.com/BobuinoRev17/Programmer.html) which is a pre-made gadget using the code I mention above, where you just press a button and the chip is programmed, which would be helpful if you are doing a lot of them.

[![CrossRoad programmer][1]][1]

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


sender: user

message:
Running a HC-SR501 PIR Sensor constantly using battery

I am not sure if this is the correct forum since I tend to use the ESP8266 standalone and not together with the arduino nano.
However, here is what I am planning.

I have a HC-SR501 PIR sensor, which I want to use to constantly track movements of animals outdoor. I dont want to go into further details, but 10 impulses per minute are expected (max. is 30/min) except for the night maybe.
I am planning to count the impulses for one hour, than send the sum to a webserver using wifi and reset the counter.
For powering I want a battery/akku solution (non-negotiable). Since the input of the PIR sensor is 4.8-20V I will directly connect it to the battery (provided the Voltage is high enough like with a 9V battery) and the ESP8266, which is used as WIFI station will be connected via an AMS1117 generating 3.3V.

WIFI Router which is connected to the internet is available and several sensor systems will be used to check several areas. Basic knowledge of using AT cmds or programming with Arduino IDE is given.

Questions:

 1. Can the ESP8266 module count impulses during one of the sleep modes?
 2. Do you have a less current consumpting module in mind allowing wifi transmittance? (LoRa or the NRF Module are not an option atm, since the router has to be used)
 3. What kind of battery/akku would you suggest? Having sufficient voltage and capacity (mAh) and still being easy to handle?

Optimum lifetime for the beginning would be 1 month for the first prototype. Afterwards a SolarModule + Akku solution will be implemented, but the first prototype has to be finished simple and fast yet satisfying :)

kind regards

sender: assistant

body:
This are multiple questions in one. But I will do my best to tackle them one by one.

> 1. Can the ESP8266 module count impulses during one of the sleep modes?

The ESP8266 has different power modes. Short answer: As long as the CPU is running, yes.

Long answer: The ESP8266 has quite a few power modes. They are easily put:

- No-sleep (as high as 170 mA while communicating)
- Modem-sleep (15 mA Wifi is off, everything else is running)
- Light-sleep (0.9 mA CPU is put to sleep and system clock stopped, can be waken up by a external interrupted)
- Deep-sleep (20 uA Everything is off, basically it's powered down, but can wake itself on set intervals or reset it to wake it. everything in RAM is lost, except RTC RAM)

So if your sensor gives a pulse, you can use that as a interrupt and go to light-sleep. If you need to pull it, all you can do is modem-sleep.

[ESP8266 power modes](https://www.espressif.com/sites/default/files/9b-esp8266-low_power_solutions_en_0.pdf)

> 2. Do you have a less current consumpting module in mind allowing wifi transmittance? (LoRa or the NRF Module are not an option atm, since the router has to be used)

Modem-sleep is your friend. Only connect to the router if there is data to send.

You can set up an AVR and use it in ultra low power mode and only turn on the esp if there is data to send. But explaining how to set that up goes way too far out of this scope.

> 3. What kind of battery/akku would you suggest? Having sufficient voltage and capacity (mAh) and still being easy to handle?

I can't choose a battery for you, there are just too many of them. But what I can do is tell you about how batteries work.

Take for example a 9 volt battery (not my first choice, you will see in a bit).

We take an energizer 522. It's a Alkaline battery and has 600 mAh. That means it can deliver 600 mA in one hour. But there is a catch. the more you draw from a Alkaline battery, the less capacity it will have.

It is 9 volts right? yes and no. you see. the voltage potential will drop (quite dramatically) over its lifetime.

A liniar voltage regulator (AMS1117) will take the needed mA of the output on the input and drop off the extra power as heat. So the battery will always have the same load (Yes, the esp8266 is a dynamic load, but lets keep it simple)

so lets say it's in modem-sleep (15mA). Lets divide 600 by 15, that is 40 hours of runtime. For simplicity I don't count the sensor itself.

[9 volt block datasheet](http://data.energizer.com/pdfs/522.pdf)

The AMS1117 needs 1.5 volts more then its output voltage for ensuring a stable output. So that is 4.8 volts or higher. But no higher than 12 volts.

[AMS1117 datasheet](http://www.advanced-monolithic.com/pdf/ds1117.pdf)

Choose a battery that has enough mAh and isn't more then 12 volts and not lower than 5 when depleted. If using outside, check if its operating temp range is wide enough.

So basically try to lower your energy footprint as far as it can possibly go and then based on the new average power usage, find a battery that is big enough for the task.

Better yet, get a solar cell and a rechargeable battery. It has a full list of other problems, but this answer is a bit too long already and that topic is out of the current scope.


message:
Rewrite part of the example code from Adafruit FONA

Recently, I bought the FONA 800 shield from Adafruit. I have got it running with the examples and it plays very nicely.

I want to use the part of the example code which handles a call in my own sketch. The example code waits for a number to call which should be entered in the serial. I want to do the exact same thing, just with the phone number supplied from a variable in Arduino.

I have two possibilities: To supply the whole number when the call should be performed and to build up let's say an array every time a number is entered.

The code for performing a call:

    // call a phone!
        char number[30];
        flushSerial();
        Serial.print(F("Call #"));
        readline(number, 30);
        Serial.println();
        Serial.print(F("Calling ")); Serial.println(number);
        if (!fona.callPhone(number)) {
          Serial.println(F("Failed"));
        } else {
          Serial.println(F("Sent!"));
        }

The flushSerial function:

    void flushSerial() {
      while (Serial.available())
      Serial.read();
    }

And the readline function:

    uint8_t readline(char *buff, uint8_t maxbuff, uint16_t timeout) {
    uint16_t buffidx = 0;
    boolean timeoutvalid = true;
    if (timeout == 0) timeoutvalid = false;

    while (true) {
      if (buffidx > maxbuff) {
        //Serial.println(F("SPACE"));
        break;
      }

    while (Serial.available()) {
      char c =  Serial.read();

      //Serial.print(c, HEX); Serial.print("#"); Serial.println(c);

      if (c == '\r') continue;
      if (c == 0xA) {
        if (buffidx == 0)   // the first 0x0A is ignored
          continue;

        timeout = 0;         // the second 0x0A is the end of the line
        timeoutvalid = true;
        break;
      }
      buff[buffidx] = c;
      buffidx++;
    }

    if (timeoutvalid && timeout == 0) {
      //Serial.println(F("TIMEOUT"));
      break;
    }
      delay(1);
    }
      buff[buffidx] = 0;  // null term
      return buffidx;
    }

It is the readline function which should be edited. Right now it retrieves the number entered from serial.

I am kind of a newbie myself so I am not that familiar with data types and so on.

Thank you very much for any answers.

EDIT:
The function without readline:

    if (!fona.callPhone("12345678")) {
            Serial.println(F("Failed calling"));
          } else {
            Serial.println(F("Calling ..."));
          }

body:
I had to enter the numbers as a string. Also I found out that I had set the variables in a wrong way.

The library for the FONA Shield needs the number to call as a string. They are creating it by assigning the input from serial to a char.
The problem was that I tried to input numbers. Also, I found out that when I tried to work with variables instead of hard coded numbers I messed around in data types.

Final conclusion:
When calling the fona.callPhone function, you have to put in a string containing the numbers instead of actual numbers.


message:
MQTT bridging with Arduino and ESP8266 - What software should I use?

Sorry for the vagueness in my question, I am just looking for ideas to point me in the correct direction please...

I wish to connect many (read: 20+) different sensors to a local wifi network and have them all datalogged and controlled by a single server on the network. Pretty standard stuff for the home automation people etc. Some sensors are connected to esp8266 boards directly, others communicate via serial and will employ an 8266 to provide wifi.

I am having trouble deciding which direction to go or which software / firmware to combine since its changing rapidly and a fair number of tutorials are around but all have different approaches and end goals.

This must be entirely contained offline - I have a raspberry pi, a wireless router, and the various sensors (mostly arduino based).

Now from research it would seem I need to setup a serial to MQTT 'bridge' - and have the esps 'talk' to the pi by MQTT. And that the pi should be running 'mosquitto' if I wish the MQTT to be bi-directional (i.e. I can receive serial data AND send serial commands. I have never dealt with MQTT so I am trying to learn as I go.

I have been working for a time with 'ESP-Link' software and had success using it as a simple serial to tcp-ip bridge and using virtual serial ports to communicate with the attached device. However using virtual serial ports on the server is clunky, unreliable and not what I wish to do - does anyone know if it can be setup so I can send 'raw' serial messages over TCP to the server for use? And from the server to control the connected devices? Or if there is an easier way? I cannot modify all of the serial devices I wish to connect, so just want to get the data out/in and have it manipulated by the server where necessary.

In essence I wish to end up with several sensors all connected to the router, and logged / controlled through a web interface hosted on the PI, all 'offline' and contained. Eventually I would like the server to be able to recognize what devices it can 'see' automatically, however at this moment I simply wish to gain insight into how I can most easily achieve this? Or even if I am completely mistaken in my approach?

Thanks

body:
[MQTT][1] is perfectly suited to this application. Here is an overview of a possible configuration. You should be able to find tutorials about each piece of the system.

On the Raspberry Pi:

 - Setup a [Mosquitto][2] server that can receive messages published by the ESP devices.
 - Write and run a MQTT client on the RPi that subscribes to the messages published by the ESP devices. This client would then store the data in some sort of permanent data store (database, flat files, whatever).
 - Write and run on the RPi a web app that reads and presents the data from the data store.

On the ESP devices:

 - Connect to the same wireless network as the RPi (or set up the RPi as an access point and have the devices connect to it)
 - Read data from the sensors and publish it to the MQTT server on the RPi.

If you want to push data to the ESP devices -- have them subscribe to certain messages (topics) on the MQTT server and then publish messages in those topics on the server.  Your web app could do this.

All of this can be done on an isolated network.

  [1]: http://docs.oasis-open.org/mqtt/mqtt/v3.1.1/os/mqtt-v3.1.1-os.html
  [2]: https://mosquitto.org/


body:
As you also asking about hardware I would recommend the following setup:

For sensors that only need to send data I would go with a
[ATtiny85](https://www.aliexpress.com/item/ATtiny-ATtiny85-Digispark-Kickstarter-Micro-USB-Development-Board-Module-For-Arduino-IIC-I2C-TWI-SPI-Low/32674596029.html). It has very low power consumption, is very small and easy to program. If you use 10-N of them then a [programming board](https://www.aliexpress.com/item/Free-Shipping-Pluggable-Development-Board-Programming-Editor-Micro-Usb-Power-Connector/32706943203.html) and only [the micro controller](https://www.aliexpress.com/item/Free-shipping-10PCS-ATTINY85-20PU-ATTINY85-20PU-ATTINY85-20-ATTINY85-ATMEL-DIP/1039693802.html) will be cheaper and even smaller.

For sensors that have some logic on it, maybe multiple attached sensors I would go with a [Wemos D1 Mini](https://www.aliexpress.com/item/ESP8266-ESP-12-ESP-12F-CH340G-CH340-V2-USB-WeMos-D1-Mini-WIFI-Development-Board-D1/32674463823.html). It has build in WIFI, you can debug it, it is still very small and there are a ton of [extension (shield) boards](https://www.aliexpress.com/wholesale?catId=0&initiative_id=AS_20180508074844&SearchText=wemos+d1+mini+shield) for it to speed up your development.

For the communication part I would go away from WIFI since 20+ devices can generate quiet some traffic. Also WIFI costs you a lot in terms of power consumption since it is not optimized for IoT (small data packages). I would add a [433mhz Mini Low Power RF Receiver/Transmitter](https://www.aliexpress.com/item/QIACHIP-433mhz-Mini-Low-Power-RF-Relay-Receiver-Transmitter-Module-Remote-Control-Switch-For-Arduino-Uno/32831237349.html) to my IoT hardware and communicate through that. It has a long range and has a very small power footprint.

Additionally you could think about using a [Wemos as MQTT gateway between your 433mhz devices and the WIFI](https://github.com/1technophile/OpenMQTTGateway) instead of your proposed Raspberry Pi solution. The nice benefit is that you will have a dedicated device managing an MQTT gateway that is far less error-prone as a Linux server (Raspberry Pi) and you don't need to update as often as with the Pi to keep it secure. There is a [Wemos D1 Mini Pro](https://www.aliexpress.com/item/Wemos-D1-Mini-Pro-NodeMcu-16M-Bytes-Antenna-Connector-Wifi-Internet-of-Things-Development-Board-Module/32796227142.html) that has a better WIFI antenna and a little bit more power that could be perfect for this use case.

The MQTT protocol is perfect for a sensor network since it is optimized for low bandwidth, high latency, and fragile connections. It supports Quality of Service (QoS) and you can configure what shall happen if a device disconnects/is not reachable anymore. There are a lot of library's already available for MQTT so that the setup is very quick. HiveMq has a nice [how to get started with MQTT](https://www.hivemq.com/blog/how-to-get-started-with-mqtt) guide for further reading.


message:
ZS-040 (HC-05) blueetooth module Arduino Mega

I followed this tutorial http://www.martyncurrey.com/using-an-arduino-mega-with-a-hc-05-zs-040-at-mode/ and it seems that the AT mode is on. (the LED is blinking like it's supposed)

I connected my pins like this:

>BT VCC to Arduino 5V out. Disconnect before running the sketch
>
BT GND to Arduino GND
>
BT RX (through a voltage divider) to Arduino TX1 (pin 18)

>BT TX  to Arduino RX1 (no need voltage divider)   (pin 19)

This is the code I run: (from the tutorial)

    // Basic Bluetooth test sketch 5a for the Arduino Mega.
    // AT mode using button switch
    // HC-05 with EN pin and button switch
    //
    // Uses serial with the host computer and serial1 for communication with the Bluetooth module
    //
    //  Pins
    //  BT VCC to Arduino 5V out. Disconnect before running the sketch
    //  BT GND to Arduino GND
    //  BT RX (through a voltage divider) to Arduino TX1 (pin 18)
    //  BT TX  to Arduino RX1 (no need voltage divider)   (pin 19)
    //
    // When a command is entered in to the serial monitor on the computer
    // the Arduino will relay it to the Bluetooth module and display the result.
    //

    char serialByte = '0';
    const byte  LEDPIN = 13;

    void setup()
    {
        pinMode(LEDPIN, OUTPUT);

        // communication with the host computer
        Serial.begin(9600);

        Serial.println("Do not power the BT module");
        Serial.println(" ");
        Serial.println("On the BT module, press the button switch (keep pressed, and at the same time power the BT module");
        Serial.println("The LED on the BT module should now flash on/off every 2 seconds");
        Serial.println("Can now release the button switch on the BT module");
        Serial.println(" ");
        Serial.println("After entering AT mode, type 1 and hit send");
        Serial.println(" ");

        // wait for the user to type "1" in the serial monitor
        while (serialByte !='1')
        {
            if ( Serial1.available() )   {  serialByte = Serial1.read();  }
        }

        // communication with the BT module on serial1
        Serial1.begin(38400);

        // LED to show we have started the serial channels
        digitalWrite(LEDPIN, HIGH);

        Serial.println(" ");
        Serial.println("AT mode.");
        Serial.println("Remember to to set Both NL & CR in the serial monitor.");
        Serial.println("The HC-05 accepts commands in both upper case and lower case");
        Serial.println(" ");
    }

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

        // listen for user input and send it to the HC-05
       if ( Serial.available() )   {  Serial1.write( Serial.read() );  }
    }

I want to mention that the baud rate is set to **9600** and **Both NL & CR** is also set.

The problem is when I insert `1` in the Serial Monitor and nothing happens. How can I solve this problem?

body:
**Solution**

Connection:

* Bluetooth RXD to Arduino Mega pin 11
* Bluetooth TXD to Arduino Mega pin 10
* Bluetooth VCC to Arduino Mega 5V
* Bluetooth GND to Arduino Mega GND

I used this code:

    #include <SoftwareSerial.h>

    #define RxD 10
    #define TxD 11

    SoftwareSerial BTSerial(RxD, TxD);

    void setup(){
      // replace BAUDRATE as suggested
      BTSerial.begin(BAUDRATE);
      Serial.begin(9600);
      BTSerial.print("AT\r\n");
    }

    void loop(){

      if (BTSerial.available())
        Serial.write(BTSerial.read());

      if (Serial.available())
        BTSerial.write(Serial.read());

    }

after setting AT mode as described in the tutorial above.

I tried running the code with `BAUDRATE` starting from 9600 to 460800:
![](https://i.stack.imgur.com/ZwIsp.png)


message:
ATtiny85 (Digispark) with 433mhz RF transmitter not working

I have the following components:

- [ATtiny85 Digispark](https://www.aliexpress.com/item/ATtiny-ATtiny85-Digispark-Kickstarter-Micro-USB-Development-Board-Module-For-Arduino-IIC-I2C-TWI-SPI-Low/32674596029.html)
- [433mhz Mini Low Power RF Transmitter](https://www.aliexpress.com/item/QIACHIP-433mhz-Mini-Low-Power-RF-Relay-Receiver-Transmitter-Module-Remote-Control-Switch-For-Arduino-Uno/32831237349.html)

I got a communication flow transmit/receive working between two Wemos D1 and like to outsource the transmitting part now to a ATtiny85. I used the same code as for the Wemos:

    #include <RCSwitch.h>

    RCSwitch mySwitch = RCSwitch();

    void setup() {
      pinMode(1, OUTPUT);
      mySwitch.enableTransmit(2);
    }

    void loop() {
        mySwitch.send("000110110001010100010001");
        digitalWrite(1, HIGH);
        delay(250);
        digitalWrite(1, LOW);
        delay(250);
    }

But the serial monitor for the Wemos does not receive any communication. I went so far that I built up the communication between the two Wemos again and connected only the data pin of the transmitter to the ATtiny85 in order to exclude any voltage problems (ATtiny gets 5V, transmitter likes <3.6V).

Now I am out of ideas. How can I debug the problem or what else can I try?

**Requested setup:**
[![enter image description here][1]][1]

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

body:
I got it to work. The last comment of @Maximilian Gerhardt about I/O output got me thinking and I read up on it. So if I use 5V to power the ATtiny the I/O output voltage representation for 1 and 0 are significantly higher then with 3.3V. So now I underclocked the ATtiny to 8Mhz in order to use a 3.3V power supply. This way the I/O output matches the transmitters expectations. Now the communication is working.

Thanks for your help Max!


message:
SyslogAppender for log4esp

I'd like to "merge" two Arduino libraires, namely [log4Esp](https://github.com/hunsalz/log4Esp) on one side and [Syslog](https://github.com/arcao/Syslog) on the other, hence creating a syslog appender for log4esp.

My problem is that log4esp's Appender prototype expects a method to return an instance of `Print` to which it'll write the message.

Syslog can't be used in this way.

**==> Question :** How to create a "Print buffer" / where can I find which class extends `Print`?

body:
Class `Print` is a base class of Arduino streaming. `Stream` is a derived class and adds reading capability. `Print` has only one abstract method `write` to write one byte to output or buffer. It is easy to [implement a derived custom class.][1]

The classes derived from Stream are classes for hardware and software serial like HardwareSerial for Serial singletons and different software serial implementations. From Stream is derived class File of the SD and SPIFFS library, TwoWire class for Wire singleton object, etc.

Class Client is derived from class Stream and is a base class for Arduino standard TCP networking. Examples of derived classes are EthernetClient, WiFiClient. For UDP, class UDP is derived from Stream, of course with implementations like EthernetUDP, WiFiUDP.

You can see this in the source code in local source file folders or in GitHub repositories.

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

  [1]: https://github.com/jandrassy/StreamLib/tree/master/src
  [2]: https://i.stack.imgur.com/3OV45.png


message:
Arduino program has suddenly stopped updating

I am writing a speedo/odometer program which was all working beautifully until I introduced an LCD screen and code for the LCD.

The screen works on power up, displays the distance recorded on an SD card, toggles from miles to km on the press of a button, but no longer runs my calculate method when invoked. The method has stopped working, or at least it's not updating with the latest information anymore when the method instructs it to. Any help would be greatly appreciated.

In case it matters, I am powering the project from an HTC one M8. Maybe it's lack of juice that is causing the issue, or just bad programming?

My code:

    #include <Arduino.h>
    #include <SPI.h>
    #include <SD.h>;
    #include <Wire.h>
    #include <LiquidCrystal_I2C.h>

    int InterruptPin = 2;
    //int PowerPin = 3;
    int ButtonPin = 4;
    int SDPin = 7;

    volatile long km = 0; // SAVE
    volatile float kmTemp = 0; // SAVE
    volatile int kmrevs = 0; // SAVE
    volatile long miles = 0; // SAVE
    volatile float milesTemp = 0; // SAVE
    volatile int milesrevs = 0; // SAVE

    volatile int kph = 0;
    volatile int mph = 0;
    volatile unsigned long start = 0;
    volatile unsigned long stop = 0;
    volatile float secs = 0;
    volatile float speed = 0;
    volatile float temp = 0;

    volatile int buttonState = 0;
    volatile int lastButtonState = 0;
    volatile boolean riding = false;

    File myFile;

    LiquidCrystal_I2C lcd(0x27, 16, 2);

    void calculate(){
        riding = true;

        // KPH SPEED CALCULATOR
        stop = millis() - start;
        start = millis();
        temp = (float)stop;
        secs = temp / 1000;
        speed = 1.854 / secs;
        speed = speed * 3.6;
        kph = speed;

        // MPH SPEED CONVERTOR
        float x = kph * 0.6214;
        mph = x;

        // KM DISTANCE CALCULATOR
        kmrevs++;
        if (kmrevs == 540){
            km++;
            kmrevs = 0;
            kmTemp = kmTemp + 0.00116;
        }
        if (kmTemp >= 1.0){
            km++;
            kmTemp = kmTemp - 1.0;
        }

        // MILES DISTANCE CALCULATOR
        milesrevs++;
        if (milesrevs == 868){
            miles++;
            milesrevs = 0;
            milesTemp = milesTemp +0.072;
        }
        if (milesTemp >= 1.0){
            miles++;
            milesTemp = milesTemp - 1.0;
        }

        // PRINT DATA TO LCD & SERIAL
        buttonState = digitalRead(ButtonPin);
        if (buttonState == HIGH){
            lastButtonState = buttonState;
            Serial.print(kph);
            Serial.print("kph  ");

            Serial.print(km);
            Serial.print("km  (");
            Serial.print(kmTemp, 6);
            Serial.println(")  ");

            lcd.clear();
            lcd.setCursor(0,0);
            lcd.print(kph);
            lcd.print("kph");
            lcd.setCursor(0,1);
            lcd.print(km);
            lcd.print("km");
        }
        if (buttonState == LOW){
           lastButtonState = buttonState;
            Serial.print(mph);
            Serial.print("mph  ");

            Serial.print(miles);
            Serial.print("miles  (");
            Serial.print(milesTemp, 6);
            Serial.println(")");

            lcd.clear();
            lcd.setCursor(0,0);
            lcd.print(mph);
            lcd.print("mph");
            lcd.setCursor(0,1);
            lcd.print(miles);
            lcd.print("miles");
        }

        // SAVE DATA TO SD CARD
        SD.remove("test.txt");
    myFile = SD.open("test.txt", FILE_WRITE);
        if (myFile) {
            myFile.print(km);
            myFile.print(" ");//
            myFile.print(kmTemp, 6);
            myFile.print(" ");//
            myFile.print(kmrevs);
            myFile.print(" ");//
            myFile.print(miles);
            myFile.print(" ");//
            myFile.print(milesTemp, 6);
            myFile.print(" ");//
            myFile.print(milesrevs);
            myFile.close();
        }
        else {
            // SD SAVE ERROR
            Serial.println("Save Error");
        }
    }

    void setup(){
        pinMode(ButtonPin, INPUT_PULLUP);
        pinMode(InterruptPin, INPUT);

        // POWER LCD SCREEN
        //lcd.begin(16,2);
        lcd.init();
        lcd.backlight();

        // LAUNCH SERIAL CONNECTION
        Serial.begin(9600);

        // LOAD DATA FROM SD CARD
        SD.begin(7);
        myFile = SD.open("test.txt", FILE_READ);
        if (myFile) {
           while (myFile.available()) {

           km = myFile.parseInt();
           kmTemp = myFile.parseFloat();
           kmrevs = myFile.parseInt();
           miles = myFile.parseInt();
           milesTemp=myFile.parseFloat();
           milesrevs = myFile.parseInt();

           }
        myFile.close();
        }
        else {
            Serial.println("Read Error");
        }

        // ATTACH INTERRUPTS
         attachInterrupt(digitalPinToInterrupt(2), calculate, RISING);

        // LOAD START SERIAL & LCD SPEED
        buttonState = digitalRead(ButtonPin);
        if (buttonState == LOW){
            // MPH DISPLAYED
            lastButtonState = buttonState;
            Serial.print("0mph  ");

            Serial.print(miles);
            Serial.print("miles  (");
            Serial.print(milesTemp, 6);
            Serial.println(")");

            lcd.clear();
            lcd.setCursor(0,0);
            lcd.print(mph);
            lcd.print("mph");
            lcd.setCursor(0,1);
            lcd.print(miles);
            lcd.print("miles");
        }
        if (buttonState == HIGH){
            // KPH DISPLAYED
            lastButtonState = buttonState;
            Serial.print("0kph  ");

            Serial.print(km);
            Serial.print("km  (");
            Serial.print(kmTemp, 6);
            Serial.println(")  ");

            lcd.clear();
            lcd.setCursor(0,0);
            lcd.print(kph);
            lcd.print("kph");
            lcd.setCursor(0,1);
            lcd.print(km);
            lcd.print("km");
        }
    }

    void loop(){
        buttonState = digitalRead(ButtonPin);

        // ZERO SPEED ON SLOW ROTATION
        if (riding == true){
        long period = millis() - start;
        if (period == 4150){
        if (buttonState == LOW){
            // MPH DISPLAYED
            lastButtonState = buttonState;
            Serial.print("0mph  ");

            Serial.print(miles);
            Serial.print("miles  (");
            Serial.print(milesTemp, 6);
            Serial.println(")");

            lcd.clear();
            lcd.setCursor(0,0);
            lcd.print(mph);
            lcd.print("mph");
            lcd.setCursor(0,1);
            lcd.print(miles);
            lcd.print("miles");
        }
        if (buttonState == HIGH){
            // KPH DISPLAYED
            lastButtonState = buttonState;
            Serial.print("0kph  ");

            Serial.print(km);
            Serial.print("km  (");
            Serial.print(kmTemp, 6);
            Serial.println(")  ");

            lcd.clear();
            lcd.setCursor(0,0);
            lcd.print(kph);
            lcd.print("kph");
            lcd.setCursor(0,1);
            lcd.print(km);
            lcd.print("km");
        }
        }
        }

        // CHANGE READING WHEN PRESSED
        if (buttonState != lastButtonState){
            long period = millis() - start;
            if (buttonState == HIGH && period < 4150){
            // KPH DISPLAYED
            lastButtonState = buttonState;
            Serial.print(kph);
            Serial.print("kph  ");

            Serial.print(km);
            Serial.print("km  (");
            Serial.print(kmTemp, 6);
            Serial.println(")  ");

            lcd.clear();
            lcd.setCursor(0,0);
            lcd.print(kph);
            lcd.print("kph");
            lcd.setCursor(0,1);
            lcd.print(km);
            lcd.print("km");
            }
            if (buttonState == HIGH && period > 4150){
            // KPH DISPLAYED
            lastButtonState = buttonState;
            Serial.print("0kph  ");

            Serial.print(km);
            Serial.print("km  (");
            Serial.print(kmTemp, 6);
            Serial.println(")  ");

            lcd.clear();
            lcd.setCursor(0,0);
            lcd.print(kph);
            lcd.print("kph");
            lcd.setCursor(0,1);
            lcd.print(km);
            lcd.print("km");
        }
        if (buttonState == LOW && period < 4150){
            // MPH DISPLAYED
            lastButtonState = buttonState;
            Serial.print(mph);
            Serial.print("mph  ");

            Serial.print(miles);
            Serial.print("miles  (");
            Serial.print(milesTemp, 6);
            Serial.println(")");

            lcd.clear();
            lcd.setCursor(0,0);
            lcd.print(mph);
            lcd.print("mph");
            lcd.setCursor(0,1);
            lcd.print(miles);
            lcd.print("miles");
        }
        if (buttonState == LOW && period > 4150){
            // MPH DISPLAYED
            lastButtonState = buttonState;
            Serial.print("0mph  ");

            Serial.print(miles);
            Serial.print("miles  (");
            Serial.print(milesTemp, 6);
            Serial.println(")");

            lcd.clear();
            lcd.setCursor(0,0);
            lcd.print(mph);
            lcd.print("mph");
            lcd.setCursor(0,1);
            lcd.print(miles);
            lcd.print("miles");
        }
        }
    }

body: Thanks guys, taking the labour out of the ISR has solved the problem perfectly. Unfortunately, the advice wasn't given as an answer so I'm unable to credit you for it, but appreciate the solutions given. Thanks.


message:
Interesting issue with my wifi Car project

Hello so i build a nodemcu wifi controlled car, everything works fine expect i have one small issue, currently i have 2 9v batterys, one of them is connected to motor controller and other one is connected to nodemcu.. but the nodemcu's 9v battery gets hot in a minute and stops working. What am i doing wrong? + is connected to vcc and - is connected to grnd on nodemcu.

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

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

body:
> the nodemcu's 9v battery gets hot in a minute and stops working. What am i doing wrong?

You're using a 9V battery.

Those batteries are useless. They have very little capacity, and can provide very little current. The NodeMCU needs a *lot* of current.

Choose a better battery. Maybe a Li-Poly battery would be good (mobile phone batteries are good for this).


message:
how long should interrupting signal last?

I want to apply the interruption of a program with a RISING signal from a pin. How long should the signal rise to be considered as the interruption?

body:
> If edge or toggle interrupt is selected, pulses that last longer than one clock period will generate an interrupt. Shorter pulses are not recommended to generate an interrupt.

Source (page 91, chapter 17.2.1 "External Interrupt Control Register A")


message:
Saving a .txt file to SD Card and Reading each content data to txt file then save it to a variable

I am new to arduino I am trying to create an arduino project that Saving a .txt file to SD Card and Reading the txt file then save it to a variable data type "Long" named 'savednum'. I had successfully can save the txt file and read it, however the problem lies in storing the read txtfile, when I read the txtfile and stored it in savednum and then serial print the savednum it gives different/ random numbers which is not equal to the data in the .txtfile that I store and read. I am wondering what seem to be wrong? Any suggestion is really appreciated. I thank you in advance.

    #include <TMRpcm.h>
     #include <SD.h>
     #include <SPI.h>
     #define SD_ChipSelectPin 4 //using digital pin 4 on arduino nano 328

     TMRpcm tmrpcm; // create an object for use in this sketch

    File myFile;

    char serialData;

    int i = 0;
    long n1 = 123456789;
    long n2 = 245678918;

    long savednum =0;

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

     }

    Serial.print("Initializing SD card...");

     if (!SD.begin(SD_ChipSelectPin)) {
    Serial.println("initialization failed!");
     while (1);
    }
    Serial.println("initialization done.");

     myFile = SD.open("NEWDATA.txt", FILE_WRITE);

    if (myFile) {
    Serial.print("Writing to NEWDATA.txt...");
    myFile.println(n1);
    myFile.println(n2);

    myFile.close();
    Serial.println("done.");
    } else {

    Serial.println("error opening NEWDATA.txt");
    }

    myFile = SD.open("NEWDATA.txt");
    if (myFile) {
    Serial.println("NEWDATA.txt:");

    while (myFile.available()) {
      Serial.write(myFile.read());
    // here the code I tried to read .txt file and store it in long
    savednum = myFile.read();
    Serial.println(savednum);
    }

    myFile.close();

    }

    }

    void loop()
     {

      }

body:
`myFile.read()` reads just one byte from the file - not the whole file or even a whole line.

You're reading one byte, then printing it. Then reading a second byte, storing that in a variable, then printing the variable. Then you loop back to the beginning again.

So you're printing alternate "odd" bytes, and storing / overwriting the variable with "even" bytes. So you just get nonsense.

You're storing the data in your file as ASCII text, so it's necessary to read the entirety of each line and then convert that string of characters into a number. Or read each character in turn and manipulate your total value for the line.

For example:

    long savedNum = 0;
    long numberOne = 0;

    while (myFile.available()) { // Something left to read
        char c = myFile.read(); // Get the next character
        if (isdigit(c)) { // It's a number 0-9
            savedNum *= 10; // Make room by decimal shifting to the left
            savedNum += (c - '0'); // Convert the character to a number and add it to the total
        } else if (c == '\n') { // End of line
            Serial.print(F("The number is: "));
            Serial.println(savedNum); // Show us the number
            numberOne = savedNum;  // Store it somewhere else - enhance this for multiple numbers.
            savedNum = 0;  // Reset to 0 ready to read the next line
        }
    }

The Arduino API (Stream class) also includes some handy helper functions, such as:

    int num = myFile.parseInt(); // get the next integer

There's no `parseLong()` though, but despite its name, `parseInt()` actually returns a `long`.  That reads characters up until it gets a non-numeric character and converts them to a long using the same method as in my example. It doesn't distinguish lines, though, so can be used to get separate numbers on the same line, such as `32847,2345534,12,-43`.

With your file though you may need to filter out the extra `\r` that may be in there from the line endings or you'll get missing numbers.


message:
Arduino and Python

Does anyone know how do I get Arduino and Python talking to each other? I would essentially like to write my code and export it somehow to the arduino-uno.

body:
You can not run python on an UNO. If you want to use python on a microcontoller you should look into boards supported by [MicroPython][1] or [Circuit Python][2]

  [1]: https://micropython.org/
  [2]: https://github.com/adafruit/circuitpython


message:
Arduino +CCLK at command parsing

I have arduino leonardo and sim800h module. I don't seem to find the problem in my program, this is probably the 5th time I'm rewriting it. Please someone tell me what should I change to work normally. I decodes the answers, but some chars seem to disappear and sometimes appear again. With time only +CCLK stays everything else is gone. Also the time should update all the time, but the seconds stay the same for 5-10 seconds.

This is the code:

 const long interval = 200;
 static long currentMillis;

 byte searchcharpos = 0; //To determine where is the + in +CCLK in the char array

 char serialdata[256]; //Array to store the chars before parsing

 char rtcy1[3]; //Current year  Format: yy\0
 char rtcm1[3]; //Current month  Format: mm\0
 char rtcd1[3]; //Current day  Format: dd\0
 char rtch1[3]; //Current hour  Format: hh\0
 char rtcmm1[3]; //Current minute  Format: mm\0
 char rtcs1[3]; //Current second  Format: ss\0

 byte pointingfinger = 0;

 char enabledtime = 0;

 char readenabl = 0;

 char foundchar[6];

 void setup() {
   Serial.begin(9600); //USB to Computer
   Serial1.begin(9600); //UART to Modem
   Serial1.print("ATE0\r"); //Disable echo
 }

 void loop() {
   if (millis() - currentMillis >= interval) //This is done every second
   {
  Serial1.print("AT+CCLK?\r");

  Serial.println("=========");
  Serial.print(serialdata[searchcharpos]);
  Serial.print(serialdata[searchcharpos + 1]);
  Serial.print(serialdata[searchcharpos + 2]);
  Serial.print(serialdata[searchcharpos + 3]);
  Serial.print(serialdata[searchcharpos + 4]);
  Serial.print(serialdata[searchcharpos + 5]);
  Serial.print(serialdata[searchcharpos + 6]);
  Serial.print(serialdata[searchcharpos + 7]);
  Serial.print(serialdata[searchcharpos + 8]);
  Serial.print(serialdata[searchcharpos + 9]);
  Serial.print(serialdata[searchcharpos + 10]);
  Serial.print(serialdata[searchcharpos + 11]);
  Serial.print(serialdata[searchcharpos + 12]);
  Serial.print(serialdata[searchcharpos + 13]);
  Serial.print(serialdata[searchcharpos + 14]);
  Serial.print(serialdata[searchcharpos + 15]);
  Serial.print(serialdata[searchcharpos + 16]);
  Serial.print(serialdata[searchcharpos + 17]);
  Serial.print(serialdata[searchcharpos + 18]);
  Serial.print(serialdata[searchcharpos + 19]);
  Serial.print(serialdata[searchcharpos + 20]);
  Serial.print(serialdata[searchcharpos + 21]);
  Serial.print(serialdata[searchcharpos + 22]);
  Serial.print(serialdata[searchcharpos + 23]);
  Serial.print(serialdata[searchcharpos + 24]);
  Serial.print(serialdata[searchcharpos + 25]);
  Serial.print(serialdata[searchcharpos + 26]);
  Serial.print(serialdata[searchcharpos + 27]);
  Serial.print(serialdata[searchcharpos + 28]);
  Serial.print(serialdata[searchcharpos + 29]);
  Serial.print(serialdata[searchcharpos + 30]);
  Serial.print ("=========");
  //Serial1.print("AT+CCLK?\r"); //ask for the time
  //delay(50);
  Serial.println("");
  Serial.println("=====");
  Serial.println(millis());

  Serial.println("YEAR: ");
  Serial.print(rtcy1[0]);
  Serial.println(rtcy1[1]);
  Serial.println("MONTH: ");
  Serial.print(rtcm1[0]);
  Serial.println(rtcm1[1]);
  Serial.println("DAY: ");
  Serial.print(rtcd1[0]);
  Serial.println(rtcd1[1]);
  Serial.println("HOUR: ");
  Serial.print(rtch1[0]);
  Serial.println(rtch1[1]);
  Serial.println("MINUTE: ");
  Serial.print(rtcmm1[0]);
  Serial.println(rtcmm1[1]);
  Serial.println("SECOND: ");
  Serial.print(rtcs1[0]);
  Serial.println(rtcs1[1]);

  enabledtime = 1;

  currentMillis = millis();
   }

   if (enabledtime == 1) {
   if (Serial1.available () > 0) {
  if (foundchar[0] == '\n') {
    /*for (byte a = 0; a < 255; a = a + 1 ) {
   serialdata[a] = 0;
   }*/
   readenabl = 0;
    //pointingfinger = 0;
    enabledtime = 0;
    rtcy1[0] = serialdata[searchcharpos + 8]; //getting first char with its offset
  rtcy1[1] = serialdata[searchcharpos + 9];
  rtcy1[2] = '\0';
  rtcm1[0] = serialdata[searchcharpos + 11];
  rtcm1[1] = serialdata[searchcharpos + 12];
  rtcm1[2] = '\0';
  rtcd1[0] = serialdata[searchcharpos + 14];
  rtcd1[1] = serialdata[searchcharpos + 15];
  rtcd1[2] = '\0';
  rtch1[0] = serialdata[searchcharpos + 17];
  rtch1[1] = serialdata[searchcharpos + 18];
  rtch1[2] = '\0';
  rtcmm1[0] = serialdata[searchcharpos + 20];
  rtcmm1[1] = serialdata[searchcharpos + 21];
  rtcmm1[2] = '\0';
  rtcs1[0] = serialdata[searchcharpos + 23];
  rtcs1[1] = serialdata[searchcharpos + 24];
  rtcs1[2] = '\0';
  }

  if (foundchar[0] == '\r') {
    readenabl = 0;
    //pointingfinger = 0;
    enabledtime = 0;
    rtcy1[0] = serialdata[searchcharpos + 8]; //getting first char with its offset
  rtcy1[1] = serialdata[searchcharpos + 9];
  rtcy1[2] = '\0';
  rtcm1[0] = serialdata[searchcharpos + 11];
  rtcm1[1] = serialdata[searchcharpos + 12];
  rtcm1[2] = '\0';
  rtcd1[0] = serialdata[searchcharpos + 14];
  rtcd1[1] = serialdata[searchcharpos + 15];
  rtcd1[2] = '\0';
  rtch1[0] = serialdata[searchcharpos + 17];
  rtch1[1] = serialdata[searchcharpos + 18];
  rtch1[2] = '\0';
  rtcmm1[0] = serialdata[searchcharpos + 20];
  rtcmm1[1] = serialdata[searchcharpos + 21];
  rtcmm1[2] = '\0';
  rtcs1[0] = serialdata[searchcharpos + 23];
  rtcs1[1] = serialdata[searchcharpos + 24];
  rtcs1[2] = '\0';
  }
  foundchar[0] = foundchar[1];
  foundchar[1] = foundchar[2];
  foundchar[2] = foundchar[3];
  foundchar[3] = foundchar[4];
  foundchar[4] = foundchar[5];
  foundchar[5] = Serial1.read();

  if (foundchar[0] == '+' && foundchar[1] == 'C' && foundchar[2] == 'C' && foundchar[3] == 'L' && foundchar[4] == 'K') {
    readenabl = 1;
    pointingfinger = 0;
  }
  if (readenabl == 1) {
    serialdata[pointingfinger] = foundchar[0];
    serialdata[pointingfinger + 1] = 0;
    pointingfinger++;
  }
   }
   }
 }

This is the output:

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

Thanks!

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

body:
This is the final working program that requests the time and parses the answer:

 const long interval = 1000;
 static long currentMillis;

 byte searchcharpos = 0; //To determine where is the + in +CCLK in the char array

 char serialdata[256]; //Array to store the chars before parsing

 char rtcy1[3]; //Current year  Format: yy\0
 char rtcm1[3]; //Current month  Format: mm\0
 char rtcd1[3]; //Current day  Format: dd\0
 char rtch1[3]; //Current hour  Format: hh\0
 char rtcmm1[3]; //Current minute  Format: mm\0
 char rtcs1[3]; //Current second  Format: ss\0

 byte pointingfinger = 0; //index of the array

 char enabledtime = 0; //this variable is set to 1 every second and set to 0 after parsing is done

 char readenabl = 0; //this is set to 1 when is finished reading from serial

 char foundchar[6]; //small buffer that works as a shift register to hold only the command for comparison

 void setup() {
   Serial.begin(9600); //USB to Computer
   Serial1.begin(9600); //UART to Modem
   Serial1.print("ATE0\r"); //Disable echo
 }

 void loop() {
   if (millis() - currentMillis >= interval) //This is done every second
   {
  Serial1.print("AT+CCLK?\r");

  Serial.println("=========");
  Serial.print(serialdata[searchcharpos]);
  Serial.print(serialdata[searchcharpos + 1]);
  Serial.print(serialdata[searchcharpos + 2]);
  Serial.print(serialdata[searchcharpos + 3]);
  Serial.print(serialdata[searchcharpos + 4]);
  Serial.print(serialdata[searchcharpos + 5]);
  Serial.print(serialdata[searchcharpos + 6]);
  Serial.print(serialdata[searchcharpos + 7]);
  Serial.print(serialdata[searchcharpos + 8]);
  Serial.print(serialdata[searchcharpos + 9]);
  Serial.print(serialdata[searchcharpos + 10]);
  Serial.print(serialdata[searchcharpos + 11]);
  Serial.print(serialdata[searchcharpos + 12]);
  Serial.print(serialdata[searchcharpos + 13]);
  Serial.print(serialdata[searchcharpos + 14]);
  Serial.print(serialdata[searchcharpos + 15]);
  Serial.print(serialdata[searchcharpos + 16]);
  Serial.print(serialdata[searchcharpos + 17]);
  Serial.print(serialdata[searchcharpos + 18]);
  Serial.print(serialdata[searchcharpos + 19]);
  Serial.print(serialdata[searchcharpos + 20]);
  Serial.print(serialdata[searchcharpos + 21]);
  Serial.print(serialdata[searchcharpos + 22]);
  Serial.print(serialdata[searchcharpos + 23]);
  Serial.print(serialdata[searchcharpos + 24]);
  Serial.print(serialdata[searchcharpos + 25]);
  Serial.print(serialdata[searchcharpos + 26]);
  Serial.print(serialdata[searchcharpos + 27]);
  Serial.print(serialdata[searchcharpos + 28]);
  Serial.print(serialdata[searchcharpos + 29]);
  Serial.print(serialdata[searchcharpos + 30]);
  Serial.print ("=========");
  //Serial1.print("AT+CCLK?\r"); //ask for the time
  //delay(50);
  Serial.println("");
  Serial.println("=====");
  Serial.println(millis());

  Serial.println("YEAR: ");
  Serial.print(rtcy1[0]);
  Serial.println(rtcy1[1]);
  Serial.println("MONTH: ");
  Serial.print(rtcm1[0]);
  Serial.println(rtcm1[1]);
  Serial.println("DAY: ");
  Serial.print(rtcd1[0]);
  Serial.println(rtcd1[1]);
  Serial.println("HOUR: ");
  Serial.print(rtch1[0]);
  Serial.println(rtch1[1]);
  Serial.println("MINUTE: ");
  Serial.print(rtcmm1[0]);
  Serial.println(rtcmm1[1]);
  Serial.println("SECOND: ");
  Serial.print(rtcs1[0]);
  Serial.println(rtcs1[1]);

  enabledtime = 1;

  currentMillis = millis();
   }

   if (enabledtime == 1) {
  if (Serial1.available () > 0) {
    /*
   if (foundchar[0] == '\n') {
     readenabl = 0;
   //pointingfinger = 0;
   enabledtime = 0;
   rtcy1[0] = serialdata[searchcharpos + 8]; //getting first char with its offset
   rtcy1[1] = serialdata[searchcharpos + 9];
   rtcy1[2] = '\0';
   rtcm1[0] = serialdata[searchcharpos + 11];
   rtcm1[1] = serialdata[searchcharpos + 12];
   rtcm1[2] = '\0';
   rtcd1[0] = serialdata[searchcharpos + 14];
   rtcd1[1] = serialdata[searchcharpos + 15];
   rtcd1[2] = '\0';
   rtch1[0] = serialdata[searchcharpos + 17];
   rtch1[1] = serialdata[searchcharpos + 18];
   rtch1[2] = '\0';
   rtcmm1[0] = serialdata[searchcharpos + 20];
   rtcmm1[1] = serialdata[searchcharpos + 21];
   rtcmm1[2] = '\0';
   rtcs1[0] = serialdata[searchcharpos + 23];
   rtcs1[1] = serialdata[searchcharpos + 24];
   rtcs1[2] = '\0';
   }
   if (foundchar[0] == '\r') {
   readenabl = 0;
   //pointingfinger = 0;
   enabledtime = 0;
   rtcy1[0] = serialdata[searchcharpos + 8]; //getting first char with its offset
   rtcy1[1] = serialdata[searchcharpos + 9];
   rtcy1[2] = '\0';
   rtcm1[0] = serialdata[searchcharpos + 11];
   rtcm1[1] = serialdata[searchcharpos + 12];
   rtcm1[2] = '\0';
   rtcd1[0] = serialdata[searchcharpos + 14];
   rtcd1[1] = serialdata[searchcharpos + 15];
   rtcd1[2] = '\0';
   rtch1[0] = serialdata[searchcharpos + 17];
   rtch1[1] = serialdata[searchcharpos + 18];
   rtch1[2] = '\0';
   rtcmm1[0] = serialdata[searchcharpos + 20];
   rtcmm1[1] = serialdata[searchcharpos + 21];
   rtcmm1[2] = '\0';
   rtcs1[0] = serialdata[searchcharpos + 23];
   rtcs1[1] = serialdata[searchcharpos + 24];
   rtcs1[2] = '\0';
   }

   if (foundchar[0] == '\r') {
   readenabl = 0;
   //pointingfinger = 0;
   enabledtime = 0;
   rtcy1[0] = serialdata[searchcharpos + 8]; //getting first char with its offset
   rtcy1[1] = serialdata[searchcharpos + 9];
   rtcy1[2] = '\0';
   rtcm1[0] = serialdata[searchcharpos + 11];
   rtcm1[1] = serialdata[searchcharpos + 12];
   rtcm1[2] = '\0';
   rtcd1[0] = serialdata[searchcharpos + 14];
   rtcd1[1] = serialdata[searchcharpos + 15];
   rtcd1[2] = '\0';
   rtch1[0] = serialdata[searchcharpos + 17];
   rtch1[1] = serialdata[searchcharpos + 18];
   rtch1[2] = '\0';
   rtcmm1[0] = serialdata[searchcharpos + 20];
   rtcmm1[1] = serialdata[searchcharpos + 21];
   rtcmm1[2] = '\0';
   rtcs1[0] = serialdata[searchcharpos + 23];
   rtcs1[1] = serialdata[searchcharpos + 24];
   rtcs1[2] = '\0';
   }
    */
    foundchar[0] = foundchar[1];
    foundchar[1] = foundchar[2];
    foundchar[2] = foundchar[3];
    foundchar[3] = foundchar[4];
    foundchar[4] = foundchar[5];
    foundchar[5] = Serial1.read();

    if (foundchar[0] == '+' && foundchar[1] == 'C' && foundchar[2] == 'C' && foundchar[3] == 'L' && foundchar[4] == 'K' && foundchar[5] == ':') {
   readenabl = 1;
   pointingfinger = 0;
    }
    if (readenabl == 1) {
   while (foundchar[0] != '\n') {
     if (Serial1.available() > 0) {
    serialdata[pointingfinger] = foundchar[0];
    serialdata[pointingfinger + 1] = 0;
    pointingfinger++;
    foundchar[0] = foundchar[1];
    foundchar[1] = foundchar[2];
    foundchar[2] = foundchar[3];
    foundchar[3] = foundchar[4];
    foundchar[4] = foundchar[5];
    foundchar[5] = Serial1.read();

     }
   }
   readenabl = 0;
   //pointingfinger = 0;
   enabledtime = 0;
   rtcy1[0] = serialdata[searchcharpos + 8]; //getting first char with its offset
   rtcy1[1] = serialdata[searchcharpos + 9];
   rtcy1[2] = '\0';
   rtcm1[0] = serialdata[searchcharpos + 11];
   rtcm1[1] = serialdata[searchcharpos + 12];
   rtcm1[2] = '\0';
   rtcd1[0] = serialdata[searchcharpos + 14];
   rtcd1[1] = serialdata[searchcharpos + 15];
   rtcd1[2] = '\0';
   rtch1[0] = serialdata[searchcharpos + 17];
   rtch1[1] = serialdata[searchcharpos + 18];
   rtch1[2] = '\0';
   rtcmm1[0] = serialdata[searchcharpos + 20];
   rtcmm1[1] = serialdata[searchcharpos + 21];
   rtcmm1[2] = '\0';
   rtcs1[0] = serialdata[searchcharpos + 23];
   rtcs1[1] = serialdata[searchcharpos + 24];
   rtcs1[2] = '\0';
    }
  }
   }
 }


message:
What is the minimal possible latency between arduino and PC

Case specifications:

 - PC OS: Debian 9, x64 arch
 - Starting time point: i have a 1kb buffer on arduino that i want to send to host PC
 - Ending time point: i have recieved the buffer in a custom written C\C++ app running on a host PC
 - I want to send such a buffer once a second

What is the minimal possible latency - time passed between starting and ending points? and with what communication type? (serial?)

body:
it is not exactly what you ask, but yesterday I tested the speed with this sketch:

    void setup() {
      Serial.begin(460800);
      delay(5000);
    }

    void loop() {
      Serial.println();
      unsigned long start = millis();
      for (unsigned long i = 0; i < 1000000L; i++) {
        Serial.write('A');
      }
      Serial.flush();
      Serial.println();
      Serial.println(millis() - start);
      while(true);
    }

to receive on linux to file:

    stty -F /dev/ttyACM0 460800
    (stty raw; cat > received.txt) < /dev/ttyACM0

the sketch measured 20000 ms to push that 1MB over Serial. the Arduino is Mega 2560. at 921600 baud not all data were transfered.

EDIT: Nano 328p clone with CH340 complete only at 230400 baud in 45000 ms


body:
There is more to low-latency communication than just squirting data as fast as you can (though that is an important part of it).

One thing people often forget is that the Arduino can only (easily) do one thing at a time. While you're sending your buffer to the PC it can't be sampling and filling your buffer.  If you have a buffer which fills up over the period of 1 second and you want to send that buffer to the PC when full, what happens during the subsequent second while you're sending the buffer? The buffer can't be being filled while it's being sent.

Using a normal UART to USB connection as most of the normal Arduino boards (Uno, Mega, etc) use the fastest you can reasonably expect is around 1MBaud. That's about 100kB/s.  Less if you use a cheap Chinese clone with a CH340G.  Even at 100kB/s your 1kB buffer, if sent completely raw and in binary, would take around 10ms to transfer. But getting the computer to make any sense of that raw data would be hard. So you'd need to wrap it in some form of protocol (up to you to design that...) so you may get half that speed (or worse depending on your protocol design).

And during that time not much else can happen.

For smooth low-latency communication of data it is much more preferable to use "ping-pong" buffers and interrupt- or DMA-driven sampling of your data. That means that one buffer is receiving your data from whatever source, and the other is being sent to the PC. Once the first buffer is filled up they reverse roles. However, the little 8-bit Arduinos aren't really suited for that kind of thing:

* They don't have much RAM to waste on two buffers
* They don't have interrupts with priorities to allow samples to occur while sending
* They don't have DMA to do background transfers of data to/from peripherals

If latency is really that critical you would be better using one of the ARM-based Arduinos, such as the Due, where you can also then take advantage of a high-speed native USB interface which can give much higher throughput than a UART connection. Your choice of USB endpoint can also influence the latency of your design:

* Isochronous - Lowest latency, small packets, not guaranteed to be delivered
* Interrupt - Medium latency, small packets, delivery guaranteed
* Bulk - High latency, large packets, delivery guaranteed

Isochronous is used mainly for audio where you would notice the slightest delay in sound, but wouldn't necessarily notice or worry about a slight glitch in the quality. Interrupt is used for things like HID where you need it to respond to you pressing the keys on your keyboard nice and fast, but you're never sending much data (64 byte packet limit on interrupt transfers).  Bulk is used for things like CDC/ACM (Serial over USB) where you may want to tranfer lots of data but wouldn't notice if it's pausing for a few ms every now and then (HS USB has a 512 byte packet limit on bulk transfers, FS USB has a 64 byte limit).

One of the great things with a direct USB connection is that underneath it is all packet-based, so you can use that as your transfer protocol if you know what you're doing. Don't just rely on the CDC/ACM "pipe", but instead make use of the underlying USB protocol to send individual packets which the receiving program can then understand and break apart into the right data without adding any extra protocol overheads.

For more advanced USB programming the Teensy and chipKIT cores have far more sophisticated USB support than the Arduino core, so you may fancy taking a look at their offerings in the way of boards that may suit your needs better.


message:
GPS not display

so im currently trying to do a a project whereby if my sensor is active, it will display my location. but, it seems that when the sensor is active, it only display location of lat: 0.00 , long: 0.00 on my LCD display.
help me to solve this problem.

    #include <LiquidCrystal.h>
    #include <TinyGPS++.h>
    #include <SoftwareSerial.h>

    SoftwareSerial mySerial(9,10);
    char msg;

    int knockPin = 7;                   // Use Pin 7 as our Input
    int knockVal = HIGH;                // This is where we record our shock measurement
    boolean bAlarm = false;
    int knockValue = digitalRead(6);
    unsigned long lastKnockTime;        // Record the time that we measured a shock
    int knockAlarmTime = 500;           // Number of milli seconds to keep the knock alarm high

    static const int RXPin = 13, TXPin = 8;
    static const int GPSBaud = 9600;
    TinyGPSPlus gps;
    SoftwareSerial ss(RXPin, TXPin);

    const int rs = 12, en = 11, d4 = 5, d5 = 4, d6 = 3, d7 = 2;
    LiquidCrystal lcd(rs, en, d4, d5, d6, d7);

    void setup ()
    {
      mySerial.begin(19200);   // Setting the baud rate of GSM Module
      delay(20000);
      ss.begin(GPSBaud);
      Serial.begin(115200);
      Serial.println("GSM SIM900A BEGIN");
      pinMode (knockPin, INPUT) ;       // input from the KY-031
      pinMode (6, OUTPUT);
      lcd.begin(16, 2);
      String latitude = String(gps.location.lat(),6);
      String longitude = String(gps.location.lng(),6);
          lcd.clear();
          lcd.setCursor(2,0);
          lcd.print("VeCAS System");
          lcd.setCursor(3,1);
          lcd.print(">>Begin>>");
          delay (5000);

    }

    void loop ()
    {
      knockVal = digitalRead (knockPin) ; // read KY-031 Value

      if (knockVal == LOW)                // If we see a knock
      {

        lastKnockTime = millis();         // record the time of the shock
                                          // The following is so you don't scroll on the output screen
        if (!bAlarm)
        {

          Serial.println("KNOCK, KNOCK");
          bAlarm = true;
          digitalWrite (6, HIGH);
          Serial.println(knockVal);
          delay(100);

          while (ss.available() > 0)
        gps.encode(ss.read());
        if (gps.location.isUpdated())
           lcd.clear();
          lcd.setCursor(4,0);
          lcd.print("KNOCK!");
          lcd.setCursor(3,1);
          lcd.print("Detected");
          delay (5000);

              lcd.clear();
              Serial.print("Latitude= ");
              Serial.print(gps.location.lat(), 6);
              Serial.print(" Longitude= ");
              Serial.println(gps.location.lng(), 6);

              lcd.setCursor(0,0);
              lcd.print("LAT:");
              lcd.setCursor(5,0);
              lcd.print(gps.location.lat());
              lcd.setCursor(0,1);
              lcd.print("LON:");
              lcd.setCursor(5,1);
              lcd.print(gps.location.lng());
              delay(1000);
              lcd.clear();

        }
       }

     else
      {
        if( (millis()-lastKnockTime) > knockAlarmTime  &&  bAlarm)
        {
          Serial.println("no knocks");
          bAlarm = false;
          digitalWrite (6, LOW);
          delay(100);
        }
       }
      }

    void gpsTrack()
    {
          lcd.clear();
          lcd.setCursor(4,0);
          lcd.print("KNOCK!");
          lcd.setCursor(3,1);
          lcd.print("Detected");
          delay (5000);

              lcd.clear();
              Serial.print("Latitude= ");
              Serial.print(gps.location.lat(), 6);
              Serial.print(" Longitude= ");
              Serial.println(gps.location.lng(), 6);

              lcd.setCursor(0,0);
              lcd.print("LAT:");
              lcd.setCursor(5,0);
              lcd.print(gps.location.lat());
              lcd.setCursor(0,1);
              lcd.print("LON:");
              lcd.setCursor(5,1);
              lcd.print(gps.location.lng());
              delay(1000);
              lcd.clear();
    }

body:
You have two SoftwareSerial ports. You can't reliably use two of them at once. Only one can be set to receive data, and that one is the first one you define. You can switch between them with the `listen()` function, but it's not recommended.  If you never want to receive on one of them then it's (almost) fine, but when sending on any of them nothing can be received anywhere (not even on the hardware Serial port).

Adding to `setup()` after `ss.begin(GPSBaud)`:

    ss.listen();

may make it work for the time being, but as soon as you start doing anything more with `mySerial` you could run into trouble.

If you need more than one serial port in your design then you really should be looking at using a more capable board with more hardware UART ports.


body:
If you put the GPS on `Serial` (pins 0 & 1) and the GSM on `AltSoftSerial` (pins 8 & 9), it could work.  You will have to disconnect pin 0 to upload new sketches over USB.  I *assume* that you have an UNO or Nano, because you didn't say which Arduino you are using.

Like Majenko said, this will never work with two `SoftwareSerial` ports.  `SoftwareSerial` is very inefficient, because it disables interrupts for long periods of time.  This can interfere with other parts of your sketch or with other libraries.  And it cannot send and receive at the same time.  [This answer provides complete details.](https://arduino.stackexchange.com/questions/34126#34130)

You may also want to take a look at my [NeoGPS](https://github.com/SlashDevin/NeoGPS) library.  It is smaller, faster, more reliable and more accurate than all other GPS libraries.  Even if you don't use it, you should read the page about [choosing a serial port](https://github.com/SlashDevin/NeoGPS/blob/master/extras/doc/Installing.md#2-choose-a-serial-port).  There are also many tips on the [Troubleshooting page](https://github.com/SlashDevin/NeoGPS/blob/master/extras/doc/Troubleshooting.md).

NeoGPS, AltSoftSerial and NeoSWSerial are available from the IDE Library Manager, under the menu **Sketch -> Include Library -> Manage Libraries**.

BTW, you can't use `delay` like that.  You must constantly read and decode the GPS characters.  The sketch will lose many, many GPS characters, preventing it from ever getting complete GPS information.  You have to do something like this:

    #include <LiquidCrystal.h>
    #include <NMEAGPS.h>
    #include <AltSoftSerial.h>

    AltSoftSerial gsmPort; // receive pin 8 to GSM TX, transmit pin 9 to GSM RX

    char msg;

    int knockPin = 7;                   // Use Pin 7 as our Input
    int knockVal = HIGH;                // This is where we record our shock measurement
    boolean bAlarm = false;
    int knockValue = digitalRead(6);
    unsigned long lastKnockTime;        // Record the time that we measured a shock
    int knockAlarmTime = 500;           // Number of milli seconds to keep the knock alarm high

    static const int GPSBaud = 9600;
    NMEAGPS gps;
    gps_fix fix;
    #define gpsPort Serial // RX pin 0 to GPS TX, TX pin 1 to GPS RX

    const int rs = 12, en = 11, d4 = 5, d5 = 4, d6 = 3, d7 = 2;
    LiquidCrystal lcd(rs, en, d4, d5, d6, d7);

    void setup ()
    {
      gsmPort.begin(19200);   // Setting the baud rate of GSM Module

      gpsPort.begin(GPSBaud);
      //Serial.begin(115200);  // gpsPort *is* serial
      //  Serial Monitor has to be set at 9600 (lower right
      //    corner of Serial Monitor window)
      Serial.println("GSM SIM900A BEGIN");
      pinMode (knockPin, INPUT) ;       // input from the KY-031
      pinMode (6, OUTPUT);

      lcd.begin(16, 2);
      lcd.clear();
      lcd.setCursor(2,0);
      lcd.print("VeCAS System");
      lcd.setCursor(3,1);
      lcd.print(">>Begin>>");
      delay( 1000 );
    }

    void loop ()
    {
      // Check for GPS characters (always!)
      if (gps.available( gpsPort )) {
        fix = gps.read(); // save the latest GPS fields in one structure
        gpsTrack();       // show the latest GPS fields
      }

      // Check for knocks

      knockVal = digitalRead (knockPin) ; // read KY-031 Value

      if (knockVal == LOW)                // If we see a knock
      {

        lastKnockTime = millis();         // record the time of the shock
                                          // The following is so you don't scroll on the output screen
        if (!bAlarm)
        {

          bAlarm = true;
          digitalWrite (6, HIGH);

          Serial.println("KNOCK, KNOCK");
          Serial.println(knockVal);

          lcd.clear();
          lcd.setCursor(4,0);
          lcd.print("KNOCK!");
          lcd.setCursor(3,1);
          lcd.print("Detected");
        }
      }
      else
      {
        if( (millis()-lastKnockTime) > knockAlarmTime  &&  bAlarm)
        {
          Serial.println("no knocks");
          bAlarm = false;
          digitalWrite (6, LOW);
        }
      }
    }

    void gpsTrack()
    {
      Serial.print("Latitude= ");
      if (fix.valid.location)
        Serial.print( fix.latitude(), 6);
      Serial.print(" Longitude= ");
      if (fix.valid.location)
        Serial.println( fix.longitude(), 6);

      lcd.clear();
      lcd.setCursor(0,0);
      lcd.print("LAT:");
      lcd.setCursor(5,0);
      if (fix.valid.location)
        lcd.print( fix.latitude() );
      lcd.setCursor(0,1);
      lcd.print("LON:");
      lcd.setCursor(5,1);
      if (fix.valid.location)
        lcd.print( fix.longitude() );
    }

Notice that it also checks the location validity flag *before* using the lat/lon values.  Your GPS may not know the location, perhaps due to bad satellite reception.


message:
How to prevent shoot-through when swiching a motor with a bridge?

Ideally, when wiring a motor with an H-Bridge one would ensure that all "open" operations are performed before and "close" operations in order to prevent a short circuit. **How does one ensure that these operations are performed in order when using a bridge?**

I see on some forums that the L298 IC is a recommended bridge for controlling motors with the Arduino, but this condition is seemingly never discussed. It is not an issue with the speed of modern ICs or are the common tutorials overlooking shoot-through in the interest of simplicity?

body:
You only get this kind of problem when you are manually controlling the high- and low-side switches manually.  Bridge chips seldom make you do that and include the logic and drive circuitry within them so that you just control a HIGH or LOW to a "leg" and it switches the two transistors properly for you.

You normally get an "enable" and a "direction" input.

For instance, take the L298 internal circuit:

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

If we look at the left-most transistor pair you can see they are driven by a pair of gates. One has an inversion on the input.  The gates are mainly there to AND the *enable* signal in, but the inversion on the upper input of the lower gate is the vital thing. That makes sure that one transistor is on when another is off. You can't turn both on, or both off - you only have a single signal that indicates which should be on.

Of course, that circuit is very simplified, and there is additional circuitry that ensures that during the switching period one transistor switches off before the other switches on.  Matched transistors with known switching characteristics, adding offsets to the base voltages with diodes, etc are all methods that are used internally.

With MOSFET based bridges it's less of an issue since gate threshold (*VGS*) come into play and choosing and matching the transistors correctly automatically creates a "dead zone" in the switching input voltage range.

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


message:
Wiring parallel TFT with ESP32

I have this [Parallel LCD TFT][1]. I want to connect it with an ESP32 (NodeMCU). I am using the [TFT_eSPI][2] library.
In the TFT_eSPI documentation, it says that the connection should be as following:

    // The ESP32 and TFT the pins used for testing are:
    //#define TFT_CS   33  // Chip select control pin (library pulls permanently low
    //#define TFT_DC   15  // Data Command control pin - use a pin in the range 0-31
    //#define TFT_RST  32  // Reset pin, toggles on startup

    //#define TFT_WR    4  // Write strobe control pin - use a pin in the range 0-31
    //#define TFT_RD    2  // Read strobe control pin  - use a pin in the range 0-31
    //#define TFT_D0   12  // Must use pins in the range 0-31 for the data bus
    //#define TFT_D1   13  // so a single register write sets/clears all bits.
    //#define TFT_D2   26  // Pins can be randomly assigned, this does not affect
    //#define TFT_D3   25  // TFT screen update performance.
    //#define TFT_D4   17
    //#define TFT_D5   16
    //#define TFT_D6   27
    //#define TFT_D7   14

P.S. My tft does not have DC PIN. So, I wired nothing to GPIO15

After I wired the TFT, the ESP32 stop responding to flash process. and obviously, it did not run anything(even if I flash it without the screen and then wiring it again)

My question is:

 - What is the mistake did I do? How can I link this parallel LCD with ESP32

  [1]: http://www.kumantech.com/kuman-uno-r3-35-tft-display-screen-with-sd-card-socket-for-arduino-mega-2560-board-module-sc3a_p0109.html
  [2]: https://github.com/Bodmer/TFT_eSPI

body:
Sorry for the Late reply, I had the same issue.
You cant have anything connected to pin 15 or 2 during flash


message:
Best method of detecting peg in hole

I’ve got a large wall with 1” holes scattered about. I’ve got some wooden pegs that fit perfectly into these holes. Now I’m thinking of creating a light installation based on the pegs, but i’m Struggling to find a way of detecting when a peg has been inserted into any hole.

What’s the best method of detecting them? I was thinking a stop switch that’s just placed on the edge of the hole to the peg activates it, but i’m Not sure how well that can be detected or if it would bend with use

body:
We can't tell you the "best" method.  It depends on too many details we don't have.

Here are some options:

 * A reed switch at the bottom of the hole and a magnet on the peg.
 * A photo sensor at the back of the hole -- the peg blocks the light.
 * As you suggest, a switch at the side of hole.
 * Use contrasting colors on the wall and the pegs and detect the pegs using a camera and some sort of image processing (not an Arduino solution)

I think you are going to need to build some prototypes and experiment to find the best option for you.


message:
When to use PROGMEM?

I believe PROGMEM is used to store large data (e.g. strings) that don't change. So it frees up the SRAM.

[in the Ardunio Reference][1] it is mentioned that.

"Using PROGMEM is also a two-step procedure. After getting the data into Flash memory, it requires special methods (functions), also defined in the pgmspace.h library, to read the data from program memory back into SRAM, so we can do something useful with it."

If I have to load the data into SRAM before using it then how is it efficient than directly stroing into SRAM by defining vaiable normally

  [1]: https://www.arduino.cc/reference/en/language/variables/utilities/progmem/

body:
Say you have a string of 1000 characters in Flash, and you want to print it to Serial.  Yes, you need to load it into RAM in order to pass that data around the place for printing. But, do you need to put *all* of it in RAM at once?  No.  You only need one character at a time.  So instead of taking 1000 characters and allocating 1000 bytes of RAM and copying the whole shebang into RAM then printing it, you just need to allocate 1 byte of RAM* and copy each character in turn and print it.

Since you can only read one character at a time from flash there's no advantage in reading the whole lot anyway.

----

*Actually, because of compiler optimizations, this probably never even touches RAM and just stays in a CPU register.


body:
If you have a constant c-string (char array) in your code without F macro or progmem, then the string is copied into RAM at start an stays there.

If in a function you use the F macro or you create a char buffer of some size and copy the progmem string into the buffer, on function return the variables are deleted from stack and the memory is released.

In case of some big array, if you put it into progmem and then in the code when you need to lookup a value in that array, you need to copy to RAM only one array item at time not the whole array.


body:
Like Majenko said, you do not need to put everything you have in flash storage into RAM at once.  You can move items into SRAM as necessary, and reuse the memory once you're done.

However, you are not limited to moving one byte at a time.  There are functions defined in [`avr/pgmspace.h`](http://www.nongnu.org/avr-libc/user-manual/pgmspace_8h.html) that can handle moving data for you.

For instance, you could do something like:

    const struct mystruct_s my_value PROGMEM = { value = 1234 };

    // ...

    struct mystruct_s working_copy;
    memcpy_P(&working_copy, &my_value, sizeof(struct mystruct_s));
    int foo = working_copy.value / 2;


message:
Arduino String: use a non-null-terminated char array?

I'm using a library that takes a `String` as it's parameter (https://github.com/gmag11/painlessMesh)

I want to pass char arrays that is binary (UTF-8) data that also contains null-bytes (`0x00`). Right now, the resulting String is cut off at the first null-byte as expected. I know the full length of the char array, is it possible to construct an Arduino String while passing the arbitrary length, so that the full String also contains the null-bytes including the data that follows after, up until the pre-set length?

I had this problem before and then I solved it by converting the UTF-8 data to hex and then add a null-byte. I was hoping there is a more elegant way, since this forces me to double the data-size.

Thanks!

body:
Assuming you are talking about the function

    bool painlessMesh::sendBroadcast( String &msg, bool includeSelf = false)

Then you'll see that ultimately, the library passes `msg` into the function `buildMeshPackage` where it constructs a JSON message ([see here](https://github.com/gmag11/painlessMesh/blob/master/src/painlessMeshComm.cpp))

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

    String ICACHE_FLASH_ATTR painlessMesh::buildMeshPackage(uint32_t destId, uint32_t fromId, meshPackageType type, String &msg) {
        debugMsg(GENERAL, "In buildMeshPackage(): msg=%s\n", msg.c_str());

        DynamicJsonBuffer jsonBuffer;
        JsonObject& root = jsonBuffer.createObject();
        root["dest"] = destId;
        //root["from"] = _nodeId;
        root["from"] = fromId;
        root["type"] = (uint8_t)type;

        switch (type) {
        case NODE_SYNC_REQUEST:
        case NODE_SYNC_REPLY:
        {
            JsonArray& subs = jsonBuffer.parseArray(msg);
            if (!subs.success()) {
                debugMsg(GENERAL, "buildMeshPackage(): subs = jsonBuffer.parseArray( msg ) failed!");
            }
            root["subs"] = subs;
            break;
        }
        case TIME_SYNC:
            root["msg"] = jsonBuffer.parseObject(msg);
            break;
        default:
            root["msg"] = msg;
        }

        String ret;
        root.printTo(ret);
        return ret;
    }

Even if you did construct a `String` with null terminators in it, the moment it gets put into the JSON string it destroys everything. JSON by default doesn't support binary data strings ([reference][1]).

So, the library is a problem because it happily passes data as JSON messages, and that's bad if you want binary data transported. You could use Base64 or the more efficient http://base91.sourceforge.net/ encoding though to mitigate this a little bit, or search for a different lib.

  [1]: https://stackoverflow.com/questions/1443158/binary-data-in-json-string-something-better-than-base64


message:
TMP36 not working with arduino uno?

I have an Arduino Uno hooked up with a TMP36 and an ESP8266 to send the temperature reading to a PHP file which receives the post request and stores it in a text file.

The ESP8266 and PHP works fine and I'm positive of that. But the temperature my code gets are ridiculous and change a lot. I'll include my code and a Fritzing sketch and the URL to the data.txt (you can see the results real time). It might be a problem with my code or something else I'm not sure I've fiddled around to no success and hopefully some fresh eyes will help.

[![][1]][1]

Most of the code is copypasta as I've never used ESP8266 before.

    #include "SoftwareSerial.h"

    String ssid ="correctssid";
    String password="correctpwd";

    float val=0;
    int temppin = 2;
    float volts=0.0;
    float tempC=0.0;

    SoftwareSerial esp(6, 7);

    String data;
    String server = "www.elijahdur.co.uk";
    String url = "/arduino/esp8266/file.php"; //I've changed this just well because

    void setup() {
      esp.begin(9600);
      Serial.begin(9600);
      reset();
      connectWifi();
    }

    void reset() {
      esp.println("AT+RST");
      delay(1000);
      if(esp.find("OK") ){
        Serial.println("Module Reset");
      }
    }

    void connectWifi() {
      String cmd = "AT+CWJAP=\"" +ssid+"\",\"" + password + "\"";
      esp.println(cmd);
      delay(4000);

      if(esp.find("OK")) {
        Serial.println("Connected!");
      }

      else {
        connectWifi();
        Serial.println("Cannot connect to wifi");
      }
    }

    void loop () {
      val = analogRead(temppin);
      volts = val * 5.0;
      volts /= 1024.0;
      tempC = (volts - 0.5) * 100;

      String string = (String) tempC;
      data = "data=" + string;
      httppost();

      delay(30000);
    }

    void httppost () {
      esp.println("AT+CIPSTART=\"TCP\",\"" + server + "\",80");//start a TCP connection.

      if( esp.find("OK")) {
        Serial.println("TCP connection ready");
      }

      delay(1000);

      String postRequest =
      "POST " + url + " HTTP/1.0\r\n" +
      "Host: " + server + "\r\n" +
      "Accept: *" + "/" + "*\r\n" +
      "Content-Length: " + data.length() + "\r\n" +
      "Content-Type: application/x-www-form-urlencoded\r\n" +
      "\r\n" + data;

      String sendCmd = "AT+CIPSEND=";//determine the number of caracters to be sent.

      esp.print(sendCmd);
      esp.println(postRequest.length());

      delay(500);

      if(esp.find(">")) {
        Serial.println("Sending..");
        esp.print(postRequest);
      }

      if( esp.find("SEND OK")) {
        Serial.println("Packet sent");
      }

      while (esp.available()) {
        String tmpResp = esp.readString();
        Serial.println(tmpResp);
      }

      esp.println("AT+CIPCLOSE");

    }

The txt file is located at http://elijahdur.co.uk/arduino/esp8266/data.txt

Sometimes is will straight up give -50 and it's because it reads 0 and takes away the 5V from the analog.

Any help is greatly appreciated thank you!

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

**EDIT:** Apologies, but I had mixed up my sensors and was using an LM35, it still does not work however so I'm still stuck :/

body:
First off, as a general debugging tip: Always use a minimal example to only test one component to make sure it works. You should have tested the temperature sensor on its own, then the ESP8266 WiFi connection.

Second, regarding this code:

      /* as global variable */
      float val=0;

    void loop () {
      val = analogRead(temppin);
      volts = val * 5.0;
      volts /= 1024.0;
      tempC = (volts - 0.5) * 100;

      String string = (String) tempC;
      data = "data=" + string;
      httppost();

      delay(30000);
    }

The line `String string = (String) tempC;` looks very suspicious to me. You are casting a `float` to a `String` object, i.e., you re-interpret it with a cast operator. That should not work because a `float` is not a `String` object.

What should work is creating a new `String` object using its constructor, i.e., write

     String string(tempC);

If this is does not work, use the sketch at https://learn.adafruit.com/tmp36-temperature-sensor/using-a-temp-sensor, change sensorPin to `2`, double check your wiring and remove the ESP8266.

And as 3rd note: You are hooking up your Arduino's TX directly to the ESP8266's RX pin, according to your schematic. This will damage the ESP8266 module, because it is a 3.3V device and should only receive 3.3V signals -- your Arduino Uno outputs 5V as a logic 'high'. You need a voltage divider or a logic level shifter between them.


body:
This [instructables](http://www.instructables.com/id/How-to-use-the-TMP36-temp-sensor-Arduino-Tutorial/) does the TMP36 part very similar using tempPin=0 instead 2 ,
I'd try that code because there shouldn't be a negative value as long you are measuring room temperate and the TMP36 is not defective.

According to these curves

[![TMP35/36/37 diagram][1]][1]

and table from the TMP35/36/37 data sheet
[![TMP35/36/37 data sheet][2]][2]

you should measure 700-750mV (with VS 3V)

  [1]: https://i.stack.imgur.com/0RsXr.png
  [2]: https://i.stack.imgur.com/zvHqZ.png


message:
USB upload to Pro Micro (32u4)

My project is based around the ATMEGA32u4 microcontroller.

I followed the Arduino Pro Micro schematic to design my own board layout and build a custom PCB, soldered on the components.  Then I used the Arduino IDE to successfully upload the Arduino bootloader with SPI.

Currently I can also upload programs to my `32u4 over SPI (using "in-serial programming").  Tested that with Blink.

But I cannot upload programs with the USB, like you would normally be able to do with a Pro Micro.  What things should I look for to debug this?

    avrdude: Version 6.3, compiled on Jan 17 2017 at 12:00:53
         Copyright (c) 2000-2005 Brian Dean, http://www.bdmicro.com/
         Copyright (c) 2007-2014 Joerg Wunsch

         System wide configuration file is "C:\Users\Myname\AppData\Local\Arduino15\packages\arduino\tools\avrdude\6.3.0-arduino9/etc/avrdude.conf"

         Using Port                    : COM12
         Using Programmer              : avr109
         Overriding Baud Rate          : 57600
         AVR Part                      : ATmega32U4
         Chip Erase delay              : 9000 us
         PAGEL                         : PD7
         BS2                           : PA0
         RESET disposition             : dedicated
         RETRY pulse                   : SCK
         serial program mode           : yes
         parallel program mode         : yes
         Timeout                       : 200
         StabDelay                     : 100
         CmdexeDelay                   : 25
         SyncLoops                     : 32
         ByteDelay                     : 0
         PollIndex                     : 3
         PollValue                     : 0x53
         Memory Detail                 :

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

         Programmer Type : butterfly
         Description     : Atmel AppNote AVR109 Boot Loader

    Connecting to programmer: .avrdude: butterfly_recv(): programmer is not responding

body:
The answer, as kindly pointed out by Gerben, is that ISP program upload overwrites the bootloader.

Only upload the bootloader via ISP, then switch to USB for uploading Arduino sketches.


message:
ESP8266 check if TCP client disconnected...informally

Hi with ESP8266WiFi library, I usually check for connection of a TCP client with client.connected().

But it seems to still return **true** if my TCP client in an unexpected way (like disconnect to WiFi/ Power loss/...). Which leaves my program stuck in a infinite loop.

Is there a more reliable to check for connection status?

body:
You have the inherent problem that a TCP connection is terminated by an explicit "FIN" message from the terminating party, followed by a FIN-ACK and ACK.

![](https://upload.wikimedia.org/wikipedia/commons/thumb/5/55/TCP_CLOSE.svg/2000px-TCP_CLOSE.svg.png)

Refer to [here][1].

If your client (or server) just powers off without closing the connection properly, that's it. The connection hangs up and no data will be transfered if it is not explicitly handled.

If you must know whether the client is still there, you must use a heartbeat meachanism. That is, after some period time without a response has passed, query the connection party with a "heartbeat" message and see if it responds after a given maximum time. The other way around would be to make the client send a periodic "Keep Alive" message which holds up the connection as long as it is sent repeadetly.

Refer to [here][2] and [here][3].

  [1]: https://en.wikipedia.org/wiki/Transmission_Control_Protocol#Connection_termination
  [2]: https://en.wikipedia.org/wiki/Heartbeat_(computing)
  [3]: https://en.wikipedia.org/wiki/Keepalive


message:
Why call a USB connection a serial connection?

Does anyone know why Arduino calls a USB connection a serial? When I hear a serial connection I automatically think of a male pin connection and not a USB connection. Also not sure if this a Linux term or just an Arduino thing.

body:
As @ratchetfreak answered, USB is a **Serial** bus. But there is more.

The microcontroller on Arduino boards has one or more built-in peripherals called `UART`s, which stands for **Universal Asynchronous Receiver-Transmitter**.

This is what the Arduino core calls a Serial port. It uses the same kind of protocol as the old DB-9 serial ports on PCs and such, but at 5V or 3.3V logic levels. Contrast this 0V to 5V voltage swing to indicate Logic LOW and Logic HIGH with the RS-232 standard for the old PC serial ports, which use a +12V to -12V swing to indicate such.

But PCs today don't often have the old RS-232 serial port. They instead have the new USB - Universal Serial Bus - port. On the Arduino board is chip that communicates on one side via USB with the PC and tells the PC that it provides the equivalent of the old COMPORT or /dev/ttyS* serial device; and on the other side via UART with the microcontroller on the Arduino board.

It's like we are "emulating" the old PC serial ports in software over the new USB bus, which itself is a serial communication system, though much more complex than a plain UART.


body:
On most Arduinos `Serial` is not a USB connection. It is a UART (real serial) connection which is used to communicate with a USB to UART adaptor (often made out of another small MCU, the ATMega16U2).  It's only from that chip onwards that it is USB.  Between the main MCU and that USB interface chip it is serial. The same serial you get from pins 0/1 (literally: it's hardwired together).

Indeed, the first Arduino prototype (that grew out of the Wiring project) had no USB at all - only Serial. The USB to UART adaptor was added later. But it still remains a Serial interface.

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

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


body: Almost all the ways protocols used to communicate on arduino are Serial.  USB,UART, I2C, SPI. Serial means one bit at a time, then the other way is Parallel communication which is what printers used to use. This allowed a whole byte to sent at one time(there were 8 data lines). As clock speeds increased there was no longer a need to have these big bulky,expensive cables and connectors. So away went parallel connections from common computer/electronics applications.


message:
RFID-RC522 Cannot read from MIFARE Ultralight

I tried many ways to get and print UID and other data from MIFARE Ultralight but it always ends with error. I am using `RFID-RC522` reader with **Arduino UNO** and [MFRC522 Library][1].
I can normally get and print the PICC type of chip, but that's the only thing that works.

That's how I have connected my RC522 reader:

[![enter image description here][2]][2]
<sub>(source: [ytimg.com](https://i.ytimg.com/vi/23aMjljCLZI/maxresdefault.jpg))</sub>

This is my code:

    #include <SPI.h>
    #include <MFRC522.h>

    #define RST_PIN 9
    #define SS_PIN 10

    MFRC522 rfid(SS_PIN, RST_PIN);

    unsigned long noSignal = 0;

    bool lastState = true;
    bool read = true;

    void setup()
    {
     pinMode(2, OUTPUT); //Red led
     pinMode(3, OUTPUT); //Green led

     Serial.begin(9600);
     SPI.begin();
     while (!Serial);

     rfid.PCD_Init();
     Serial.println("RFID ctecka byla uspesne spustena."); //Prints "RFID Reader succesfully started"
     Serial.println();

     changeLed(true);
    }

    void changeLed(bool red)
    {
     digitalWrite(2, red);
     digitalWrite(3, !red);
    }

    void loop()
    {
     if (millis() - noSignal >= 300)
     {
      changeLed(true);
      read = true;
     }

     bool state = !rfid.PICC_IsNewCardPresent() && !rfid.PICC_ReadCardSerial();

     if (state != lastState)
      if (state)
       noSignal = millis();
      else if (read)
      {
       read = false;

       changeLed(false);
       noSignal = millis();

       Serial.println("---------Cip detekovan----------"); //Prints "Chip detected"
       Serial.println();

       MFRC522::PICC_Type piccType = rfid.PICC_GetType(rfid.uid.sak);

       Serial.print("Znacka cipu: ");//Prints chip type
       Serial.println(rfid.PICC_GetTypeName(piccType));

       rfid.PICC_DumpToSerial(&rfid.uid); //Here is the error

       Serial.println();
       Serial.println("---------Cteni skoncilo----------");//prints "Read ended"
       Serial.println();

       rfid.PICC_HaltA();
       rfid.PCD_StopCrypto1();
      }

     lastState = state;
    }

Serial monitor snapshot:

[![][3]][3]

Maybe important thing is that when i call `PCD_DumpVersionToSerial()` i get:

    Firmware Version: 0x12 = (unknown)

Somewere I read that my Arduino isn't compatibile with MIFARE Ultralight and I need MIFARE Classic cards. Is that true? Can I solve this problem by using other library or it's hardware problem? Thanks

Btw. Sorry for my english, it's not my native language.

  [1]: https://github.com/miguelbalboa/rfid
  [2]: https://i.stack.imgur.com/rHwFQ.jpg
  [3]: https://i.stack.imgur.com/4dbi9.jpg

**EDIT:**
I asked my friend, which have arduino too from same shop like me, if he can read MIFARE Ultralight cards. He said that it's working for him. So my problem will be probably on hardware side. We both have unoficial arduino from aliexpress.

body:
In the first lines of code there are two lines that say:

    #define RST_PIN 9
    #define SS_PIN 10
They define the RESET pin to be on the D9 pin and the SDA on the D10 pin.
So you have an connection error try connecting like shown and you should be good to go.

[![default connection ][1]][1]

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


message:
2 buttons, 1 servo, turn when pressed only

I have a code problem. I need to turn a servo clockwise or counter clockwise using 2 microswitches.

The problem is that my code is fine on startup, but when i press the button the servo continues to spin.

How do i make this so it only spins while the buttons are pressed and turn off when they are not pressed?

    #include <Servo.h>

    Servo myservo; // create servo object to control a servo

    // CONSTANTS

    // PINS
    const int crServo = 12; // sets pin 12 as servo
    const int buttonPinCW = 2; // sets pin 2 as button; CW => clockwise => FOCUS FAR
    const int buttonPinCC = 3; // sets pin 3 as button; CC => counterclockwise => FOCUS NEAR

    // SERVO PROPERTIES
    const int crSpeedDefault = 0; // is the stay still position, motor should not turn
    const int crSpeedCW = 110; // turns the motor full speed clockwise
    const int crSpeedCC = 70; // turns the motor full speed counter-clockwise

    // SET BUTTON STATES
    int buttonStateCW = 0; //sets button 1 as off
    int buttonStateCC = 0; // sets button 2 as off

    void setup()
    {
      myservo.attach(crServo); // attaches the servo on pin 12 to the servo object
      pinMode (crServo, OUTPUT);
      pinMode (buttonPinCW, INPUT); // sets button as input
      pinMode (buttonPinCC, INPUT); // sets button as input
      myservo.write(crSpeedDefault); // default servo to crSpeedDefault
    }

    void loop()
    {
      crServo = digitalRead(crSpeedDefault);
      buttonStateCW = digitalRead(buttonPinCW);
      buttonStateCC = digitalRead(buttonPinCC);
      // clockwise rotation
      if (buttonStateCW == HIGH) {
        myservo.write(crSpeedCW);
        // counterclockwise rotation
      }
      if (buttonStateCC == HIGH) {
        myservo.write(crSpeedCC);
      }
    }

body:
If you want the logic "if none of the two buttons are pressed, stop the servo immediately", then you'd express this in your `loop` as a `if` expression where you check if both buttons read `LOW`:

    void loop()
    {
      buttonStateCW = digitalRead(buttonPinCW);
      buttonStateCC = digitalRead(buttonPinCC);
      // clockwise rotation
      if (buttonStateCW == HIGH) {
     myservo.write(crSpeedCW);
     // counterclockwise rotation
      }
      if (buttonStateCC == HIGH) {
     myservo.write(crSpeedCC);
      }

      //Are both buttons not pressed?
      if(buttonStateCC == LOW && buttonStateCW == LOW) {
     //Stop the servo.
     myservo.write(0);
      }
    }

This assumes your buttons are with pull-down resistors to GND on one side and with +5V on the other side, as detailed in the [Arduino tutorial](https://www.arduino.cc/en/Tutorial/Button). In short this means that an unpressed button reads as `0` and a pressed on reads as `1` (`HIGH`). This is unusual because we usually use the internal pullup resistors via the `INPUT_PULLUP` `pinMode` parameter with a switched logic (`1` = unpressed, `0` = pressed).

I've also removed the line `crServo = digitalRead(crSpeedDefault);` because that doesn't make sense in my opinion, as I've detailed in my comment.


body:
This solution is similar to @Maximilian Gerhardt's solution. So his comments on the pull-up/down resistors apply.

I assume that you only want to turn either CW or CC and not oscillate between the two.

Then you should cater for 4 button conditions:
None pressed, CW only press, CC only press, both pressed.

We only need to worry about the "only pressed" conditions and a default state when coding.

Here is my solution:

    void loop()
    {
      buttonStateCW = digitalRead(buttonPinCW);
      buttonStateCC = digitalRead(buttonPinCC);

      // CW button pressed only
      if (buttonStateCW == HIGH && buttonStateCC == LOW) {
        myservo.write(crSpeedCW); // clockwise rotation
      }
      // CC button pressed only
      else if (buttonStateCW == LOW && buttonStateCC == HIGH) {
        myservo.write(crSpeedCC); // counterclockwise rotation
      }
      // Default condition
      else {
        myservo.write(crSpeedDefault);
      }
    }