message:
Stepper motor based clock movement with DS3231

I am working on a clock movement that is powered using a stepper motor and the GSM2 driver board. The delay between steps needed to achieve 1 rpm on the second hand works out to 25 ms. In my current setup, I am sending pulses to the driver board using the delay() function. This works reasonably well, although it is not accurate enough for me. To remedy this problem, I ordered a DS3231 RTC module, thinking I could use that to replace delay()/millis(). However, I can't figure out how to achieve millisecond resolution using the RTC. It seems like it should be strait forward given the oscillator on board the RTC is 32kHz. I am new to arduino programming and am out of my comfort zone with this one.

Does anyone know of a way to achieve the 25 ms pulses we need while still retaining the accuracy of the RTC? Is it possible to use the RTC to correct the output produced by the built in delay()/millis() function? How would you then translate that output to pulses sent to the stepper motor driver board?

Internet research produces some mixed results on whether or not this is possible. I have yet to see an example of a clock with millisecond resolution. The theory behind it makes sense, but I don't know where to start.

body:
It is unclear, why you need the high accuracy, and you didn't include your code. So my explanations will be as broad as your question.

"millisecond resolution" is a broad term. Generally you have to consider 2 different errors.

1. The jitter for every `millis()` value
2. clock drifting over time

You can eliminate the second point quite easily using the RTC with the [Time library][1]. It uses the RTC as a reference, so that you don't have the clock drifting this much. Though, you would have to use the libraries functions for all time related things, since it does not change the value of `millis()` or it's siblings.

Also, for low differences in the range of a few milliseconds, you should better use `micros()` instead of `millis()` (if you are not using the RTCs functions).

---

> How would you then translate that output to pulses sent to the stepper motor driver board?

It is unclear, why exactly you need "millisecond resolution", and you didn't show us your code. But there are multiple Stepper libraries on the web, for example the standard [Stepper][2] library or the [AccelStepper][3] library (Accelstepper is more capable, don't know, if you need it). With the AccelStepper libraries you can set a certain speed and target position and then you simply call then `run()` method (haven't looked up the name, but there is definitely a function like that) until the desired position is reached. The method itself will only pulse the stepper, if it is time to do so. So you are freed from doing all the stuff with `millis()`, since the library is doing that for you.

Though the libraries are using the Arduinos internal time: `millis()` and siblings. To change that, you would have to change the library.

  [1]: https://github.com/PaulStoffregen/Time
  [2]: https://github.com/arduino-libraries/Stepper
  [3]: https://github.com/adafruit/AccelStepper


sender: user

sender: assistant

body:
Consider a Phase Locked Loop (PLL) to synchronize your 40x 25ms pulses with your 1pps RTC.

If you need 25ms/pulse to get 1rpm, that's 2400ppm or 1pulse/0.025ms=40pps.  If you get a 1pps pulse out of the RTC, you can use it to discipline your timing.  https://www.romanblack.com/one_sec.htm is a good reference.

The basic trick is to keep track of the mismatch and run faster when it is slow, and run slower when it is too fast.

Try something like the below, but replace the LED pulse stuff with your stepper code.

    // pps_pll.ino for https://arduino.stackexchange.com/questions/67699/stepper-motor-based-clock-movement-with-ds3231
    //
    // Adapting code from https://www.arduino.cc/reference/en/language/functions/external-interrupts/attachinterrupt/
    // to do a PPS PLL per https://www.romanblack.com/one_sec.htm

    const int pps = 40;
    const int pulse_us = 1;
    const int pulse_interval = (1000L / pps);
    int count = 0; //
    int count_at_sync = 0; //
    unsigned long next_pulse = 0; //
    unsigned long pulse_off = 0;

    const byte led_pin = LED_BUILTIN;
    const byte interrupt_pin = 2; // Choose pin per https://www.arduino.cc/reference/en/language/functions/external-interrupts/attachinterrupt/
    volatile byte state = LOW;

    void setup() {
      pinMode(led_pin, OUTPUT);
      pinMode(interrupt_pin, INPUT_PULLUP);
      attachInterrupt(digitalPinToInterrupt(interrupt_pin), sync_ISR, RISING);
    }

    void loop() {
      unsigned long loop_micros = micros();  // capture start of loop time
      if (loop_micros >= next_pulse) {
        // Schedule pulse
        digitalWrite(led_pin, HIGH);
        next_pulse += pulse_interval ;
        pulse_off = loop_micros + pulse_us; // schedule off time
        // PLL accounting
        count++;
        if (count_at_sync > 0) next_pulse++; // too fast: slow down
        else if (count_at_sync < 0) next_pulse--; // too slow: speed up
      }
      if (state == HIGH && loop_micros >= pulse_off) {
        state = LOW;
      }
      digitalWrite(led_pin, state);
    }

    void sync_ISR() { // called by 1pps interrupt
      count_at_sync = (count -= pps); // PLL accounting and record synchronization state
    }


message:
Using Arduino to Record analog signals with SPI ADC + Sampling Rate Issue

I am using Arduino UNO to Read 8-channel, 24-bits resolution Analog signals using ADS1299 Analog-fornt-end. ADS1299 use SPI interface to talk with Arduino. Currently, I can record the analog signal with arduino based on the SPI protocol and send the data via serial port to the PC.

The ADS1299 has 8 channels with 24-bits resolutions. The sampling rate can be defined from 250s/s to 16Ks/s. As you can see in the below code, when the data is ready I put the device in reading data mode and store 8-bits (1-byte) in each run and concatenate 3 bytes to make a full sample. I repeat these procedures to obtain the whole samples of all channels. At the end I have sent a sample of one channel to the serial port using serial.print command.

Here is my problem: If I want to increase the sampling rate of device to e.g 10 Ks/s the arduino fails to provide this sampling rate due to  delay produced by Serial.println command. Is is possible to store the data into a big array and then send the whole array via serial port?  Is it possible that other types of microcontroller such as ARM types handle this issue? Generally how it is possible to avoid the delay of serial print?

        #include <SPI.h>
        #define WAKEUP 0x02
        #define STANDBY 0x04
        #define RESET 0x06
        #define START 0x08
        #define STOP 0x0a
        #define RDATAC 0x10
        #define SDATAC 0x11
        #define RDATA 0x12
        #define TESTaa 0xaa
        #define TEST55 0x55

        #define CONFIG1 0x01
        #define CONFIG2 0x02
        #define CONFIG3 0x03
        #define CH1SET 0x05
        #define CH2SET 0x06
        #define CH3SET 0x07
        #define CH4SET 0x08
        #define CH5SET 0x09
        #define CH6SET 0x0A
        #define CH7SET 0x0B
        #define CH8SET 0x0C

          const int PIN_START = 7;
          const int IPIN_DRDY = 9;
          const int PIN_CS = 10;

          const int DOUT = 12;
          const int DIN = 11;
          const int PIN_SCLK = 13;
          const int PIN_RESET = 8;

          byte chSet;
          byte chSet2;
          boolean flag = false;
          long t0, t;

        void setup(){

          // You can use serial communication for debugging
          Serial.begin(2000000);
          Serial.flush();
          delayMicroseconds(100);
          // You have to set SPI communication according to datasheet
          SPI.setDataMode(SPI_MODE1);
          //SPI.setClockDivider(SPI_CLOCK_DIV16);
          SPI.setBitOrder(MSBFIRST);
          SPI.begin();

          pinMode(DOUT, OUTPUT);
          pinMode(PIN_SCLK, OUTPUT);
          pinMode(PIN_CS, OUTPUT);
          pinMode(PIN_START, OUTPUT);
          pinMode(IPIN_DRDY, INPUT);
          pinMode(PIN_RESET, OUTPUT);

          //reset communication, see datasheet
            digitalWrite(PIN_SCLK, LOW);
            digitalWrite(DIN, LOW);
            digitalWrite(PIN_CS, HIGH);

          digitalWrite(PIN_CS, LOW); //Low to communicated
          SPI.transfer(RESET);
          digitalWrite(PIN_CS, HIGH); //Low to communicated

          // Wait longer for TI chip to start
          delay(500);
          send_command(SDATAC);
          delay(10);
          chSet = read_byte(0x00);
          Serial.println("-- ID CHIP is:" + hex_to_char(chSet) );

          // Write Config 1 and 2: see datasheet page 47
          // Config 1: Bits 7 6 5 4 3 2 1 0 --- 1 DAISY_EN=1 CLK_EN=0 1 0 DR[2:0] (110-- 250 Sample/S)  --->   0b11010110
          // Config 2: Bits 7 6 5 4 3 2 1 0 ----  1 1 0 INT_CAL=1(Int/Ext test sig) 0 CAL_AMP=(calibration signal amplitude)
          // CAL_FREQ[1:0] (calibration signal frequency)  ----->  0b11010100

          // for normal operation write to config1 0x02, config2 0xA0. For test signal write 0xA3 to config2
          write_byte(CONFIG1, 0x96);   // Daisy chain Enabled: D6 , Daisy chain Disabled: 96
          delay(10);

          write_byte(CONFIG2, 0xD1);   // Test signal Enabled: D0   Test signal  Disabpled: C0
          delay(10);

          write_byte(CONFIG3, 0xE0);   // INT Reference Enabled: E0    else  INT Reference Disabled: 60

          delay(1000);
          //this part is just to check if you send and read correct data
          Serial.println("Check Configs");
          chSet = read_byte(CONFIG1);
          Serial.println("CONFIG1: Received " + hex_to_char(chSet) );
          chSet = read_byte(CONFIG2);
          Serial.println("CONFIG2: Received "  + hex_to_char(chSet) );
          chSet = read_byte(CONFIG3);
          Serial.println("CONFIG3: Received "  + hex_to_char(chSet) );

          //remember that ch1 is used for respiration! use channel 2 for ECG measurements

           // Ch1 Setting: Bits 7 6 5 4 3 2 1 0 ---  PDn(channel power mode) GAINn[2:0] (PGA gain-- 101:  12 110 : 24)
           //SRB2 (SRB2 connection) MUXn[2:0] (channel input selection: 000 : Normal electrode input , 101 : Test signal )

           /// Input Channel Shorted  ---> 0b00000001 0X01;   Test signal Activated ---> 0b00000101 0X05;
          delay(1000);

          write_byte(CH1SET, 0x05); //
          write_byte(CH2SET, 0x05); //
          write_byte(CH3SET, 0x05); //
          write_byte(CH4SET, 0x05); //
          write_byte(CH5SET, 0x05); //
          write_byte(CH6SET, 0x05); //
          write_byte(CH7SET, 0x05); //
          write_byte(CH8SET, 0x05); //

          Serial.println("Check Channel Settings");
          chSet = read_byte(CH1SET);
          Serial.println("Ch1: Received " + hex_to_char(chSet) );
          chSet = read_byte(CH2SET);
          Serial.println("Ch2: Received  " +   hex_to_char(chSet) );
          chSet = read_byte(CH7SET);
          Serial.println("Ch7: Received  " +   hex_to_char(chSet) );
          chSet = read_byte(CH8SET);
          Serial.println("Ch8: Received  " +   hex_to_char(chSet) );

          // Start communication, you can use RDATAC or RDATA according to datasheet
          send_command(RDATAC);
          digitalWrite(PIN_START, LOW);
          delay(150);
          send_command(START);
        //  digitalWrite(PIN_CS, LOW); //Low to communicated
        //  SPI.transfer(START);
        //  digitalWrite(PIN_CS, HIGH); //Low to communicated

        }

        boolean gActiveChan [2];
        int nChannels = 1;
        int gMaxChan=1;

        void loop(){

        // Based on the Page. 36 For the 8-channel ADS1299, the number of data outputs is
        //[(24 status bits + 24 bits × 8 channels) = 216 bits].

          delayMicroseconds(10);

             if(digitalRead(IPIN_DRDY) == LOW){
              t0 = micros();

                digitalWrite(PIN_CS, LOW);

                long output[9];
                long dataPacket;
                for(int i = 0; i<9; i++){
                    for(int j = 0; j<3; j++){
                        byte dataByte = SPI.transfer(0x00);
                        dataPacket = (dataPacket<<8) | dataByte;
                    }

                    output[i] = dataPacket;
                    dataPacket = 0;
                }

                digitalWrite(PIN_CS, HIGH);
                Serial.println(output[1]);

        // t = micros()-t0;  // calculate elapsed time
       // Serial.print(1000000/float(t));
        //Serial.println(" samples per second");
        //delay(200);

         }

                }

            String hex_to_char(int hex_in) {
          int precision = 2;
          char tmp[16];
          char format[128];
          sprintf(format, "0x%%.%dX", precision);
          sprintf(tmp, format, hex_in);
          //Serial.print(tmp);
          return(String(tmp));
        }

        // see datasheet 38
        int read_byte(int reg_addr){
          int out = 0;
          digitalWrite(PIN_CS, LOW);
          SPI.transfer(0x20 | reg_addr);
          delayMicroseconds(5);
          SPI.transfer(0x00);
          delayMicroseconds(5);
          out = SPI.transfer(0x00);
          delayMicroseconds(1);
          digitalWrite(PIN_CS, HIGH);

          return(out);
        }

        void send_command(uint8_t cmd) {
          digitalWrite(PIN_CS, LOW);
          delayMicroseconds(5);
          SPI.transfer(cmd);
          delayMicroseconds(10);
          digitalWrite(PIN_CS, HIGH);
        }

        //see page 38
        void write_byte(int reg_addr, int val_hex) {
          digitalWrite(PIN_CS, LOW);
          delayMicroseconds(5);
          SPI.transfer(0x40 | reg_addr);
          delayMicroseconds(5);
          SPI.transfer(0x00);
          delayMicroseconds(5);
          SPI.transfer(val_hex);
          delayMicroseconds(10);
          digitalWrite(PIN_CS, HIGH);

        }

body:
Try changing the order of these:

      SPI.setDataMode(SPI_MODE1);
      //SPI.setClockDivider(SPI_CLOCK_DIV16);
      SPI.setBitOrder(MSBFIRST);
      SPI.begin();

I think SPI.begin() needs to be started before the other two calls.

Instead of digitalWrite to control the chip select, use Direct Port Manipulation, much faster.

Does the ADC support 8 MHz SPI clock? From 7.6 & 7.7 of the datasheet, I would say yes.
You can get rid of all the delayMicroseconds(5), (1), (10), as well, they are not doing anything for you.

"Unpack" this and just do 3 SPI.transfers in a row to read the data, doing it in a loop slows it down:

            for(int i = 0; i<9; i++){
                for(int j = 0; j<3; j++){
                    byte dataByte = SPI.transfer(0x00);
                    dataPacket = (dataPacket<<8) | dataByte;
                }

I would go so far as to do all 27 in a row even, then do the array manipulation/data combining when all 27 bytes are captured.


message:
Powering two stepper motors with A4988 drivers

New to this site and wanted advice and sanity checking on my project design. I know there are similar questions to this but I couldn’t find one that was closely similar to mine.

I’m creating a device the uses two NEMA 17 stepper motors (https://www.omc-stepperonline.com/nema-17-stepper-motor-bipolar-l48mm-w-gear-raio-1001-planetary-gearbox-17hs19-1684s-pg100.html) with chunky 100:1 gearboxes in addition to using 1/16 microstepping. The end result of this is to achieve a stepper motor that turns very slowly (minutes per revolution).

Each motor is rated at 2.8V and 1.68A per phase (3.36A total since two phase) and I’m using an A4988 driver for each of them (https://www.amazon.co.uk/gp/product/B07FKXXJ41/ref=ppx_yo_dt_b_asin_title_o00_s00?ie=UTF8&psc=1) (note that these are Chinese versions where RCS = 0.1Ω). Since the A4988 drivers are limited to 1A without additional cooling, I’ve used the onboard potentiometer to reduce Vref to just below 0.9V to prevent overheating (using the equation Vref = 8 x Imax x RCS from Pololu).

This should mean that consequentially the torque output from each motor is reduced by a factor of 1/(3.36) = 0.3 (as torque α current) since each motor is only being supplied with 1A (which is not an issue due to the large gearing ratio giving a suitable output torque). I think 1/16th microstepping might also reduce the torque slightly, but I couldn’t find any conclusive sources that didn’t contradict each other on this.

This gives a power requirement of 2.8 x 1 = 2.8W per motor, hence 5.6W in total. So, I plan to use a power source that provides at least 3A (surplus on the 2A required by the drivers) and rated at a voltage of 12V-24V to run the stepper motors. I’m also aware that I need to make sure I power the drivers in parallel from this source, and not in series to reduce strain / overheating.

I’ve included two power sources I was thinking of using:

1: 24V, 4A, 96W Desktop Switching Power Supply (https://www.amazon.co.uk/DTK-Charger-90-240V-Switching-Transformers/dp/B07K85GJ54/ref=sr_1_1_sspa?crid=362Z7XFFLAYLL&keywords=24v+3a+dc+power+supply&qid=1565084176&s=electronics&sprefix=24V+3A+dC,electronics,124&sr=1-1-spons&psc=1&spLa=ZW5jcnlwdGVkUXVhbGlmaWVyPUFHM1hUTjRTOUhYVDcmZW5jcnlwdGVkSWQ9QTA5NzA5MzQzM09IT05IR1JITEpQJmVuY3J5cHRlZEFkSWQ9QTA0NjgyMTUyQjY0UEYzRFI5OVBFJndpZGdldE5hbWU9c3BfYXRmJmFjdGlvbj1jbGlja1JlZGlyZWN0JmRvTm90TG9nQ2xpY2s9dHJ1ZQ==)

2: 24V, 15A, 360W PSU Transformer Adaptor (https://www.amazon.co.uk/NEWSTYLE-Universal-Regulated-Switching-Transformer/dp/B0758BNMLH/ref=sr_1_3?keywords=PSU+24V&qid=1565084433&s=electronics&sr=1-3)

Overall question is: would either of these power supplies be suitable, I think the second might be a bit overkill but i'm not sure.

Here’s the circuit diagram for reference:
[![enter image description here][1]][1]

Apologies for the long post, just needed to get all the information out of my head. I’m curious to see if I’ve made any errors in my calculations / assumptions, so any help is greatly appreciated.

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

body:
Both power supplies are suitable.

The actual 12V/24V current required is not comparable to what the driver current is set at, since the stepper motor coils do not have those 12V/24V across them.

My first 3D printer came with a 12V 5A power supply, which proved suitable for simultaneous use of four stepper drivers, the control board, a display, and the heater cartridge (40W).


message:
Using Arduino as contact to the world for linux box if app crashes

I am new to this micro controller thingie world so bare with me :)

**Let me describe a scenario first.**
Say I have a linux box for house automation embedded in a wall.
For security reasons is **the only active access** to the box the display mounted to the wall.

**Another access would be via network and ssh but ssh is disabled.**
Unfortunately does the web app sometimes crash and nothing goes. In the wake of that do I have to disassemble quite some stuff to get to the box and to revive it.

**My Idea:**
I can use a nfc or rfid sensor and hook it up to Arduino.
**Would it be possible to make Arduino log on to the linux box and fire up and shutdown ssh?**

I don't want to use Arduino Yun.
Is it achievable with an Arduino nano/Mega?

If not, which system would be your first choice to accomplish this task?

Thanks for your patience :)

body:
I will put our comments together in an answer.

You are overthinking the security issue. In my opinion, using RFID to reset the system is a bigger security thread, than using ssh the correct way. Normal RFID chips are susceptible to spoofing (copying an existing chip). Also the intruder could remove the RFID module to directly access the communication lines (depending on how much you will have accessible of the extra hardware). Also you can of course use the Serial interface of an Arduino to execute shell commands on your machine. You need a program on the machine to read the input and execute the commands (Majenko mentioned `agetty` for this). But is that really the best way? Using an Arduino here is a very hardware-ry way of solving a software issue. It is overly complex to do things this way and there are better options.

Instead you should really just use ssh with key-based authentication (disable password authentication). You can limit the ssh daemon to the local network (though, if you don't have configured corresponding port forwarding in your router, it isn't reachable from the internet either way), or - if you really want the additional security - to one specific device in your network. With a normal ssh key (I think 2048 bit is the standard), brute forcing is not a viable option for intruders. If you keep your private key save, there is very very little chance, that an intruder can get past that. You can also save the private key only on an USB stick, which you only use for resetting the machine. Also you can limit the commands, that the ssh user can execute, to only the resetting (like only allowing rebooting).

Depending on your actual security needs, you can choose, how far you want to go. I personally would just use key-based ssh limited to the local network. That should be plenty enough security and would also give you the possibility to access the machine, that is running in your home easier.

---

Or, if you really don't want to open ssh for the machine, you can write a simple watchdog program, that can run on the machine. Since the webapp is failing, you can write a simple python program (or any other language you like), which is regularly loading the webapp (how exactly depends largely on the webapp and the exact type of failure - may be a simple HTTP GET request) to check, if it is still alive. If the liveliness test fails for a defined number of times (let's say 3), it will reboot the machine.

This method does not require any access to the machine, but you will have to develop the liveliness test. Writing the program is then really simple.

---

All that said, it is not a good sign, that the app fails that often. You didn't write, what app that is, and what exactly fails. Maybe you are able to fix that issue directly. Or the developer of the app can, so maybe raise an issue on his platform (where the project is hosted).


message:
Arduino HTTP Request Fails Slow Cellular Connection

### Setup:

* Arduino Mega 2560 w/ Wiznet W5500 Ethernet Sheild

* Using TP-Link TL-MR6400 LTE router to connect to internet over cellular connection in Uganda.

---
Using an HTTP Post with the following,
<!-- language-all: lang-cpp -->
```
client.println("POST /hook HTTP/1.1");
client.print("Host: "); client.println(server);
client.println("Accept: */*");
client.print("Content-Type: text/html;");
client.println("User-Agent: Arduino/1.0");
client.println("Connection: close");
client.print("Content-Length: ");
client.println(PostData.length());
client.println();
client.println(PostData);
```

where PostData is a `String` and Ethernet2 is the library used.

This works just fine from the US to the same AWS server, or a [https://requestbin.com/][1] instance.

---

When testing from Uganda using a Raspberry Pi and curl it works fine.

```
$ curl -vs -d 'ABCDEFG' -H "User-Agent: Arduino/1.0"  -H "Content-Type: text/html" -H "Connection: close"   http://<server here>/hook
*   Trying <ip here>...
* TCP_NODELAY set
* Connected to <server here> (<ip here>) port 80 (#0)
> POST /tg HTTP/1.1
> Host: <server here>
> Accept: */*
> User-Agent: Arduino/1.0
> Content-Type: text/html
> Connection: close
> Content-Length: 7
>
* upload completely sent off: 7 out of 7 bytes
< HTTP/1.1 200 OK
< Access-Control-Allow-Origin: *
< Content-Type: application/json; charset=utf-8
< Date: Tue, 06 Aug 2019 21:06:49 GMT
< x-pd-status: sent to primary
< X-Powered-By: Express
< Content-Length: 16
< Connection: Close
<
* Curl_http_done: called premature == 0
* Closing connection 0
{"success":true}
```

---

I even tried an HTTP GET example from the Ethernet2 library,

[https://www.arduino.cc/en/Tutorial/WebClientRepeating][2]

It worked just fine in the US but in Uganda I get,

```
My IP address: 192.168.1.177

connecting...

connecting...

connecting...

```

I increased the time between requests here to 100 seconds where it is listening for the whole time inbetween.

It seems that `client.connect(server, 80)` is successful and the `client.print` messages go through but the message never reaches the server so there is no response. My AWS server does not recieve the request and this is the same for the requestbin instance. This behavior is mirrored in all my Arduino tests.

I thought the ISP might be blocking but the RPi can send nearly the same message. I thought maybe a timeout somewhere but I can not find where with my tests. I thought my message was too long but I reduced the size to only 10 characters with the same results.

---

Trying to figure out why the Arduino HTTP request cannot reach any webhooks from Uganda and how to fix it if possible. Different ISP, slower connection, cellular connection?

Any help would be appreciated.

  [1]: https://requestbin.com/
  [2]: https://www.arduino.cc/en/Tutorial/WebClientRepeating

body:
**Buffering and flush()**

Many arduino libraries suffer of slow communication because the authors didn't use buffering. To not to send every small piece of data over a connection with overhead of protocol bytes use buffering. Data are collected until the buffer is full and then the collected data are send and the buffer is ready for next bytes. The flush() functions sends the buffer even if it is not full, but you do not have more data. (The flush() 'dilemma' was resolved and in Arduino core classes the flush() method is declared in Print class which is the Arduino standard interface for output streams.)

My StreamLib library offers a BufferedPrint class which wraps the target stream and buffers the data to be send over the target stream. Of course, do not forget to use flush() after last data printed.

----------

**HTTP data length**

It is common practice in Arduino sketches to not to send the Content-length header with POST requests. In most cases it is because when the HTTP headers are send, the size of data is not known. The WebServer then doesn't know if it received all the data and waits until the connection is closed or timeout is reached. It leads to long time until a Web Server sends the response to requesting Arduino sketch.

If the data can be prepared to a string in memory, fill the Content-length HTTP header.

If the data to be send as response or in POST request wouldn't fit into available memory, ChunkedPrint from my StreamLib can be used with HTTP chunked Transfer-Encoding. And ChunkedPrint is an extension of BufferedPrint so the Web Server handles your request without hesitating.


message:
Udp.endPacket fails

I am trying to send measurements over UDP, but the function Udp.endPacket continuously fails.

I use an Arduino Uno WiFi rev 2, WiFiNINA library version 1.4.0 and WiFiNINA firmware version 1.2.1 which seems to be the latest available.

WiFi connection setup works, obtaining a correct IP address in the 192.168.3.0/24 network.

This is a snippet of my code:
<!-- language-all: lang-cpp -->
```
const char* udpDestIP = "192.168.3.126";
const int udpDestPort = 1844;
WiFiUDP Udp;

void loop() {
  // establish variables for distance result:
  long cm;

  // execute measurement
  cm = measureDistance();

  // check for false measurements and repeat if necessary
  if(minDist < cm && cm < maxDist) {
    Serial.print(cm);
    Serial.print(" cm");
    Serial.println();

    // Check WiFi connection and reconnect if necessary
    if (WiFi.status() != WL_CONNECTED) {
      connectToWifi();
    }

    // Send over UDP
    //if(!Udp.beginPacket("192.168.3.255", udpDestPort)) {
    if(!Udp.beginPacket(udpDestIP, udpDestPort)) {
      Serial.println("beginPacket fail");
    }
    String msg = "water_distance:";
    msg += cm;
    byte size = Udp.write(msg.c_str(), msg.length());
    if(DEBUG){
      Serial.print("Sending this message over UDP: ");
      Serial.println(msg);
      Serial.print("udp write: ");
      Serial.println(size);
    }
    if(!Udp.endPacket()) Serial.println("endPacket fail");

    delay(delayTime);
  }
}

```

Terminal output is as follows:
```
151 cm
Sending this message over UDP: water_distance:151
udp write: 18
endPacket fail
151 cm
Sending this message over UDP: water_distance:151
udp write: 18
endPacket fail
33 cm
Sending this message over UDP: water_distance:33
udp write: 17
endPacket fail
34 cm
Sending this message over UDP: water_distance:34
udp write: 17
endPacket fail
153 cm
Sending this message over UDP: water_distance:153
udp write: 18
endPacket fail

```

Which makes me conclude the beginPacket, and udp.write functions are executed correctly, but I see no reason why the endPacket function keeps failing. Does anyone have an idea? Thanks a lot.

body:
The Arduino Ethernet and WiFi library implementations require to specify the outgoing port with UDP.begin(port) before calling UDP.beginPacket().

But UDP.begin(port) starts listening for UDP messages on this port too, so it is not a clean API. Call UDP.end() to stop listening for incoming messages.


message:
I am working on a thermometer and humidity why am i getting this error

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

In file included from C:\Users\Admin\Documents\Arduino\libraries\DHT-sensor-library-master\DHT_U.cpp:15:0:

C:\Users\Admin\Documents\Arduino\libraries\DHT-sensor-library-master\DHT_U.h:36:29: fatal error: Adafruit_Sensor.h: No such file or directory

compilation terminated.

exit status 1
Error compiling for board Arduino/Genuino Uno.

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

body:
This indicates your IDE is missing the "Adafruit Unified Sensor" library as outlined [here][1].

To install it, select "Tools" -> "Manage Libraries" and search for "Adafruit Unified Sensor". You can install the library by selecting it and pressing "Install".

  [1]: https://forum.arduino.cc/index.php?topic=471001.0


message:
Arduino detect order of objects

I'm trying to find a way to detect blocks being placed on grid on a table. The table will have fixed places where you can place the blocks, but the user is allowed to place the blocks in any free slot. I would like to have an Arduino poll the slots on the table and tell me which blocks are placed where.

I'm going to design the blocks with magnetic connections on the top and bottom to create a circuit as soon as they are placed.

What kind of chips can I use so that the arduino can give me the topology of the blocks when placed?

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

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

body:
You need to track unique objects in an 8x8 grid of slots? How many unique objects?

If the total number of objects is 112 or less, you could give each one a unique I2C address.

You'd add 4 circular electrical contacts in a "bulls-eye" configuration on the top and bottom of each object so that all the I2C pins would connect regardless of orientation. All objects in the same stack would be connected together on that stack's I2C bus.

You'd have an 8x8 multiplexer to connect to the I2C bus for each of your 64 grid positions in turn, and poll that bus for each of the possible I2C addresses. (Send a ping for each address and look for `ACK`s.)

---
Alternately, you could give every object a unique weight, varied by a power-of-two amount. (first object weighs 1000 grams. Second weighs 1001 grams (1000+2^0)) third object weighs 1002 grams (1000+2^1). Fourth object weighs 1004 grams (1000+2^2). Etc.)

Then you'd put a scale on each pad. Weigh the objects, modulo 1000 grams. That result, in binary, would give you flags for every object on that pad.

---

Or 2 circular electrical contacts on the top and bottom of each object, with resistors that have unique power-of-two resistance on each one, as Juraj suggests in their comment. Measure the resistance and you can figure out which set of objects is present.

The math would be simpler if you rigged the objects so that they made a series circuit through all objects present (put a normally closed switch on the top that shorts the top contacts of that object through its resistor if there's no object on top of it. If there is an object, the switch would open, and the objects on top would close the circuit.)


message:
Arduino Mega TIMER1 one second interval

Is this timer set correctly for Arduino Mega? It should count exactly one second. And why when I print in serial monitor (seconds_passed++) is it incremented by 2 not by 1?

Full code on Pastebin: [LINK][1]

    noInterrupts();
    //set and initialize the TIMER1

    TCCR1A = 0; // set entire TCCR1A register to 0
    TCCR1B = 0; // set entire TCCR1B register to 0
    TCCR1B |= (1 << CS12);
    TIMSK1 |= (1 << TOIE1);
    TCNT1 = 3036;

    attachInterrupt(digitalPinToInterrupt(ignition_pin), ignitionSignal, CHANGE);
    interrupts();

    ISR(TIMER1_OVF_vect) {
      //TIMER1 overflow interrupt -- occurs every 1sec --
      instantSpeed();
      LPG_Consumption();
      LPG_injector_open_duration = 0;
      unleadedConsumption();
      unleadinj_Open_Duration = 0;
      seconds_passed++;
      vss_pulses = 0;
      TCNT1 = 3036;
    }

  [1]: https://pastebin.com/Efkx07WR

body:
Your timer configuration is ok so far. Never the less I recommend using the `TIMER1_COMPA_vect` interrupt vector instead of `TIMER1_OVF_vect` which has the advantage of better readability (in my oppinion) and `TCNT1` doesn't have to be reset in the ISR (instead, OCR1A is just initialized with 62500 once in `setup()`). Therefore, TIMER0 has to run in CTC (clear timer on compare match) mode and `WGM12` has to be set in TCCR1B.

The reason why `seconds_passed` is incremented twice is because you `Serial.print(seconds_passed++)` in `instantSpeed()`. Printing on the serial interface is damn slow and using it in an ISR is a no-go!


message:
How do I upload an Arduino STM32 binary from the Mac command line?

I've compiled an Arduino program via a Makefile and have the resulting hex file.

From the Mac command line, how do I upload this hex file to my [STM32 Cortex M3][1] board?  For an ATMEL processor I would use avrdude.

  [1]: https://www.st.com/en/microcontrollers-microprocessors/stm32-32-bit-arm-cortex-mcus.html

body:
There are several different tools for uploading binaries to a Cortex M3.  Depending on the board (not chip) configuration, they include (ht: Majenko):

- dfu-util through an FT232 adapter
- stm32flash through serial
- micronucleus through the Micronucleus bootloader
- stlink through an STLink programmer

Many Arduino flavors use a board with some kind of USB or FT232 adapter.  In this case:

the STM32 line of processors include a [DFU][2] ([device firmware update][3]) bootloader in ROM.

The [dfu-util][4] project supports a Mac version of dfu-util, their command line DFU tool.

Note that this answer is identical for any binaries which run on the processor, be they Arduino sketches or programs developed with other frameworks.

  [2]: https://www.st.com/content/ccc/resource/technical/document/application_note/6a/17/92/02/58/98/45/0c/CD00264379.pdf/files/CD00264379.pdf/jcr:content/translations/en.CD00264379.pdf
  [3]: https://www.digikey.com/en/articles/techzone/2018/jan/update-firmware-field-using-microcontroller-dfu-mode
  [4]: http://dfu-util.sourceforge.net/


message:
Programming ESP32 MCUs for production

Before committing to learning about the ESP32 and how to program it, I would like to know if the ESP can be programme the same way for production as it can on évaluation boards (with the Arduino IDE).

Since it obviusly much easier than most for microcontrollers, I was wondering if a product is eventually mass produced, if the code used to program the evaluation board (such as this one https://makeradvisor.com/tools/esp32-dev-board-wi-fi-bluetooth/) could be used on the final product.

body:
Yes. Most manufacturers would just require a binary (or HEX depending on MCU) file of your compiled code. If it's not a system they already know how to handle you will also need to provide a procedure for them to follow to program the device. What form that takes depends on the manufacturer.

You can also generally order pre-programmed MCUs and modules direct from the manufacturer where they (for a small fee) will program the chips for you before they are then sent to the board manufacturer for population.

If there is no facility on the MCU manufacturer's website then just email their sales department and I am sure they would be happy to quote you. Again, all they will require is a HEX or BIN file (depending on manufacturer) for programming.


message:
I2C master/slave maximum requestEvent message size

Using a `NodeMCU` master and an `Arduino` slave (`Wire.h` on both sides), is there a maximum message size (32 bytes?) for the answer that the slave sends from `requestEvent()`?

If so, is there any solution to circumvent such a restriction WITHOUT the use of other libraries (like `I2C_Anything`, for example)?

body:
The I2C protocol itself does not have a transmission size restriction. But the implementation in the Wire library only reserves a specific amount of RAM for the buffers. [This site](https://playground.arduino.cc/Main/WireLibraryDetailedReference/) mentiones 32 bytes for normal Arduinos (couldn't find the source code currently) and I found 128 bytes for the ESP8266 in the [source code](https://github.com/esp8266/Arduino/blob/master/libraries/Wire/Wire.h).

You cannot have unlimited message length, since the buffer has to hold the whole message and the RAM on normal Arduinos is very limited.

But you can make the buffers of the libraries bigger by changing the corresponding defines in the header files to a bigger value. Keep in mind, that the actual used memory space is with a factor 2, since the buffer size gets used for both send and receive buffer.

---

If you need bigger messages, than is fitting in the available RAM, you should either change to a board with more RAM, or develop a way to process one part of a message, deleting it and then process the next part (multi part message). Though that raises the question, why the messages have to be that big in the first place.


message:
Powering Motor shield and Arduino Mega Separately

I'm trying to build a fire fighting robot, that uses 2 BO DC motors, 2 Servos - MG996R and SG90. For them I'm using Motor Shield v1 of Adafruit's make that uses 2 L293D IC's and a 74HC595 shift registers.

Now, I'm placing the motor shield over Arduino Mega and trying to connect other components such as Flame Sensor, Ultrasonic Sensor and submersible DC Water Pump.
As soon as I try to power up ultrasonic sensor, the power indicating LED's on both the shield and Mega goes off.

I've been testing this with simple USB connected power supply and to my understanding the power being supplied is insufficient.
Since **it would be a moving cart, I would like to know whether there is any way to power up Shield and Mega separately by a 9v Battery?**

body:
On the side of the DC Motor Shield v1, there is an external power - +  2 pin terminal.

This can be used to supplement the shield with power.

Adafruit: "The motor controllers on this shield are designed to run from 4.5V to 25V.
MOST 1.5-3V MOTORS WILL NOT WORK"

If you are lucky to have the motor specs and ratings on hand, you will be able to account for how much power your motor(s) will need in your application.

Adafruit: "The motor driver chips that come with the kit are designed to provide up to 600 mA per motor, with 1.2A peak current. Note that once you head towards 1A you'll probably want to put a heatsink on the motor driver, otherwise you will get thermal failure, possibly burning out the chip."

Here is an important tid-bit for your scenario... (So no 9v Batteries for the motors!):

Adafruit: "You can't run motors off of a 9V battery so don't even waste your time/batteries! Use a big Lead Acid or NiMH battery pack. Its also very much suggested that you set up two power supplies (split supply) one for the Arduino and one for the motors. 99% of 'weird motor problems' are due to noise on the power line from sharing power supplies and/or not having a powerful enough supply!"

...

So makes sense,  get the Arduino powered, by itself, then get another power source for your motor shield.

Your sensors might be able to hop on the Arduino power supply if it's providing enough power.  I'd keep them separate from the motor power line, due to noise interference as suggested.

Try this, and see if the Arduino stays powered.

There is a lot of helpful info here, some new things I've learned just now.
https://learn.adafruit.com/adafruit-motor-shield/power-requirements


message:
ESP8266 (Huzzah Feather) I2C scanner finds nothing

I am trying to address an I2C device on my Huzzah Feather (Adafruit) ESP8266, but the I2C scanner tool does not detect anything.  All is sufficiently powered and quadruple checked the wiring.

Is there something I am missing for this board in regards to I2C connections?

I've had no issue on an Arduino, which uses the 2 pins on the Analog rail for I2C...

The Huzzah has no Analogue But the one pin, regardless, Huzzah Feather has different (still pin 4 & 5 tho) I2C,  and not via A0 A1 like on the Uno.

Do I need to dig deep and change some pin configurations for the Huzzah?

Thought I would ask before wasting more time on trial and error experiments.

**Update Note:**

I failed to mention there is a Feather Neopixel board (4x32) hard soldered to the board. Which I suspect is not the culprit as this issue also persists on same board without the neopixel shield attached.

**Update**

The soldering job was good, but discovered a faulty wire.  This allowed the I2C scanner to detect the i2C controller (LCD2004) at the address of 0x3F...

I checked with a I2c LCD library example, and I don't get any characters to come up... This is the same with both Huzzah Feather boards, one with Neopixel shield and the other is bare.

body:
This particular issue was due to a faulty wire on the I2C bus. I replaced the wire and I was able to scan and get an address to the I2C LCD controller.

I still cannot get text to the LCD.  I will start a new question for that.

EDIT:

Upon scrapping my I2C_LCD_DISPLAY library, I downloaded one that was linked in a ESP32/8266 tutorial for the LCD, and finally got it working.


message:
Difficulties programming Arduino uno for 24 hour cycle

I am trying to program my Arduino Uno board for a 24 hour cycle.
I have the Arduino board and two relays.
The aim is; every 24 hours relay 1 has to switch on for 5 seconds, and 1 second later relay 2 has to switch on for 15 seconds.
I have a sketch for a 12 hour cycle, and that works fine, but when I try for a 24 hour cycle, by changing the const unsigned int totalTime from 43200 seconds to 86400 seconds, everything goes wrong.

24 hour sketch - what is wrong?

    //turn relays on and off at certain times.
    //when the digital output pin is HIGH, then the relay is off.
    //when the digital output pin is LOW, then the relay is on.

    enum actioEnum {
      RELAY1_ON,
      RELAY1_OFF,
      RELAY2_ON,
      RELAY2_OFF,
    };

    struct tableStruct{
      unsigned int time;
      actionEnum action;
    }
    const table [] = {
      {0,RELAY1_ON},
      {5,RELAY1_OFF},
      // remaining 86395 for a total of 86400.
      {0,RELAY2_OFF}, // not needed, it is already off.
      {6,RELAY2_ON},
      {6+15,RELAY2_OFF},
      // remaining 86379 for a total of 86400.
    };

    const unsigned int totalTime = 86400; // total amount for sequence
    unsigned int seconds;

    unsigned long previousMillis;
    const unsigned long interval = 1000; // 1000 ms; // 1000 ms is one second

    const int relay1Pin = 2;
    const int relay2Pin = 3;

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

      // the relay is off when the pin is high.
      // turn output high before setting the pinMode.
      // then the output changes from a floating pin to high,
      // and the relays will not be activated.
      digitalWrite (relay1Pin, HIGH);
      pinMode (relay1Pin, OUTPUT);
      digitalWrite (relay2Pin, HIGH);
      pinMode (relay2Pin, OUTPUT);
    }

    void loop () {
      // a one second timer with millis
      if (millis() - previousMillis >= interval) {
        previousMillis += interval;
        // scan table
        for ( int i = 0; i < int (sizeof(table) / sizeof (tableStruct)); i++) {
          if (table [i] . time == seconds) {
            switch (table [i] . action) {
              case RELAY1_ON:
                Serial.println("Relay 1 on");
                digitalWrite (relay1Pin, LOW); // low is relay on.
                break;
              case RELAY1_OFF:
                Serial.println("Relay 1 off");
                digitalWrite (relay1Pin, HIGH); // high is relay off.
                break;
              case RELAY2_ON:
                Serial.println("Relay 2 on");
                digitalWrite (relay2Pin, LOW); // low is relay on.
                break;
              case RELAY2_OFF:
                Serial.println ("Relay 2 off");
                digitalWrite (relay2Pin, HIGH); // high is relay off.
                break;
              default:
                Serial.println ("Error, a bug in the scketch");
            }
          }
        }
        seconds++;
        if (seconds >= totalTime) {
          seconds = 0;
        }
      }
    }

body:
On the Uno `unsigned int` is a 16 bit number. That means, that it can hold values between (and including) 0 and 65535. If you try to write a bigger value to this variable, it will cut of the higher bits, so that the rest fits into 16 bits. That gives you a totally different value, which is significantly small than 24h.

The solution is to use a bigger variable type for `totalTime`.
 You can use `unsigned long`, which has 32 bits and can hold way bigger values ( 0 to 4,294,967,295 (2^32 - 1)). That should be plenty enough for all your cases.


message:
esp8266- how to use GPIO0 as an input?

First, my setup:
I have an Arduino Uno with an Adafruit Audio Shield.  I have a Wemos D1 Mini controlling the project.

I need for the D1 to know when a file is playing.

I have a GPIO pin on the Uno programmed to be high when a file is playing.  Low otherwise.  I have two GPIO pins on the Wemos that are unused, D3 and D4 (GPIO0 and GPIO2).  (I use a divider circuit of a 10K over a 20K resistor to bring the 5V from the Uno down to 3v3 for the Wemos). D4 is already a problem because it has to be high to boot and the GPIO from the Uno is normally low. D3 (GPIO0) has to be high to boot and has an internal pullup.

Here's my problem.  How do I turn off the pullup on GPIO0? Even when the Uno GPIO is low (0V), the GPIO0 measures 2.4V, which my sketch sees as a logical 1.

Any tips would be appreciated.  (I thought of reversing the polarity on the Uno so that low=true, but even when the Uno is driving the pin low, the Wemos GPIO0 pin is still at 2.4V, so low-true logic won't work either.).

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

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

body:
Don't use the voltage divider and never set the Uno pin HIGH.

Pull io 0 of esp8266 LOW with pinMode of the Uno pin.

    pinMode(TO_ESP_IO0, OUTPUT); // sets the pin LOW

    pinMode(TO_ESP_IO0, INPUT); // let it to the io0 pull-up resistor


message:
how to use keypad button multiple integer value input

I have been working on water flow sensor which measures volume then i need to restrict the amount of water which disperse from depend on the user input form the keypad so how can i store the input form the keypad into a variable.

body:
When you use the keypad library, there is a command to read a key:

     myKeypad.getKey();

Store these keys in a (string) buffer, and after a certain key is pressed (e.g. #), parse the string buffer to retrieve the integer (with the c function `atoi`, see [here for a description][1]).

  [1]: https://fresh2refresh.com/c-programming/c-type-casting/c-atoi-function/


message:
please tell me how do I fix this code down here(please tell in my easy English)

LiquidCrystal 1cd(12, 11, 5, 4, 3, 2);

     void setup() {
       1cd.begin(16, 2);
       1cd.print"abbu, kya, chalrelaye!");
     }

     void loop() {

     }

body:
Variable names MUST NOT start with a digit. Only '_' and a-z are allowed!

`1cd` really should be `lcd` with an 'ell' instead of a one (1).


body:
I suggest you modify the LiquidCrystal "Hello World" sketch:

[![drop down menu used to open the sketch][1]][1]

Here is the example code:

    // include the library code:
    #include <LiquidCrystal.h>

    // initialize the library by associating any needed LCD interface pin
    // with the arduino pin number it is connected to
    const int rs = 12, en = 11, d4 = 5, d5 = 4, d6 = 3, d7 = 2;
    LiquidCrystal lcd(rs, en, d4, d5, d6, d7);

    void setup() {
      // set up the LCD's number of columns and rows:
      lcd.begin(16, 2);
      // Print a message to the LCD.
      lcd.print("hello, world!");
    }

    void loop() {
      // set the cursor to column 0, line 1
      // (note: line 1 is the second row, since counting begins with 0):
      lcd.setCursor(0, 1);
      // print the number of seconds since reset:
      lcd.print(millis() / 1000);
    }

Good luck!

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


message:
Programming the ATMega328P without Arduino board always returns the error: avrdude: stk500_recv(): programmer is not responding

I have a microcontroller: `ATMega328P`.
I don't have any `Arduino Uno board`.

I want to program the `ATMega328P` using my `FTDI programmer`.

But when I try to program the `ATMega328P` without `Arduino` board I always get this **error**:

`avrdude: stk500_recv(): programmer is not responding`

I've followed this [YouTube Tutorial][1] to build this.

And ended up with this diagram:

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

All the connections seems OK.

I choose the board: `"Arduino Pro or Pro Mini"` because only with this one I can choose the correct processor: `"ATMega328P (5V, 16MHz)"`

The port is correct: `"/dev/ttyUSB0"`

And as for the the programmer I've choose: `"USBasp"`, which I don't know if this is correct. I've used this `FTDI programmer` to program the `STM32 microcontroller` and the programmer was `"Serial"`, which I don't see the very same option here.

I'm lost, what am I missing up here?

BTW I've seen [this][3], [this][4] and [this][5] but couldn't get it fixed.

[![enter image description here][6]][6]

  [1]: https://www.youtube.com/watch?v=Sww1mek5rHU&t=31m39s
  [2]: https://i.stack.imgur.com/9TGcM.png
  [3]: https://arduino.stackexchange.com/questions/22191/avrdude-stk500-recv-programmer-is-not-responding
  [4]: https://arduino.stackexchange.com/questions/16732/program-an-atmega328p-and-use-it-without-arduino-board
  [5]: https://arduino.stackexchange.com/questions/29348/atmega328p-programming-with-arduino-libraries
  [6]: https://i.stack.imgur.com/Gssiz.png

body:
A new chip cannot be programmed in that manner until it has the Bootloader installed. The Bootloader starts after a reset and monitors the serial interface to see if something is attempting to download code via the serial port.

Selecting a Programmer has no effect on serial download, that only comes into play when Programming via the SPI pins SCK/MOSI/MISO/Reset/Power/Gnd.

Your "design" needs a couple more parts: 0.1uF caps between VCC and Gnd, and AVCC and Gnd.

The Cryslal and 22pF caps could also be a lot closer to the device - like right next to it.

I can't read the FTDI markings, so I can't tell if you have Rx and Tx swapped there.


message:
Serial connection two devices two power supplies

I'm trying to connect an ESP32-CAM to a 3d printer using a serial connection.
When powering the ESP from the 5V rail on the 3D printer(and using 3.3V zener diodes between tx, rx & gnd), everything works fine. The ESP expects 3.3V on the serial pins, hence the diodes.

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

[circuit diagram][2]

Common ground not shown.

Then when I try to run the ESP32 from its own 5v power supply, I cannot establish a serial connection, regardless of whether I connect the gnd from the 5v from the 3d printer with that of the ESP power supply.
In fact, the ESP doesn't function then.

Any suggestions?

PS: the ESP has its own power since it should trigger a relay to cut power to the printer.

  [1]: https://i.stack.imgur.com/DxYBK.jpg
  [2]: https://i.ibb.co/QFJXBQG/Ender3-relay-pptx-Microsoft-Power-Point-000291.jpg

body:
The 3.3V zener diodes are connected backwards. The anode should be connected to ground and the cathode (banded end) to the GPIO signal. Zener diodes work in reverse bias...as you have them connected now they are forward biased and will clamp the signals to about 0.7V.

The zener diode on the line for data transmitted at 3.3V to a 5V input doesn't do any good. You need to **increase** that signal voltage to a proper 5V logic level. The best thing to do would be to get rid of the zener diodes altogether and use a proper logic level converter.

Also, you really should have resistors between GPIO output pins and the zener diodes, to limit the current through the zeners when the GPIO pin is at 5V.


message:
Monitoring Power Down Using Arduino UNO and ZMPT101B

I am in the process of implementing power down alerting system suing Arduino UNO and ZMPT101B Single phase relay.

My code as follows,

    #include <Filters.h> //Easy library to do the calculations

    float testFrequency = 50;                     // test signal frequency (Hz)
    float windowLength = 40.0/testFrequency;     // how long to average the signal, for statistist

    int Sensor = 0; //Sensor analog input, here it's A0

    float intercept = -0.04; // to be adjusted based on calibration testing
    float slope = 0.0405; // to be adjusted based on calibration testing
    float current_Volts; // Voltage

    unsigned long printPeriod = 1000; //Refresh rate
    unsigned long previousMillis = 0;

    void setup() {
        Serial.begin( 9600 );    // start the serial port
    }

    void loop() {

        RunningStatistics inputStats;                //Easy life lines, actual calculation of the RMS requires a load of coding
        inputStats.setWindowSecs( windowLength );

        while( true ) {
            Sensor = analogRead(A0);  // read the analog in value:
            inputStats.input(Sensor);  // log to Stats function

            if((unsigned long)(millis() - previousMillis) >= printPeriod) {
                previousMillis = millis();   // update time every second

                Serial.print( "\n" );

                current_Volts = intercept + slope * inputStats.sigma(); //Calibartions for offset and amplitude
                current_Volts= current_Volts*(40.3231);                //Further calibrations for the amplitude

                Serial.print( "\tVoltage: " );
                Serial.print( current_Volts ); //Calculation and Value display is done the rest is if you're using an OLED display

                if (current_Volts <229) {
                    test_loop();
                }
            }
        }
    }

    void test_loop(){
        Serial.print( "Warning!! Server Room Power Down" );
        delay(1000);
    }

I am getting the correct voltage reading. When power down it says power down. But when power got up, it still shows power down with older reading. I think the reason for this because my code unable to stop the loop. And if I remove the delay (1000) in test_loop function it works, But my intention to use this sms alerting system and for that I need this delay to stop unnecessary alerts.

My code for SMS Alerting,

    Serial.print( "\tVoltage: " );
    Serial.print( current_Volts ); //Calculation and Value display is done the rest is if you're using an OLED display

    if (current_Volts <229) {
        SendMessage();
    }

    void test_loop() {
        mySerial.println("AT+CMGF=1");    //Sets the GSM Module in Text Mode
        delay(1000);  // Delay of 1000 milli seconds or 1 second
        mySerial.println("AT+CMGS=\"xxxxxxxxx\"\r"); // Replace x with mobile number
        delay(1000);
        mySerial.println("Warning!! Server Room Power Down");
        delay(100);
        mySerial.println((char)26);// ASCII code of CTRL+Z
        delay(150000);
        mySerial.println("AT+CMGD=2");
    }

This code works for the very first outage but after power up also it send power down. First part of serial priniting in test_loop code of Serial.print is used for debugging.

body:
Got a answer for the issue,

Attaching code for anyone interested.

```
/*
   Design by Vinod Amarathunga 26.08.2018
   FSSG R&D Team
*/

#include <OneWire.h>
#include <DallasTemperature.h>
#include <SoftwareSerial.h>
#define ONE_WIRE_BUS 2
SoftwareSerial mySerial(11, 10); //SIM800L Rx Tx
char msg;
String textMessage;

bool D7_alarmSent = false;
bool Temp_alarmSent = false;

OneWire oneWire(ONE_WIRE_BUS);

DallasTemperature sensors(&oneWire);

void setup()
{
  mySerial.begin(9600);   // Setting the baud rate of GSM Module
  Serial.begin(9600);    // Setting the baud rate of Serial Monitor (Arduino)
  delay(100);
}

void PowerSMS()
{
  Serial.println("Warning!! Server Room Power Down");
  mySerial.println("AT+CMGF=1");    //Sets the GSM Module in Text Mode
  delay(1000);  // Delay of 1000 milli seconds or 1 second
  mySerial.println("AT+CMGS=\"No1\"\r");
  delay(1000);
  mySerial.println("Warning!! Server Room Power Down");
  mySerial.println((char)26);// ASCII code of CTRL+Z
  delay(1000);
  mySerial.println("AT+CMGD=2");

  mySerial.println("AT+CMGF=1");    //Sets the GSM Module in Text Mode
  delay(1000);  // Delay of 1000 milli seconds or 1 second
  mySerial.println("AT+CMGS=\"No2\"\r");
  delay(1000);
  mySerial.println("Warning!! Server Room Power Down");
  mySerial.println((char)26);// ASCII code of CTRL+Z
  delay(1000);
  mySerial.println("AT+CMGD=2");

  mySerial.println("AT+CMGF=1");    //Sets the GSM Module in Text Mode
  delay(1000);  // Delay of 1000 milli seconds or 1 second
  mySerial.println("AT+CMGS=\"No3\"\r");
  delay(1000);
  mySerial.println("Warning!! Server Room Power Down");
  mySerial.println((char)26);// ASCII code of CTRL+Z
  delay(1000);
  mySerial.println("AT+CMGD=2");

}

void SendMessage()
{

  Serial.println("Warning!! Server Room Temperature is Critical");

  mySerial.println("AT+CMGF=1");    //Sets the GSM Module in Text Mode
  delay(1000);  // Delay of 1000 milli seconds or 1 second
  mySerial.println("AT+CMGS=\"No1\"\r"); // Replace x with mobile number
  delay(1000);
  mySerial.println("Warning!! Server Room Temperature is Critical");
  mySerial.println(String("Reading : ") + sensors.getTempCByIndex(0) + String("*C"));
  delay(100);
  mySerial.println((char)26);// ASCII code of CTRL+Z
  delay(1000);
  mySerial.println("AT+CMGD=2");

  mySerial.println("AT+CMGF=1");    //Sets the GSM Module in Text Mode
  delay(1000);  // Delay of 1000 milli seconds or 1 second
  mySerial.println("AT+CMGS=\"No2\"\r");
  delay(1000);
  mySerial.println("Warning!! Server Room Temperature is Critical");
  mySerial.println(String("Reading : ") + sensors.getTempCByIndex(0) + String("*C"));
  delay(100);
  mySerial.println((char)26);// ASCII code of CTRL+Z
  delay(1000);
  mySerial.println("AT+CMGD=2");

  mySerial.println("AT+CMGF=1");    //Sets the GSM Module in Text Mode
  delay(1000);  // Delay of 1000 milli seconds or 1 second
  mySerial.println("AT+CMGS=\"No3\"\r");
  delay(1000);
  mySerial.println("Warning!! Server Room Temperature is Critical");
  mySerial.println(String("Reading : ") + sensors.getTempCByIndex(0) + String("*C"));
  delay(100);
  mySerial.println((char)26);// ASCII code of CTRL+Z
  delay(1000);
  mySerial.println("AT+CMGD=2");

}

void loop()
{
  sensors.requestTemperatures(); // Send the command to get temperature readings
  delay(1000);
  Serial.println(String("Temp Reading : ") + sensors.getTempCByIndex(0) + String("*C"));
  Serial.println(String("Voltage Digital: ") + digitalRead(7));
  Serial.println(Temp_alarmSent ? "True" : "False" );
  Serial.println(D7_alarmSent ? "True" : "False" );
  Serial.println("***********");
  ReceiveMessage();

  if (digitalRead(7) == 1 || sensors.getTempCByIndex(0) > 29 || D7_alarmSent == true || Temp_alarmSent == true ) {
    if (digitalRead(7) == 1 ) {
      if (!D7_alarmSent) {
        D7_alarmSent = true;
        PowerSMS();
      }

    }

    else if (sensors.getTempCByIndex(0) > 29 ) {
      if (!Temp_alarmSent) {
        Temp_alarmSent = true;
        SendMessage();
      }

    }

    else {

      if (D7_alarmSent){                  //alarmSent == true means that previous state was "Power Down"
          SendMessage_After_Power_Down();          //Send message
          D7_alarmSent = false;
          Temp_alarmSent = false;             //Reset alarmstate
        }

    }
  }

}

void SendMessage_Normal()
{
  Serial.println("Temperature and Power is OK");

  mySerial.println("AT+CMGF=1");    //Sets the GSM Module in Text Mode
  delay(1000);  // Delay of 1000 milli seconds or 1 second
  mySerial.println("AT+CMGS=\"No1\"\r");
  delay(1000);
  mySerial.println("Temperature and Power is OK");
  mySerial.println(String("Reading : ") + sensors.getTempCByIndex(0) + String("*C"));
  delay(100);
  mySerial.println((char)26);// ASCII code of CTRL+Z
  delay(1000);

  mySerial.println("AT+CMGF=1");    //Sets the GSM Module in Text Mode
  delay(1000);  // Delay of 1000 milli seconds or 1 second
  mySerial.println("AT+CMGS=\"No2\"\r");
  delay(1000);
  mySerial.println("Temperature and Power is OK");
  mySerial.println(String("Reading : ") + sensors.getTempCByIndex(0) + String("*C"));
  delay(100);
  mySerial.println((char)26);// ASCII code of CTRL+Z
  delay(1000);

  mySerial.println("AT+CMGF=1");    //Sets the GSM Module in Text Mode
  delay(1000);  // Delay of 1000 milli seconds or 1 second
  mySerial.println("AT+CMGS=\"No3\"\r");
  delay(1000);
  mySerial.println("Temperature and Power is OK");
  mySerial.println(String("Reading : ") + sensors.getTempCByIndex(0) + String("*C"));
  delay(100);
  mySerial.println((char)26);// ASCII code of CTRL+Z
  delay(1000);

}
void SendMessage_After_Power_Down(){

  Serial.println("Power Back Online");

  mySerial.println("AT+CMGF=1");    //Sets the GSM Module in Text Mode
  delay(1000);  // Delay of 1000 milli seconds or 1 second
  mySerial.println("AT+CMGS=\"No1"\r");
  delay(1000);
  mySerial.println("Power Back Online");
  delay(100);
  mySerial.println((char)26);// ASCII code of CTRL+Z
  delay(1000);

  mySerial.println("AT+CMGF=1");    //Sets the GSM Module in Text Mode
  delay(1000);  // Delay of 1000 milli seconds or 1 second
  mySerial.println("AT+CMGS=\"No2\"\r");
  delay(1000);
  mySerial.println("Power Back Online");
  delay(100);
  mySerial.println((char)26);// ASCII code of CTRL+Z
  delay(1000);

  mySerial.println("AT+CMGF=1");    //Sets the GSM Module in Text Mode
  delay(1000);  // Delay of 1000 milli seconds or 1 second
  mySerial.println("AT+CMGS=\"No3\"\r");
  delay(1000);
  mySerial.println("Power Back Online");
  delay(100);
  mySerial.println((char)26);// ASCII code of CTRL+Z
  delay(1000);

  }

void ReceiveMessage()
{
  if (mySerial.available() > 0)
  {
    mySerial.println("AT+CNMI=2,2,0,0,0"); // AT Command to recieve a live SMS
    delay(1000);
    textMessage = mySerial.readString();
    Serial.print(textMessage);
    delay(10);
  }
  if (textMessage.indexOf("Status") >= 0) {
    SendMessage_Normal();
    mySerial.println("AT+CMGD=2");

  }
}
```


message:
Communication with sensor KMX63 in I2C

I trying to use a new sensor the KMX63 with a Arduino Uno board, my sensor is on a evaluation board made by kionix.
For the connexion il linked as follows:

| Pin Uno | Pin evaluation board |
| A5 | 5 |
| A4 | 7 |
| 3.3 | 1 |
| GND | 8 |

Here the schematic of the evaluation board:
[![eval board schematic][1]][1]

I found a technical note from the constructor that advice to do some steps after the power up of the sensor to insure it's well functioning I wrote a code following it:
<!-- language-all: lang-cpp -->
~~~~~
#include <Wire.h>
#include "KMX62.h"

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

  Serial.println(F("Starting"));

  byte error=7;
  byte id=0;
  byte command=0;
  delay(60);
  Wire.beginTransmission(KMX62_I2C_ADD_2);
  Wire.write(0x7F);
  Serial.println(F("Write 0x7F"));
  Wire.write(0x00);
  Serial.println(F("Write 0x00"));
  delay(100);
  error=Wire.endTransmission();
  Serial.print(F("retour 1 : "));
  Serial.println(error);
  if( error==0 ){
    Wire.beginTransmission(KMX62_I2C_ADD_2);
    Wire.write(CNTL2);
    Wire.write(0x00);
    error=Wire.endTransmission();
    if( error==0 ){
      Wire.beginTransmission(KMX62_I2C_ADD_2);
      Wire.write(CNTL1);
      Wire.write(0x80);
      error=Wire.endTransmission();
      if(error==0){
        delay(5);
        Wire.beginTransmission(KMX62_I2C_ADD_2);
        Wire.write(WHO_AM_I);
        Wire.endTransmission(false);
        Wire.requestFrom(KMX62_I2C_ADD_2,1);
        id=Wire.read();
        error=Wire.endTransmission();
        if(id==0x18||id==0x2D){
          Wire.beginTransmission(KMX62_I2C_ADD_2);
          Wire.write(COTR);
          Wire.endTransmission(false);
          Wire.requestFrom(KMX62_I2C_ADD_2,1);
          command=Wire.read();
          error=Wire.endTransmission();
          if(command==0x55){
            Serial.println(F("device ok"));
          }else{
            Serial.println(F("Issue with the sensor step e : need to be rebooted"));
          }
        }else{
          Serial.println(F("Issue with the sensor step d id=wrong : need to be rebooted"));
        }
      }else{
        if(error==2||error==3){
        Serial.println(F("Issue with the sensor step c : need to be rebooted"));
        }
      }
    }else{
      if(error==2||error==3){
        Serial.println(F("Issue with the sensor step b : need to be rebooted"));
      }
    }
  }
}

void loop(){

}
~~~~~~

but i have an issue the steps , the program seem to freeze when i try to write into the register 0x7F.
I don't get any trace that i should have after the wire.endtransmission().
Here the trace i obtain :
````
09:56:35.477 -> Starting
09:56:35.511 -> Write 0x7F
09:56:35.511 -> Write 0x00

``````

i have use the I2C scanner to check if the sensor appear, i had to modify the scanner to add a delay before Wire.beginTransmission and the Wire.endTransmission to avoid the scanner to be freeze too at the first address tried. After the modification i did saw the sensor at the address it was mean to be.
here the trace for the I2C scanner :
````
Scanning...
I2C device found at address 0x0F  !
done
````

Anyone have an idea of why i can't write anything to my sensor without making my program freeze indefinitely each time ?

PS : After the advice of chrisl i rerunned all my programs on a arduino mini pro on 3.3V / 8Mhz and got the same result.

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

body: I finally found where the problem was, i had made a error on the reading of the schematic of the evaluation board. I thought that the pin J1-9 was already wired in intern but it was wrong. I wired it to the VCC output of my board and it work perfectly now.


message:
3.3v pin on a 5v Pro Micro?

I have a arduino pro micro that runs on 5v.
I also have a Max4466 that needs 3.3v, however the pro micro doesn't seem to have a 3.3v VCC.
Is there any way to attach the max4466 to the Board?

body:
You need to add an external 3.3V voltage regulator. You can get these quite cheap on eBay (etc) as a module - some even come in a breadboard friendly format.

Power it from the 5V from the Arduino, then power your MAX4466.

However, the MAX4466 can run at up to 5.5V, so I fail to see why you think you need 3.3V.


message:
TSX0108 logic level converter not working

Am trying to setup logic level converter with arduino for eps8266 WiFi module. Am using this logic level converter but it’s not working not sure what am doing am not getting any output.

My circuit

    Red wire : 3.3v power source
    Orange wire : 5v power source
    Blue wire : ground.
    Yellow wire : arduino TX1 on B2
    White wire : output on A2

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

**Multi meter it red wire : 3.3 v showing on display**

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

**Multi meter it orange wire : 4.68 v showing on display**

[![enter image description here][3]][3]

**Multi meter it yellow wire : 4.36 v showing on display**

[![enter image description here][4]][4]

**Multi meter it white wire : no voltage showing on display ??? **

[![enter image description here][5]][5]

Update : have set OE pin to enable and swapped red and orange. Still no output for yellow wire

[![enter image description here][6]][6]

  [1]: https://i.stack.imgur.com/8vjMw.jpg
  [2]: https://i.stack.imgur.com/DlfgW.jpg
  [3]: https://i.stack.imgur.com/xftbT.jpg
  [4]: https://i.stack.imgur.com/W4cFA.jpg
  [5]: https://i.stack.imgur.com/ysBH7.jpg
  [6]: https://i.stack.imgur.com/KASwO.jpg

body: When the output-enable(OE) input is low, all outputs are placed in the high-impedance (Hi-Z) state.  You must connect the OE pin to logic high to enable the outputs.


message:
Non-blocking incrementation with single button pressure

I am looking for a way to increment a variable by one each time a button is pressed. Current approach is the following :

        if (redButton.isPressed())
        {
            a++;
            delay(100);
        }

`isPressed()` just return true if the pin state is HIGH.

`delay(100)` is used to compensate the small amount of time the button is being pressed. Otherwise `a` would be incremented multiple times in a single press. But it's blocking behavior, my program can't do anything else during that delay.

In short I'm looking to add a method in my Button class to detect if the button "has just been released".

body:
In your approach a button press will be detected every 100ms when you just keep the button pressed. So you have to set a flag when the button is pressed. When the button is **not** pressed while your flag is set, that's the event you're looking for. In this way you can detect both a button press and a release respectively.
As @JRobert mentioned, there still has to be an amount of time between two calls to such a routine to provide some button debouncing.

    bool pressed_flag=false;
    bool button_timestamp=millis();
    uint16_t button_period=100;

    if(millis()-button_timestamp>button_period){
      button_timestamp=millis();
      if(redButton.isPressed() && !pressed_flag){
        // button has just been pressed
        // you can do sth. here
        pressed_flag=true;
      }
      else if(!redButton.isPressed() && pressed_flag){
        // button has just been released
        // you can do sth. here
        pressed_flag=false;
      }
    }


message:
How to read a text file line by line

I am making an LED controller that reads instructions from a text file on my computer. I need to get the arduino to read this text file line by line and put each line into the appropriate variables. I'm using a sparkfun pro micro which is a knock off arduino pro micro. The pro micro is connected via USB

I've seen people use the SD library, but I don't know if this will work for my situation because I am reading directly from the computer and not an SD card. Is this the correct approach, or is there an additional/alternate library that I need to use?

body:
What you can do is:

- Read character by character and copy it to a temporary buffer of the maximum length of one line.
- When you parsed an end of line symbol, you start parsing the (complete) line in the buffer.
- In this line parsing (preferably a separate function), you parse the line, using string to type conversion functions, like `atoi` (string to an inter) etc. Also you can use the C function `strtok` to split the string based on a symbol (e.g. comma).
- After parsing the line, clear the buffer (you already processed it), and continue filling the buffer again until it is full.
- Don't forget to check for end of file.


body:
The Arduino cannot read data on the PC.

Instead the PC has to send the data to the Arduino, and the Arduino has to parse (interpret) that data.

You need two things:

1. A piece of software running on the PC that sends the file contents to the Arduino over serial
2. Software on the Arduino that accepts the stream of data coming in over the serial port and does something with it.

It is no different to handling commands that are manually typed by someone using the Serial Monitor - it's just they tend to come in a lot faster when being sent by the PC from a file.


message:
Arduino is incorrectly reading serial input from C# program

I am trying to create a program to operate my arduino based LED controller. I'm pretty sure that my C# program is outputting to serial port correctly as I double checked the output in Debug.WriteLine(). The program is supposed to send information to the arduino in the following format (newlines included):

```
mode
number of colors
blend speed
beats until color change
Red   <---
Green <---
Blue  <---
Brightness <---
```
the last 4 are the only ones that matter for now as I am trying to get the LED's to show up one solid color first before worrying about other modes or patterns. The debug writeline loop output of my last test looks like this
```
1
1
0
1
209
255
255
219
```

This should be translating to the relevant arduino variables the same way but instead, I only get white light that seems to randomly brighten or darken when I mess with the color/brightness sliders

My code for the arduino is below. I am very new to this so it's probably not even close to right. getData() at the bottom is the function that most likely is the culprit, but I'll put the rest in just in case:

```
#include <SPI.h>
#include <Adafruit_DotStar.h>

#define NUMPIXELS 60

Adafruit_DotStar strip = Adafruit_DotStar(NUMPIXELS, DOTSTAR_BRG);

// Variables
int mode;
int numColors;
int fadeSpeed;
int BBCC;
int R;
int G;
int B;
int Bright;
String buff;

void setup() {
  strip.begin();
  strip.show();
  //Serial.begin(9600);
}

void loop() {
  getData();

  if (mode == 1)
  {
    //strip.setPixelColor(0, R, G, B);
    strip.setBrightness(Bright);
    strip.show();
  }
}

void getData()
{
 // if (Serial.available() > 0)
 // {
    buff = Serial.read();
    int result = buff.toInt();
   mode = result;
   if (mode != -1)
   {
    buff = Serial.read();
    int result = buff.toInt();
    numColors = result;
    buff = Serial.read();
    result = buff.toInt();
    fadeSpeed = result;
    buff = Serial.read();
    result = buff.toInt();
    BBCC = result;
    buff = Serial.read();
    result = buff.toInt();
    R = result;
    buff = Serial.read();
    result = buff.toInt();
    G = result;
    buff = Serial.read();
    result = buff.toInt();
    B = result;
    buff = Serial.read();
    result = buff.toInt();
    Bright = result;//Serial.read();
    strip.setPixelColor(0, R, 0, 0);
    //strip.setBrightness(Bright);
    strip.show();
   }
   else
   {
    strip.setPixelColor(0, R, 0, 0);
    //strip.setBrightness(Bright);
    strip.show();
   }
//  }
}
```

body:
Your Serial receive code is not correct in some ways:

1. You should only read from Serial, if there is really something to read. For the first read, that is not the problem, since you checked against the return value being -1 (which is the return code for "there is no new data in the buffer). But after that, you read without ever checking, if there is something to read. You need to understand, that the data is really send serially. The bytes come in one after another and there is no concept as messages on the Serial interface (which is actually called UART in non-Arduino environments). More over, there might be small pauses somewhere in the transmission, since you cannot foresee, when exactly the PC will send the data (the PC has a bunch of other tasks to do, too). So it might be, that you have received one byte, which will lead you into the `if` statement, but the rest of the data will arrive later. All data is then read as -1, since there is no data in the buffer.

    You have to check, if there is actually data to read, before reading. This can be done with `Serial.available()`. It will return the number of new data bytes in the buffer. For example, if you want to read 8 bytes, you should wait, until at least 8 bytes are inside the buffer by using `if(Serial.available >= 8)`.

2. You are sending the data from the PC as ASCII encoded text. That means, that every number above 9 consists of multiple data bytes. The 4 values, that you are interested in, are all over 200, which means, that you need to read 3 bytes to get them. But you only call `Serial.read()` once for every value. That will give you the first digit, which is a 2 for all values in the shown data. More over, since you only read 1 byte, where there is the whole number (which may be multiple bytes) plus 1 or 2 bytes for the new line (depending on the chosen line ending `\n` or "\n\r"), The whole reading gets misaligned to the data structure. Now the read data (if there is any) is also dependent on how much data was send for the values before.

    Keep in mind, that with ASCII encoded text, you may need multiple `Serial.read()` calls to actually read a full number. I will describe the way to go here in the next point.

3. As I already mentioned above, there is no message protocol on the Serial interface. Lost data would lead to misalignment and thus garbled data. But you can impose an own protocol onto the Serial stream of data. It is a good practice, to first receive a full message (maybe with multiple data values inside it) and then process it. For that I would suggest a new data structure

        mode|number of colors|blend speed|beats until color change|Red|Green|Blue|Brightness\n

    The new line is here realized only with a newline character (`\n`). The values are separated with a vertical dash. You should put an `if(Serial.available()>0)` into your loop function. Then inside that if statement, you read one character and add it to a buffer. If you read the `\n` character, you start to process the buffer. You can then convert one value after another from the buffer and save them into variables. After that, you clear the buffer. You can see this style in the `SerialEvent` example, that comes with the Arduino IDE. You should also read Majenko's blog article about [reading the Serial interface on the Arduino][1].

---

That said, you should be cautious with using `String` object on the Arduino. Sure, `String`s are convenient, but they dynamically allocate the needed memory during the runtime. On microcontrollers, which normally have very limited RAM memory, that can lead to heap fragmentation (heap is the memory area for dynamic memory allocation). When using `String` objects, the underlying buffer get's often recreated. As buffers get allocated and deleted later, that can lead to small memory areas, which are unused, but to small to actually be used by the buffer. You can fill up your RAM very fast with that.

It is better to not use `String`, but directly a `char` array with a fixed length. Majenko also wrote an article about the `String` problem: [The Evils of Arduino Strings][2]

  [1]: https://majenko.co.uk/blog/reading-serial-arduino
  [2]: https://majenko.co.uk/blog/evils-arduino-strings


body:
First off this is **NOT** how to read from the serial USART!

    buff = Serial.read();
    int result = buff.toInt();

`Serail.read` returns a single byte, you are treating it as a string, then trying to parse it; you will never see anything other than 0-9 if your lucky (its very unlikely that buff contains a valid string, chances are it will just keep going till it finds a \0, and return some random number, or just fail.

EDIT: It seems I was mistaken, the 'read()' returns an int, nominally only a byte is returned, but a 16-bit -1 (0xffff) is returned for an error; the documentation could be clearer here.

<s>Second the arduino serial library has a huge flaw, -1 is used as a failure to read, but -1 (i.e. 255) could be a valid piece of data, this makes the return value useless, as you don't know if 255 is the correct value, or an error. The only way around this is with `Serial.available` so you must use this to control your code or you won't know whats going on.</s>

Finally, you can write binary data in c# with `.Write(byte[] ...)` and then read it in binary back, so you don't have to parse it.


message:
How do I send multiple variables via stream to Unity?

So I currently have this for arduino.ino:

    Serial.println(Variable1);

that does this in Unity:

    string variable1 = stream.ReadLine();
    float x = float.Parse(variable1);
 transform.Rotate (0, -x/1000, 0);

My question is; How would I send 3 variables from the Arduino to Unity so I can put each value into the `transform.Rotate` function at once?

For example in pseudocode:

    Arduino.ino
    send(Variable1, Variable2, Variable3);

    Unity
    transform.Rotate(Variable1,Variable2,Variable3);

I hope this makes sense.
Thank you.

body:
What you need to do is define a communication scheme/protocol. You appear to be using the Serial UART via USB.

Your first example has a simple scheme its simply the ASCII representation of the variable followed by a newline. i.e. :

    float x = 123.45;
    Serial.println(x);

this simply outputs

    "123.45\n"

you could continue this pattern

    float x, y, z,
    ... // assume x, y and z have values in them
    Serial.print(x);
    Serial.print(' ');
    Serial.print(y);
    Serial.print(' ');
    Serial.println(z);

this outputs something like:

    "123.43 23.34, 42.24\n"

then your receiving code will do do something like

    string line = stream.ReadLine();
    string[] parts = line.Split(' ', StringSplitOptions.RemoveEmptyEntries)
    float x = float.Parse(parts[0]);
    float y = float.Parse(parts[1]);
    float z = float.Parse(parts[2]);

but this is very inefficient, since the arduino needs to convert the float to an ASCII string, then transmit that over the serial port, where its read on the other side, then parsed back into a float. One doesn't need to do this, you can do in binary, it won't be human readable, but it will use much less transmission space.

    float x, y, z; // assume these are valid
    Serial.write(&x, sizeof(float));
    Serial.write(&y, sizeof(float));
    Serial.write(&z, sizeof(float));
    // n.b. one should write an end of message here or something else to frame the data

and on the other side

    byte[] data = new byte[12];
    stream.Read(data, 0, 12);

    float x = BitConverter.ToSingle(data, 0);
    float y = BitConverter.ToSingle(data, 4);
    float z = BitConverter.ToSingle(data, 8);

You will generally also want some way to frame the data, so you might want to start with a simple message header, i.e.:

    struct head
    {
      int length;
      int code;
    };

and you write it like:

    head header; //assume this is valid
    Serial.write(&header, sizeof(header));

then you can write you message.

You might also want to implement some sort of checksum, so you can verify that you got the data correctly.

You can create multiple message structures this way, i.e.

    struct vect3d
    {
      head header;
      float x;
      float y;
      float z;
    }

just fill and send

    vect3d v3;
    v3.head.length = sizeof(vect3d); // one could subtract sizeof(head) off so the reader can always read the first 8 bytes and read the rest of the message from there
    v3.head.code = VECT3D; // assume this is defined somewhere
    v3.x = 123.5;
    v3.y = 23.4;
    v3.z = 42.24;

    Serial.write(&v3, sizeof(v3));

On the other side one would read in the first 8 bytes, then read in the rest of the message based on the length, and parse it based on the code.


message:
MPU6050 Gyroscope does not give reliable readings

It gives reliable readings for a couple of seconds and then it becomes unreliable.

My arduino code is this:

    #include<Wire.h>
    const int MPU6050_addr=0x68;
    int16_t AccX,AccY,AccZ,Temp,GyroX,GyroY,GyroZ;
    void setup(){
      Wire.begin();
      Wire.beginTransmission(MPU6050_addr);
      Wire.write(0x6B);
      Wire.write(0);
      Wire.endTransmission(true);
      Serial.begin(9600);
    }
    void sendVector(float x, float y, float z) {
      Serial.print(x, 4);
      Serial.print("|");
      Serial.print(y, 4);
      Serial.print("|");
      Serial.println(z, 4);
    }

    void loop(){
      Wire.beginTransmission(MPU6050_addr);
      Wire.write(0x3B);
      Wire.endTransmission(false);
      Wire.requestFrom(MPU6050_addr,14,true);
      AccX=Wire.read()<<8|Wire.read();
      AccY=Wire.read()<<8|Wire.read();
      AccZ=Wire.read()<<8|Wire.read();
      Temp=Wire.read()<<8|Wire.read();
      GyroX=Wire.read()<<8|Wire.read();
      GyroY=Wire.read()<<8|Wire.read();
      GyroZ=Wire.read()<<8|Wire.read();
      //Serial.print(AccX);
      //Serial.print(AccY);
      //Serial.print(AccZ);
      //Serial.print(" || Temp = "); Serial.print(Temp/340.00+36.53);
      //Serial.print(" || GyroX = ");
      //Serial.println(GyroX);
      //Serial.print(" || GyroY = ");
      //Serial.println(GyroY);
      //Serial.print(" || GyroZ = ");
      //Serial.println(GyroZ);
      sendVector(GyroX, GyroY, GyroZ);
      delay(100);
    }

The above sends data to unity which controls an object. The object works with the gyroscope and then due to the random readings it rotates quickly and randomly.

body:
I don't think you have given enough information to help you debug this, but i can try to give some advice:

First verify that the chip works correctly
=

Use the arduino plot monitor, and a sample program, to see the behavior of the chip and values over time; make sure its not a problem with the chip

Second verify that you are interpreting the values correctly
=

The MPU6050 outputs 16-bit data, but doesn't have 16-bit resolution, this means that the lower bits of the data are random, meaningless noise, and should be ignored/discarded.

If you are assuming that all 16 bits contain valid data, and your code is sensitive enough to be affected by those lower bits, then you will see unstable random data.

Third consider other (possible) obstacles
=

Try increasing the serial BAUD rate, you may be taking too much time and causing problems that way.

Maybe you are getting out of sync while reading from the chip, if there is additional data being sent, you could could build up a backlog in the buffer, and start interpreting messages incorrectly because you are reading part of one and part of another. Try using a library to talk to the chip, one that other people have used and is known to work; this could remove bugs you are blind to, or bugs that everyone will run into, but they have already been fixed in the library!


message:
How to control the power of attiny13a via pin change interrupt?

I'm trying controll the power of attity13a and turn off/turn on the led.

I'm going to goals:

After to click on the button0
led will blicking 5 second nad then the attiny13a going to sleep.

After to click on the button1 then wake attiny13a up and then led will shane.

The button0 to sleep and blink the led.
the button1 to wake up and turn on the led.

Could you explain what is wrong in this sketch, please?
thank you for your answers.

**code:**
```c
    #define F_CPU  1200000UL
    #define LED     PB2 // PB2
    #define BUTTON1 PB1 // PCINT1
    #define BUTTON0 PB0 // PCINT0

    #define HIGH    1
    #define LOW    0
    #define INPUT    0
    #define OUTPUT    1
    #define INPUT_PULLUP 2
    #define FALSE    0
    #define TRUE    1
    #define _BV(bit)  (1 << (bit))

    #include <avr/io.h>
    #include <avr/interrupt.h>
    #include <avr/sleep.h>
    #include <util/delay.h>

    void pinMode(uint8_t pin, uint8_t mode)
    {
     if(mode == OUTPUT) // Pin as output
      DDRB |= _BV(pin);
     else // Pin as input or input pullup
     {
      DDRB &= ~_BV(pin); // Set pin as input
      if(mode == INPUT_PULLUP)
       PORTB |= _BV(pin); // Enable pullup resistors
     }
    }

    void digitalWrite(uint8_t pin, uint8_t val)
    {
      if(val)
        PORTB |= _BV(pin);  // Set pin high
      else
        PORTB &= ~_BV(pin); // Set pin low
    }

    uint8_t digitalRead(uint8_t pin)
    {
      return !!(PINB & _BV(pin));
    }

    // go to sleep
    ISR(PCINT0_vect)
    {
       if(digitalRead(BUTTON0)){
         int i=0;
      while(i<10){
       blink();i=i+1;
      }
      set_sleep_mode(SLEEP_MODE_PWR_DOWN);
      sleep_enable();
      sleep_cpu();
     }
    }

    //wake up
    ISR(PCINT1_vect){
       if(digitalRead(BUTTON1)){
     digitalWrite(LED, HIGH);
       }
    }

    void blink(){
     digitalWrite(LED, LOW);
     _delay_ms(500);
     digitalWrite(LED, HIGH);
        _delay_ms(500);
    }

    int main(void)
    {
     pinMode(BUTTON0, INPUT_PULLUP);
     pinMode(BUTTON1, INPUT_PULLUP);

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

     // Sets the Pin change interrupt mask PB0, PB1
     PCMSK |= _BV(PCINT0)|_BV(PCINT1);

     //Enables Interrupts globally after setup
     //sei();
     SREG |= _BV(SREG_I);

     while(TRUE){}
    }
```

body:
```c
#define F_CPU   1200000UL

#define LED     PB2 // PB2
#define BUTTON1 PB1 // INT0
#define BUTTON0 PB0 // PCINT0

#define HIGH         1
#define LOW          0
#define INPUT        0
#define OUTPUT       1
#define INPUT_PULLUP 2
#define FALSE        0
#define TRUE         1
#define _BV(bit)    (1 << (bit))

#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/sleep.h>
#include <util/delay.h>

void pinMode(uint8_t pin, uint8_t mode){
 if(mode == OUTPUT) // Pin as output
  DDRB |= _BV(pin);
 else // Pin as input or input pullup
 {
  DDRB &= ~_BV(pin); // Set pin as input
  if(mode == INPUT_PULLUP)
   PORTB |= _BV(pin); // Enable pullup resistors
 }
}

void digitalWrite(uint8_t pin, uint8_t val){
  if(val)
 PORTB |= _BV(pin);  // Set pin high
  else
 PORTB &= ~_BV(pin); // Set pin low
}

uint8_t digitalRead(uint8_t pin){
  return !!(PINB & _BV(pin));
}

//wake up
ISR(INT0_vect){
   sleep_disable();
   //cli(); // Turn off global interrupts
   digitalWrite(LED, HIGH);
}

void blink(){
 digitalWrite(LED, LOW);
 _delay_ms(1000);
 digitalWrite(LED, HIGH);
 _delay_ms(1000);
}

// go to sleep
ISR(PCINT0_vect)
{
   //cli(); // Turn off global interrupts
   if(!digitalRead(BUTTON0)){
  cli(); // Turn off global interrupts

  blink();

  digitalWrite(LED, LOW);

  sei(); // Turn on global interrupts
  set_sleep_mode(SLEEP_MODE_PWR_DOWN);
  sleep_enable();
  sleep_cpu();
 }
}

int main(void)
{
 //enabled external interrupt
 MCUCR=0;
 //MCUCR=0b00000000;
 GIMSK|=_BV(INT0); // enabled external interrupt INT0 - PB1

 // Sets the Pin change interrupt mask
 GIMSK|=_BV(PCIE);
 PCMSK|=_BV(PCINT0);//PB0

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

 pinMode(BUTTON1, INPUT_PULLUP);//INT0 - PB1
 pinMode(BUTTON0, INPUT_PULLUP);//PCINT0 - PB0

 //Enables Interrupts globally after setup
 //SREG |= _BV(SREG_I);
 sei(); // Turn on global interrupts
 set_sleep_mode(SLEEP_MODE_PWR_DOWN);
 sleep_enable();
 sleep_cpu();

 while(TRUE){}

 return 0;
}
```


message:
How can I program an ESP 10 module

I buy an ESP-10 module and I want to upload custom room to its flash. The problem is that there is no way to access GPIO 0 pin! Is there some way around it to upload custom room without connecting GPIO 0 to the ground?
How in the earth should I program it without this pin?
here is an address to supplier's page which contains schematic and some other details.
https://www.tindie.com/products/George/esp8266-esp-10-module/#product-description

body: You can't.  Not without physical modification to the PCB itself (remove the chip, scratch off a pad and trace, replace pad with fine enamelled copper wire tinned at the end, replace chip).  All you can use is whatever firmware is currently installed in the module.


message:
use of spec sensor in arduino uno

i have been trying to use NO2 spec senor in arduino UNO. how to write the code for it to get the output in terms of 'ppm' and how to give connection.with the helo of cross-sensitivity given in datasheet how to detect the interference gases from this sensor itself..the datasheet URL:

https://www.spec-sensors.com/wp-content/uploads/2016/10/3SP_NO2_5F-C-Package-110-508.pdf

body:
In the specification sheet linked to in the post we find this:

> -30+/-10nA/ppm

This is a very small amount of current.  The Arduino ADC is a voltage sensing device and (unless modified) has a range of 0 to the operating voltage of the Arduino.  Usually 3.3V or 5V.

Converting nano Amps to that range of voltage will require additional hardware.  A stock Arduino and code are unlikely to make use of such a sensor.

The conversion of such small amounts of current to voltages measurable by a stock Arduino is not trivial. And most answers do not fit into the short format of stack exchange.  [Here is an Engineering Design News article][1] on the subject.

  [1]: https://www.edn.com/design/analog/4315417/Measuring-nanoamperes


message:
led chaser fill color effect

Please help. I am learning a lot about Arduino. Most all in lightning. I am a newbie. I play with nano and LED ws2812 and use fastled library.

What ask is to make effect like fill effect. For example with larson scanner/chaser.

    for (int i = 0; i<NUM_LEDS; i++)
    {
      leds[i]=CRGB::Red;
      FastLED.show();
      leds[i]=CRGB::Black;
      delay(50);
    }

From that code above how to make LED stop and lit up and loop again and stop and lit up.  I want every LED stop the LED lit up even LED looping start again from first LED. It like this:

> 10000 01000 00100 00010 00001 10001 01001 00101 00011 10011 01011
> 00111 10111 01111 11111

body:
You need two counter for this, one to keep track of how far the LED bar is filled, and one about the current 'running' LED to eventually 'touch' the LEDs which are already moved to the right.

Every led (currentLed) will run from index 0 until the last filled index, while the last filled index is decreased with 1 after every loop.

(note: I haven't checked the code).

    // Fill from the right, thus count backwards.
    for (int filledLedIndex = NUM_LEDS; filledLed >= 0; filledLed--)
    {
       // Now let a LED run from 0 upto filedLedIndex;
       for (int currentLed = 0; currentLed < filledLedIndex)
       {
          // Make previous LED black
          if (currentLed > 0)
          {
             leds[i - 1] = CRGB::Black;
          }

          // Make current LED red
          leds[i] = CRGB::Red;

          // Show.
          FastLED.show();
          delay(50);
       }
    }

    // Clear all LEDs.
    for (int led = 0; led < NUM_LEDS; led++)
    {
        leds[i] = CRGB::Black;
    }

    FastLED.show();
    delay(50);


message:
Increasing range of a DC-offset signal (software)

I am trying to read a signal with a DC offset of 511 (as seen by the ADC). The signal's tiny with regards to the offset, and I'm feeding it to a library that does a Fourier transform on it. It comes from a 3.5mm audio jack with AC coupling and the offset so I can see the full signal.

How may I increase the range of the signal? I am thinking something like the input signal is (490-530) and I want an output of (400-630) or something (numbers solely for example). The issue is that I still need the resulting signal to be centered around 511 AND I don't know the exact amplitude of the input (since it varies based on volume and particular audio going in at the moment).

I can assume that the volume of the audio input is relatively fixed (I need to be able to adjust this gain later, but I'm assuming the volume will be constant at some value per time I'm running the project), so I don't need envelope-following or something, but I'm not sure how to do this even so.

body:
You can't magic more resolution out of thin air (well, you can, but it slows down your sampling - you would "oversample" and average a number of sequential samples).

Instead you need to boost your signal *before* it gets to the ADC using an op-amp.  The simplest circuit (which also inverts the signal, but you don't really care about that I suspect) is:

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

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

<!-- End schematic -->

That circuit will both invert the signal (if you care, just do a little bit of maths in your program to flip the signal, but for FFT you don't really care) and double the amplitude around the mid-point. The doubling is controlled by the ratio of R1 to R2 (20000:10000 = 2:1 = doubled). The mid-point offset is created by R3/R4 - you don't need to manually add your own offset.