message:
Use JYETech 2.4 Inch LCD Display Screen Module with Arduino?

I have this JYETech 2.4 Inch LCD Display Screen Module that I would like to use for a project I have in mind, however, I'm not sure how to wire it up with my Arudino Mega. [Here is the datasheet for the display][1]. I have also attached a picture of the display below. The display is meant to work with a DIY oscilloscope but according to the manufacturer and other forum posts, it can be used as a display with other projects as well.

[Pictures of the display][2]

  [1]: https://jyetech.com/wp-content/uploads/2018/07/dso138-schematic-lcd.pdf
  [2]: https://i.stack.imgur.com/iJ3FC.jpg

body:
That display is an ILI9341 based one. On the DSO138 it connects the data pins D0-D7 to PORTB of the STM32.

You need to connect those 8 pins to 8 pins on the Arduino, along with the RS (Register Select) and CS (Chip Select) pins. The RD pin can be connected to 3.3V and the WR pin to GND, since you only really want to write to the screen (if you do want to read from the screen then you will want to connect RD and WR to two IO pins as well). Reset can be connected to a GPIO or to 3.3V, depending on if you want to do a hard reset at any point or not.

LED-A can connect to 5V, and each of the LED-K* pins should connect to ground through a resistor each. The size of the resistor will set the backlight brightness (try 100Ω to start with).

Then it's just a matter of finding a library that works with the ILI9341 in 8-bit parallel mode (u8glib maybe? I don't know, I never use Arduino to drive a TFT).

Note that since this is a 3.3V device you should really use a level shifter for all the digital signals.


sender: user

message:
String generator not working as expected

I'm trying to build a random string, save it to EEPROM as int, then read it back and output it.
If I give it a predefined string then it works fine. But Something is wrong with the random string generator.

      String output;
      char letter;

      String mystr=""; //"ABCabc123..";
      String characters = "ABCDEFGHIJKLMNOPQRSTUVXYZabcdefghijklmnopqrstuvxyz";
      String numbers = "0123456789";
      String other = "<>!.,()?|=&%¤#";

      // add random characters to empty string
      for(int i=0 ; i < 12 ; i++){
        mystr += characters[random(0, characters.length())];
      }
      // add two numbers, one other and two more characters
      mystr += numbers[random(0, numbers.length())];
      mystr += numbers[random(0, numbers.length())];
      mystr += other[random(0, other.length())];
      mystr += characters[random(0, characters.length())];
      mystr += characters[random(0, characters.length())];

      // loop the string and place one character in each EEPROM address
      for(int i=0 ; i < mystr.length() ; i++)
      {
        EEPROM.writeInt( i,mystr[i] );
      }

      // read the string back from EEPROM
      for(int i=0 ; i < 17 ; i++){
        letter = EEPROM.readInt(i);
        output += letter;
      }

If I run the code output will be "H". Every time.
If I use the predefined string "ABCabc123.." then it works correct.

What am I doing wrong with building the mystr?

sender: assistant

body:
Your first mistake is to use `String`. Don't. Instead use a `char` array.

    char mystr[18]; // Room for 17 characters plus the NULL terminating character

Your string constants should also be char arrays, not `String` variables. And better to put them in `PROGMEM`:

    const char characters[] PROGMEM = "ABCDEFGHIJKLMNOPQRSTUVXYZabcdefghijklmnopqrstuvxyz";
    const char numbers[] PROGMEM = "0123456789";
    const char other[] PROGMEM = "<>!.,()?|=&%¤#";

Now filling your target array becomes:

    for(int i=0 ; i < 12 ; i++){
      mystr[i] = pgm_read_byte_near(characters + random(0, 50));
    }

    mystr[12] = pgm_read_byte_near(numbers + random(0, 10));
    mystr[13] = pgm_read_byte_near(numbers + random(0, 10));
    mystr[14] = pgm_read_byte_near(other + random(0, 14));
    mystr[15] = pgm_read_byte_near(characters + random(0, 50));
    mystr[16] = pgm_read_byte_near(characters + random(0, 50));
    mystr[17] = 0; // Don't forget the NULL...

Your second problem is the use of `EEPROM.writeInt` and `EEPROM.readInt`.  Those are for writing integer values, not characters.  Instead just use `EEPROM.read` and `EEPROM.write`:

    for (int i = 0; i < 17; i++) {
        EEPROM.write(i, mystr[i]);
    }

Then to read back:

    for (int i = 0; i < 17; i++) {
        mystr[i] = EEPROM.read(i);
    }
    // And don't forget to terminate the string...
    mystr[17] = 0;


message:
Connect a hundred SIM800L's to Arduino (or any other board)

Is there a way to connect one hundred SIM800L's to Arduino? Essentially I want to be able to communicate with any of them that I want. If Arduino isn't capable of doing this, what do you suggest, so I could connect to and control 100 SIM cards?

Thanks for your help in advance!

R.

body:
You left unclear, what your exact requirements are. So the answer will be as general as your question. The SIM800L uses the Serial interface (UART). So the point is to connect to 100 different serial interfaces.

If it is ok to talk to each SIM800L sequentially (only one at a time), you can use a series of multiplexers. A multiplexer chip connects one pin to one of multiple pins (called channels here). Depending on the used chip, the channel can be selected in different ways. The standard way is with simple digital input pins, that construct a binary number. So for 8 channels you need 3 input pins (`2^3`). Other ways are through communication interfaces like SPI or I2C.

Normally a multiplexer has only 8 channels, though you can also find once with more, but I don't think there are multiplexers with 100 channels. So you could next the multiplexers. If you put another multiplexer on every channel of the first multiplexer, you get `8*8 = 64` channels with 9 multiplexers in total. Add some more multiplexers on the next level and you will get to over 100 channels. Then you need 2 of these multiplexer trees to multiplex both serial lines (TX and RC). Since that are a lot of multiplexers and thus a lot of inputs to choose the correct channels, you could use multiplexers with SPI or I2C interface. The first would require 1 digital output pin of the Arduino per multiplexer as slave select pin, the latter would require either a multiplexer type, that can as many different I2C addresses as multiplexers in your system, or a bit more complex programming and also 1 pin per multiplexer to change the address of the chip to configure. How to use these multiplexers with Arduino depends on the used chip. You should refer to it's datasheet.

As you now see, connecting one single Arduino to 100 serial interfaces it a complex task. Depending on your actual requirements and goals in your "PoC project", it might be a better way to follow Majenkos advice and build it more modular with multiple Arduinos/microcontrollers.


message:
Missing time when using timer

I have set up Timer2 to count every tick at 16MHz, or 62.5ns per tick. Then I run the following code:

    int t = 0;
        for (int i=0;i<64;i++){
      data[4*i] = TCNT2;
      data[4*i+1] = TCNT2;
      byte now = data[4*i+1];
      byte last = data[4*i];
      t += now > last? (long)(now-last) : 256 -(long)(last-now);
      data[4*i+2] = TCNT2;
      data[4*i+3] = TCNT2;
      }
    }
    for (int i=0;i<255;i++){
      Serial.println(data[i]-data[i+1]);
    }

and I get the output: "4 4 4 11" (repeated) which makes sense, 4 clock cycles to read *TCNT2* and write it to the correct place in *data* and 11 cycles when also evaluating the loop condition. However, I can't understand when the variable *t* is updated. I have tried running with and without *t* and both give the same timings. From my (obviously lacking) understanding updating a variable is at minimum one instruction, so how can it do it under one clock cycle? Am I misunderstanding what one instruction is or does the *TCNT2* counter for the timer not update accurately here?

body: Ops, I just realized it's the compiler working it's magic. I never used t, thus the compiler said "Wtf is this guy doing, this t is useless and I'll remove it!". When I used t I got sensible results.


message:
Why does the reading on the ESP32 read max, when the reading on UNO read accurately?

I have a 'Capacitive Soil Moisture Sensor' hooked up to my Uno.
Very simple code. AnalogRead(MoistureSensorPin);
This will return a differing value that I can work with.

When applying the same code to an ESP32 with a similar set-up. It always returns '4095' which I understand is the maximum value an analog input can return. But I cannot understand why it does this.

Any help will be much appreciated.

body:
The ESP is a 3.3v device. If your Uno is a 5v device, its A/D converter can measure and report voltages from 0 to 4.9878v (5v minus 1 LSB). If the same signal is presented to the ESP, any value above 3.29919 volts (3.3v - 1 LSB) will read as 4095, i.e., out of range.

(If this isn't your issue, adding wiring diagrams of each system to your question will help us understand it better.)

Update:

> Perhaps a different ESP unit would be the ideal solution?

As far as I know, all of the ESP's are 3.3v devices. So the solutions I see are:

 1. Power your sensor with 3.3v (is this an option?) so its output will be within the input range of the ESP's built-in A/D.

 2. Scale the sensor output from it's 0-5v range to the 0-3.3v range the ESP can accept. Whether you can use a simple divider network or would need an op-amp may depend on the sensor, but if, as I suspect, it is a simple resistance device, a voltage divider should work.

 3. Use an external 5v A/D converter. This will require a 5v power supply (which I presume you are using already, to power the sensor) and voltage level conversion between the A/D and input pin(s) of the ESP. The conversion could be a purchased level-converter board or a simple resistor-divider network.


message:
Trying to control DC motor speed with PID

i'm trying to control a DC motor with PID. I have already made a code where i control the motor with an ultrasonic sensor (for distance) but now i need to run the motor at a given RPM (the Output). I did a lot of resarch and found that i will have to use the PID Library. But with my existing code i'm not sure if it's going to work. I know that i will have to modify PWM values by the Input on the analogWrite(). Can you enlight me on this PID? Here is my code:

    int enableBridgePin = 10;
    int forwardPin = 11;
    int backWardPin = 9;
    int tickPin = 2;
    const int trig = 5;
    const int echo = 6;

    int dt;
    int distance;

    void setup() {
      pinMode(enableBridgePin, OUTPUT);
      pinMode(forwardPin, OUTPUT);
      pinMode(backWardPin, OUTPUT);
      pinMode(trig, OUTPUT);
      pinMode(echo, INPUT);
      Serial.begin(9600);

      digitalWrite(forwardPin, LOW);
      digitalWrite(backWardPin, LOW);

      digitalWrite(enableBridgePin, HIGH);
    }

    void loop() {
      analogWrite(enableBridgePin,255);

      digitalWrite(forwardPin, HIGH);
      digitalWrite(backWardPin, LOW);
      Serial.println(distancefonction(dt,distance));

      if (distancefonction(dt,distance)<15 && distancefonction(dt,distance)>7){
        slowdown();}
    }

    int distancefonction(int dt, int distance) //function to show distance

    void slowdown(){
      for(int i=255;i>=0;--i){
          analogWrite(enableBridgePin,i);
          delay(10);}
       Serial.println("SLOWDOWN");
    }

body:
PID- or any similar control needs

- set point
- actual value
- controlling variable (your PWM value)

The difference between set point and actual variable and its change over time are combined to calculate the controlling variable in order to minimize that difference.

Control theory in general is too complex to answer the "how to" here in general.

Besides measuring the actual value you also need knowledge about the behavior of your system: e.g. If you change the PWM value from 50 to 100, how much and how quick will the motor speed change? Even the response form over time will affect the optimal parameters for your control loop. It's called (feedback) loop because any change of the PWM value will change that difference and lead to a different new value of the controlling PWM value again (Allowing for instable behavior in case of bad controlling parameters).

Getting the actual value is your first task. How your `distancefonction` affects the desired value (set point) might also need more clarification...


message:
Arduino Nano/Uno and js sketch compiling/uploading from browser

I need to compile generated source code in js runtime then upload it to my device.

### Compiling:

I have found [arduino-cli][1]

### Uploading:

There is only [avrgirl][2] but it doesn't work in browser. What should I do?

  [1]: https://github.com/arduino/arduino-cli
  [2]: https://github.com/noopkat/avrgirl-arduino

body: You can't, and that's a good thing. If the browser could let a Web site access your hardware, that would be a huge security breach. You may be able to bypass this security restriction if you can write an extension (plugin) for your browser.


message:
Driving an enable pin low via arduino

I have the following V regulator, that has an enable pin that i'd like to control via an arduino:  https://www.pololu.com/product/2582

I tried using a relay (ELEGOO Relay Module 4 Channel DC 5V with Optocoupler for Arduino) with the following pins:

Relay pin1: 0v of 24v battery
--
Relay pin2: enable pin of pololu v regulator
--
I then enabled the above relay via an arduino digital out pin.

However it seemed to have no effect, the regulator never shut off.
If i manually join the two relay pins, pin1 and pin2 the regulator does shut off though ..  A and B in picture.

Any ideas why the relay is not working via the arduino?  or should it work? am i doing something wrong?  I am not too familiar with pull up or pull downs..

I have since disconnected everything and put it away, i am just looking for theory help, confirmation it should wotk.   I managed to get the relay working for leds at the time .. would the fact that current flows in the other direction for this pull down relay setup, be my issue and that i should swap around wires A and B?

(As a workaround i used a relay to switch on or enable the 24v Vin line out from the battery instead, that seemed to work okay..)![enter image description here](https://i.stack.imgur.com/Z4lSv.jpg)

body:
Unless you require galvanic isolation (and it's highly unlikely that you do) you don't need the relay.

The EN pin only needs to be above 1.3V to turn the unit on, or below 0.9V to turn it off. The voltage range is anything up to 30V.

Just connect the EN pin directly to an Arduino IO pin. Write a HIGH for on and a LOW for off.  And of course connect the grounds together.


message:
How to set an array size to a variable which might change later into the code?

I'm trying to initialize an array globally which could be of different sizes according to future code in Arduino. `
int n=0;
int val[n];
`This says that the array bound is not an integer constant before ']' token. This also says that the val variable wasn't declared.

I have browsed other forms and have been told to use dynamic storage usage which I don't know how to use.

I'm trying to store different weight values respective to time in a variable. I first tried to store the weight in one variable but couldn't find the total weight etc.

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

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

body:
The Arduino platform uses a C / C++ compiler.  In C++ one can use features such as [Vectors][1] to create what appear as arrays of varying sizes.  However, it is likely memory is wasted when trying to abstract the memory usage from the application in this way.  In an embedded environment, memory is likely at a premium.  Consequently, it is almost always better to handle array sizes in embedded situations by allocating the expected amount manually at the beginning of the program.

Tip: If the size of the array depends on the situation the application is used in and there are advantages of smaller verses larger arrays depending on the application, try using [Conditional Compiling][2] to create different versions of the application.

  [1]: https://www.geeksforgeeks.org/vector-in-cpp-stl/
  [2]: http://ee.hawaii.edu/~tep/EE160/Book/chap3/subsection2.1.3.4.html


body:
In general arrays declared like

    int array[n];

needs a constant size `n`, so that the correct memory size can be allocated at the time of declaration. Otherwise the compiler doesn't know what to do with that variable. You cannot change the size of an array, especially not by simply assigning values to non-existent elements. To create a new array with a size unknown at compile time, you would need to use dynamic allocation:

    int *array = new int[n];

The variable `array` is actually not the array itself, but a pointer to an integer array. The compiler will create the pointer variable, which will only hold an address, where the new dynamically created array is stored. With the `new` keyword we are allocating a new memory space. With `int[n]` we are telling the program to allocate space for `n` integers. You can create arrays with sizes unknown at compile time, but you cannot change the size of an array. You would need to create a new one to change size. Dynamically allocated storage, that is not needed anymore should be freed. (You can google more about this)

**BUT: On an Arduino you should not use dynamic allocation.** If you use the dynamic allocation too much (over and over again) in a program, you will get memory fragmentation. As you allocate and free memory of different sizes, you will get many small memory spaces, which are too small to hold your new arrays. So this memory is now useless and Arduinos only have very little RAM to use for dynamic memory. When your RAM is full, your program will crash. Real computers - in contrast - have loads of memory, so that is not a problem there.

It is better to allocate your memory statically, with enough space to handle your biggest expected amount of data. So you should really think about, if you really need dynamic allocation. I would say no.

---

There are also other problems with your code.

- You use the following for loop:

        for(n = 0; isFinished = true; n++)

    A single `=` marks an assignment. So at the start of every for loop iteration you are assigning `true` to `isFinished`. And every assignment will evaluate as true. So you have an infinite loop there. If you want to check for equality, you need to use `==` (double equal sign). Also in that for loop `isFinished` newer changes. You initialize it with `false`, so the loop will not run once. If you instead check for it to be `false` the loop  will be infinite, since there is no possibility, that this variable changes inside the loop. Instead use `n` for the loop condition and run the loop as many times as you have elements in your array.

- Generally your logic seems not well thought through. You are already using a for loop to measure multiple values, so why don't you just directly measure as many values, as you want to measure, by using the for loop as described above. Then you don't need all the `isFinished` stuff, because you will always have all the needed values, when you exit the for loop. So you also don't need to check, if there are enough values measured. And it is not clear, what the threshold check should do.


body:
As others have suggested, dynamically allocated memory is often problematic on a memory-starved device like an Arduino. As you create and release memory, the "heap" (a pool of memory to be used for that purpose) gets broken up into "islands" of free memory with still-used blocks of memory peppered throughout.

In fairly short order you wind up with your available memory pretty much unusable, your app runs out of available memory, and your app crashes.

This is known as "heap fragmentation". When you only have a couple of K of RAM to work with, it quickly becomes fatal.

If you can be sure that you allocate a dynamic buffer in a function call sequence, don't do any other dynamic memory allocation, and then free it before returning, you can probably get away with it without fragmentation, but you really have to be careful.

If you instead dynamically allocate a block of memory very early in your app's life and then keep it for the entire run that can be okay too. That block takes a chunk of your heap and just stays there.

A third alternative is to allocate a statically sized array at compile time that's big enough for your largest use, and treat that as a buffer. You can save contents there as needed, then when you're done with those contents, use the buffer for something else.


message:
Arduino ultrasonic sensor weird output

So I just got into arduino and bought Elegoo's car robot v3 kit and built it, but when I put the robot on "object avoidance" it constantly spins as though there is an object in front of it. I tried changing the code and had no luck so I thought maybe it was the sensor itself, when I hooked it up and ran:

    void loop() {
       a=sr04.Distance();
       Serial.print(a);
       Serial.println("cm");
       delay(1000);
    }

it displayed the correct distances so I figured it could not be the sensor. The curious thing happened when I added a few lines to the car's code to also make it print the distance it was seeing, and when the sensor is hooked up to the car for whatever reason all it sees is 18cm no matter the actual distance, which explains why it is constantly spinning. I have found the problem, but now my issue is that for the life of me I cannot figure out why it detects only 18cm constantly when hooked to the car.

    #include <SR04.h>

    /*
     * @Description: Rocker_Control
     * @Author: HOU Changhua
     * @Date: 2019-08-12 18:00:25
     * @LastEditTime: 2019-08-27 10:45:29
     * @LastEditors: Please set LastEditors
     */
    #include <Servo.h>
    #include <stdio.h>
    #include "HardwareSerial.h"
    #include "ArduinoJson-v6.11.1.h" //ArduinoJson

    /*Driving Interface for Ultrasound Ranging*/
    #define ECHO_PIN A4
    #define TRIG_PIN A5

    /*Motor Drive Interface*/
    #define ENA 5
    #define ENB 6
    #define IN1 7
    #define IN2 8
    #define IN3 9
    #define IN4 11

    /*Driving Interface for Infrared Pipeline Patrol*/
    #define LineTeacking_Pin_Right 10
    #define LineTeacking_Pin_Middle 4
    #define LineTeacking_Pin_Left 2
    #define LineTeacking_Read_Right !digitalRead(10)
    #define LineTeacking_Read_Middle !digitalRead(4)
    #define LineTeacking_Read_Left !digitalRead(2)

    #define carSpeed 180 //PWM(That is: motor speed/vehicle speed)

    Servo servo;
    unsigned long IR_PreMillis;
    unsigned long LT_PreMillis;

    enum FUNCTIONMODE
    {
      IDLE,
      LineTeacking,
      ObstaclesAvoidance,
      Bluetooth,

    } func_mode = IDLE; /*Functional model*/

    enum MOTIONMODE
    {
      STOP,
      FORWARD,
      BACK,
      LEFT,
      RIGHT
    } mov_mode = STOP; /*Motion model*/

    void delays(unsigned long t)
    {

      for (unsigned long i = 0; i < t; i++)
      {
        getBTData_Plus();
        delay(1);
      }
    }

    /*Acquisition Distance: Ultrasound*/
    unsigned int getDistance(void)
    {
      static unsigned int tempda = 0;
      unsigned int tempda_x = 0;
      digitalWrite(TRIG_PIN, LOW);
      delayMicroseconds(2);
      digitalWrite(TRIG_PIN, HIGH);
      delayMicroseconds(10);
      digitalWrite(TRIG_PIN, LOW);
      tempda_x = ((unsigned int)pulseIn(ECHO_PIN, HIGH) / 58);
      if (tempda_x < 150)
      {
        tempda = tempda_x;
      }
      else
      {
        tempda = 30;
      }
      return tempda;
    }
    /*Control motor: */
    void forward(bool debug, int16_t in_carSpeed)
    {

      analogWrite(ENA, in_carSpeed);
      analogWrite(ENB, in_carSpeed);
      digitalWrite(IN1, HIGH);
      digitalWrite(IN2, LOW);
      digitalWrite(IN3, LOW);
      digitalWrite(IN4, HIGH);
      if (debug)
        Serial.println("Go forward!");
    }

    /*Control motor: */
    void back(bool debug, int16_t in_carSpeed)
    {

      analogWrite(ENA, in_carSpeed);
      analogWrite(ENB, in_carSpeed);
      digitalWrite(IN1, LOW);
      digitalWrite(IN2, HIGH);
      digitalWrite(IN3, HIGH);
      digitalWrite(IN4, LOW);
      if (debug)
        Serial.println("Go back!");
    }
    /*Control motor:*/
    void left(bool debug, int16_t in_carSpeed)
    {
      analogWrite(ENA, 250);
      analogWrite(ENB, 250);
      digitalWrite(IN1, LOW);
      digitalWrite(IN2, HIGH);

      digitalWrite(IN3, LOW);
      digitalWrite(IN4, HIGH);
      if (debug)
        Serial.println("Go left!");
    }
    /*Control motor:*/
    void right(bool debug, int16_t in_carSpeed)
    {
      analogWrite(ENA, 250);
      analogWrite(ENB, 250);
      digitalWrite(IN1, HIGH);
      digitalWrite(IN2, LOW);
      digitalWrite(IN3, HIGH);
      digitalWrite(IN4, LOW);
      if (debug)
        Serial.println("Go right!");
    }
    /*Control motor:*/
    void stop(bool debug = false)
    {
      digitalWrite(ENA, LOW);
      digitalWrite(ENB, LOW);
      if (debug)
        Serial.println("Stop!");
    }
    /*
      Bluetooth serial port data acquisition and control command parsing
    */
    void getBTData_Plus(void)
    {
      String comdata = "";

      while ((Serial.available() > 0) && (false == comdata.endsWith("}")))
      {
        comdata += char(Serial.read());
        delay(3);
      }
      if ((comdata.length() > 0) && (comdata != "") && (true == comdata.endsWith("}")))
      {
        StaticJsonDocument<200> doc;                                //Create a JsonDocument object
        DeserializationError error = deserializeJson(doc, comdata); //Deserialize JSON data
        if (!error)                                                 //Check if deserialization is successful
        {
          int control_mode_N = doc["N"];
          char buf[3];
          uint8_t temp = doc["H"];
          sprintf(buf, "%d", temp);
          String CommandSerialNumber = buf; //Get the serial number of the new command

          switch (control_mode_N)
          {
          case 5: /*Clear mode  processing <command：N 5>*/
            func_mode = Bluetooth;
            mov_mode = STOP;
            Serial.print('{' + CommandSerialNumber + "_ok}");
            break;
          case 3:               /*Remote switching mode  processing <command：N 3>*/
            if (1 == doc["D1"]) // Line Teacking Mode
            {
              func_mode = LineTeacking;
              Serial.print('{' + CommandSerialNumber + "_ok}");
            }
            else if (2 == doc["D1"]) //Obstacles Avoidance Mode
            {
              func_mode = ObstaclesAvoidance;
              Serial.print('{' + CommandSerialNumber + "_ok}");
            }
            break;
          case 2: /*Remote switching mode  processing <command：N 2>*/

            if (1 == doc["D1"])
            {
              func_mode = Bluetooth;
              mov_mode = LEFT;
              Serial.print('{' + CommandSerialNumber + "_ok}");
            }
            else if (2 == doc["D1"])
            {
              func_mode = Bluetooth;
              mov_mode = RIGHT;
              Serial.print('{' + CommandSerialNumber + "_ok}");
            }
            else if (3 == doc["D1"])
            {
              func_mode = Bluetooth;
              mov_mode = FORWARD;
              Serial.print('{' + CommandSerialNumber + "_ok}");
            }
            else if (4 == doc["D1"])
            {
              func_mode = Bluetooth;
              mov_mode = BACK;
              Serial.print('{' + CommandSerialNumber + "_ok}");
            }
            else if (5 == doc["D1"])
            {
              func_mode = Bluetooth;
              mov_mode = STOP;
              Serial.print('{' + CommandSerialNumber + "_ok}");
            }
            break;
          default:
            break;
          }
        }
      }
    }

    /*Bluetooth remote control mode*/
    void bluetooth_mode()
    {
      if (func_mode == Bluetooth)
      {
        switch (mov_mode)
        {
        case FORWARD:
          forward(false, carSpeed);
          break;
        case BACK:
          back(false, carSpeed);
          break;
        case LEFT:
          left(false, carSpeed);
          break;
        case RIGHT:
          right(false, carSpeed);
          break;
        case STOP:
          stop();
          break;
        default:
          break;
        }
      }
    }
    /*
      Line Teacking Mode
    */
    void line_teacking_mode(void)
    {
      if (func_mode == LineTeacking)
      {
        if (LineTeacking_Read_Middle)
        {                           //Detecting in the middle infrared tube
          forward(false, carSpeed); //Control motor：the car moving forward
          LT_PreMillis = millis();
        }
        else if (LineTeacking_Read_Right)
        {                         //Detecting in the right infrared tube
          right(false, carSpeed); //Control motor：the car moving right
          while (LineTeacking_Read_Right)
          {
            getBTData_Plus(); //Bluetooth data acquisition
          }
          LT_PreMillis = millis();
        }
        else if (LineTeacking_Read_Left)
        {                        //Detecting in the left infrared tube
          left(false, carSpeed); //Control motor：the car moving left
          while (LineTeacking_Read_Left)
          {
            getBTData_Plus(); //Bluetooth data acquisition
          }
          LT_PreMillis = millis();
        }
        else
        {
          if (millis() - LT_PreMillis > 150)
          {
            stop(); //Stop motor control：Turn off motor drive mode
          }
        }
      }
    }
    /*f(x) int */
    static boolean function_xxx(long xd, long sd, long ed) //f(x)
    {
      if (sd <= xd && xd <= ed)
        return true;
      else
        return false;
    }
    /*Obstacle avoidance*/
    void obstacles_avoidance_mode(void)
    {
      static uint16_t ULTRASONIC_Get = 0;
      static unsigned long ULTRASONIC_time = 0;
      static boolean stateCar = false;
      static boolean CarED = false;
      static uint8_t switc_ctrl = 0x00;
      static boolean timestamp = true;
       Serial.print(A4);
       Serial.println("cm");
       delay(1000);

      if (func_mode == ObstaclesAvoidance)
      {
        servo.attach(3);
        if (millis() - ULTRASONIC_time > 100)
        {
          ULTRASONIC_Get = getDistance(); //Measuring obstacle distance
          ULTRASONIC_time = millis();
          if (function_xxx(ULTRASONIC_Get, 0, 30)) //If the distance is less than Xcm obstacles
          {
            stateCar = true;
            stop(); //stop
          }
          else
          {
            stateCar = false;
          }
        }
        if (false == CarED)
        {
          if (stateCar == true)
          {
            timestamp = true;
            CarED = true;
            switc_ctrl = 0x00;
            stop();          //stop
            servo.write(30); //sets the servo position according to the  value
            delays(500);
            if (function_xxx(getDistance(), 0, 25)) //How many cm in the front have obstacles?
            {
              switc_ctrl |= 0x01;
              //goto
            }
            else
            {
              switc_ctrl &= (~0x01);
            }
            servo.write(150); //sets the servo position according to the  value
            delays(500);
            if (function_xxx(getDistance(), 0, 25)) //How many cm in the front have obstacles?
            {
              switc_ctrl |= 0x02;
              //goto
            }
            else
            {
              switc_ctrl &= (~0x02);
            }
            servo.write(90); //tell servo to go to position in variable 30
            delays(500);
            if (function_xxx(getDistance(), 0, 25)) //How many cm in the front have obstacles?
            {
              switc_ctrl |= 0x04;
              //goto
            }
            else
            {
              switc_ctrl &= (~0x04);
            }
          }
          else
          {
            forward(false, 180); //Control motor：the car moving forwar
            CarED = false;
          }
        }

        if (true == CarED)
        {
          // Get cpu time
          static unsigned long MotorRL_time;
          if (timestamp == true || millis() - MotorRL_time > 420)
          {
            timestamp = false;
            MotorRL_time = millis();
          }
          if (function_xxx((millis() - MotorRL_time), 0, 400))
          {
            switch (switc_ctrl)
            {
            case 0 ... 1:
              left(false, 150); //Control motor：The car moves forward and left
              break;
            case 2:
              right(false, 150); //Control motor：The car moves forward and right
              break;
            case 3:
              forward(false, 150); //Control motor：the car moving forwar
              break;
            case 4 ... 5:
              left(false, 150); //Control motor：The car moves forward and left
              break;
            case 6:
              right(false, 100); //Control motor：The car moves forward and right
              break;
            case 7:
              back(false, 150); //Control motor：Car backwards
              break;
            }
          }
          else
          {
            CarED = false;
          }
        }
      }
      else
      {
        servo.detach();
        ULTRASONIC_Get = 0;
        ULTRASONIC_time = 0;
      }
    }
    void setup(void)
    {
      Serial.begin(9600);         //initialization
      servo.attach(3, 500, 2400); //500: 0 degree  2400: 180 degree
      servo.write(90);            //sets the servo position according to the 90（middle）

      pinMode(ECHO_PIN, INPUT); //Ultrasonic module initialization
      pinMode(TRIG_PIN, OUTPUT);

      pinMode(IN1, OUTPUT); //Motor-driven port configuration
      pinMode(IN2, OUTPUT);
      pinMode(IN3, OUTPUT);
      pinMode(IN4, OUTPUT);
      pinMode(ENA, OUTPUT);
      pinMode(ENB, OUTPUT);

      pinMode(LineTeacking_Pin_Right, INPUT); //Infrared tracking module port configuration
      pinMode(LineTeacking_Pin_Middle, INPUT);
      pinMode(LineTeacking_Pin_Left, INPUT);
    }

    void loop(void)
    {
      getBTData_Plus();           //Bluetooth data acquisition
      bluetooth_mode();           //Bluetooth remote mode
      line_teacking_mode();       //Line Teacking Mode
      obstacles_avoidance_mode(); //Obstacles Avoidance Mode
    }

New Debug:

    /*Acquisition Distance: Ultrasound*/
    unsigned int getDistance(void)
    {
      static unsigned int tempda = 0;
      unsigned int tempda_x = 0;
      digitalWrite(TRIG_PIN, LOW);
      delayMicroseconds(2);
      digitalWrite(TRIG_PIN, HIGH);
      delayMicroseconds(10);
      digitalWrite(TRIG_PIN, LOW);
      tempda_x = ((unsigned int)pulseIn(ECHO_PIN, HIGH) / 58);
      if (tempda_x < 150)
      {
        tempda = tempda_x;
      }
      else
      {
        tempda = 30;
      }
      Serial.print(tempda);
      Serial.println("cm");
      delay(1000);
      return tempda;
    }

body:
`Serial.print(A4)` makes no sense, that just directly reads the GPIO pin (0 or 1). Maybe that statement is actually messing up the configuration of the GPIO and messing up the distance measurement.
You need to use the `getDistance()` function. For debugging, try printing the tempda return value just before the return statement. You still might need to convert that echo timing to cm distance though.


body:
I'm using ultrasonic sensor to get the water level in a watertank for my irrigation system. The following piece of code for measuring the distance works fine for me. I'd suggest to replace:

    tempda_x = ((unsigned int)pulseIn(ECHO_PIN, HIGH) / 58);

(BTW what is 58?)
 with the following:

    long duration;
    duration = pulseIn(ECHO_PIN, HIGH);
    tempda_x = duration*0.034029/2;

0.034029 is the speed of sound per second(m/s). And this times the duration it takes sound to get back, divided by 2 gives us the distance from the object.

Hope it helps.


body:
Welcome to the wonderful world of Arduino programming and robotics!

As you have discovered, sometimes the magic doesn't work with the first incantation, so some work is required to get the spell just right ;-).

When troubleshooting a problem with a sophisticated system like the Elegoo kit you have, it helps to drastically simplify things to start with to establish a working baseline, then add complexity incrementally until the problem behavior occurs. Then you can concentrate on the (hopefully) smaller piece of code that caused the problem, without having to wade through lines and lines of irrelevant programming.

It appears that you have started in the right direction with your simple program to display the distance once per second, so you have the right idea.  If you haven't done so already, I suggest you create a completely new Arduino sketch, with just your once/second measurement as the entire program (plus the #include <SR04.h> necessary to access the sensor).  Once you have it running in isolation, then add just the 'obstacles_avoidance_mode(void)' function along with some print statements to instrument the different decision trees of the function.  For instance, I might simplify the function down to something like this:

    void obstacles_avoidance_mode(void)
    {
      static uint16_t ULTRASONIC_Get = 0;
      static unsigned long ULTRASONIC_time = 0;
      ULTRASONIC_Get = getDistance(); //Measuring obstacle distance
      ULTRASONIC_time = millis();
      Serial.print("time = ");Serial.print(ULTRASONIC_time);
      Serial.print(", dist = ");Serial.println(ULTRASONIC_Get);
     }

Then add the required 'getDistance() function to the bottom of your new test program and call 'obstacles_avoidance_mode(void)' once per second.  Once you have that working to your satisfaction, then start adding small pieces of 'obstacles_avoidance_mode(void)' one at a time, along with whatever preconditions are required to force each small section to execute as you cause the sensor's reported distance to change by moving your hand toward and away from the sensor. Don't worry about the motors and/or servos all; you can hook them up later as needed.

By doing this you should very rapidly come to understand how the program is making decisions, without getting bogged down in all the other stuff going on in the full robot code.

Hope this helps,

Frank


message:
Multiple MPU9250 Synced

I am interested in collecting data from 3 MPU9250 via I2C communication protocol. As I've read, I can collect measurements on the same I2C Bus from up to two MPUs. However, how can I collect **Synced** data from more than 2 MPUs.
And if not Arduino what do you recommend?

body:
The MPU uses a FIFO buffer for the data. So the time of measurement is not necessarily the same as the time of communication. Additionally there is the FSYNC pin. In the [MPU9250 datasheet][1] there is nearly nothing described about that pin, only the pin description:

> 11    FSY    Frame  synchronization digital input.  Connect  to GND  if  unused.

I would interpret this as: If you pulse this pin to high (active high), a measurement is started. I cannot garantee, that it works this way; I also only can look into the datasheet. For my answer I will assume, that the pin really works this way. You will have to test this yourself.

Based on that info I would propose the following solution (without being able to try it myself due to the lack of MPU):

Connect 1 Arduino digital output pin to the FSYNC pins of all MPUs. If you pulse this pin from LOW to HIGH (and then to LOW again after a short time to return to the passive state), the MPUs will start their measurements. Since they all get the same start pulse, they will do the measurement at the same time. (It may be, that you need to configure the MPU for this) When the measurement is done, the data will be placed in the FIFO buffer. Then you need to grab this data from all the MPUs over I2C.

Here come a trick, so that you can effective connect to a great number of MPUs: The address pin of the MPU is also checked during operation. This means, that you can change the address of an MPU during operation by connecting it's address pin to a digital output pin of your Arduino. Do this with every used MPU, one output pin for one MPU address pin. On the Arduino you set all the pins to the same output state (let's say LOW) to keep all the MPUs on the same address. You must not ever call this address through I2C. If you want to communicate with one of the MPUs, you output a HIGH at it's address pin. This specific MPU will change it's address, where you can now communicate like normal. When you are done communicating with it, just output LOW again. Now you can activate the next MPU for communication by outputting HIGH on it's corresponding address pin.

This way you have 1 inactive address and 1 active address, where the MPU's being there change based on your digital outputs.

  [1]: https://cdn.sparkfun.com/assets/learn_tutorials/5/5/0/MPU9250REV1.0.pdf


message:
Comparing a text string to text output (DHT22)

Lately I've received a DHT22 sensor. I've started to create a small temperature and humidity monitor station. One of the things I noticed was if you pulled out the sensor while in use, it displayed "nan". What I wanted to do was if the variable "temp" (for the temperature) equaled "nan", my LCD would display a message. But I keep getting a scope, conversion, and declaring errors. I've tried every variable and a lot of online forums, documentations, and the official Arduino reference site. My code looks like this:
<!-- language-all: lang-cpp -->

    #include <Adafruit_Sensor.h>
    #include <DHT.h>
    #include <LiquidCrystal.h>

    const int rs = 53, en = 51, d4 = 49, d5 = 52, d6 = 48, d7 = 47;

    LiquidCrystal lcd(rs, en, d4, d5, d6, d7);

    #define DHTPIN 27
    #define DHTTYPE DHT22
    DHT dht(DHTPIN, DHTTYPE);

    int chk;
    float hum;
    float temp;

    byte bigdot[8] = {
      B00000,
      B00000,
      B00000,
      B01110,
      B01110,
      B01110,
      B00000,
      B00000
    };

    byte circle[8] = {
      B00110,
      B01001,
      B01001,
      B00110,
      B00000,
      B00000,
      B00000,
      B00000
    };

    void setup() {
      lcd.createChar(0, bigdot);
      lcd.createChar(1, circle);
      lcd.begin(16, 2);
      dht.begin();
      do {
      lcd.setCursor(5,1);
      lcd.write(byte(2));
      lcd.setCursor(4,0);
      lcd.print("Loading");
      delay(500);
      lcd.clear();
      lcd.setCursor(7,1);
      lcd.write(byte(2));
      lcd.setCursor(4,0);
      lcd.print("Loading");
      delay(500);
      lcd.clear();
      lcd.setCursor(9,1);
      lcd.write(byte(2));
      lcd.setCursor(4,0);
      lcd.print("Loading");
      delay(500);
      lcd.clear();
      dht.readHumidity();
      dht.readTemperature();
      } while (hum > 90 || temp > 50.00);
      Serial.begin(9600);

    }

    void loop() {
        hum = dht.readHumidity();
        temp = dht.readTemperature();
        lcd.clear();
        lcd.setCursor(0,0);
        lcd.print("Temp: ");
        lcd.print(temp);
        lcd.write(byte(1));
        lcd.print("C");

        lcd.setCursor(0,1);
        lcd.print("RH:   ");
        lcd.print(hum);
        lcd.print("%");

        if (temp == a) {
          lcd.clear();
          lcd.home();
          lcd.print("Whoops! An");
          lcd.setCursor(0,1);
          lcd.print("error occured!");
        };
        Serial.print("Humidity: ");
        Serial.print(hum);
        Serial.print(" %, Temp: ");
        Serial.print(temp);
        Serial.println(" Celsius");
        delay(2000); //Delay 2 sec.
     }

Thanks in advance!

body:
A "float" number has multiple possible states, besides just being a number (It never, though, can be compared to a string):

* A real floating point number
* Infinity
* Something that isn't a valid number

The latter is what you want - that is, the internal data of the float variable doesn't represent a valid number.

There are two functions in the standard math library that deal with this for you.

* Is the number infinity? [`ininf(x)`](https://en.cppreference.com/w/c/numeric/math/isinf)
* Is the number invalid? [`isnan(x)`](https://en.cppreference.com/w/c/numeric/math/isnan)

To use it:

    if (isnan(temp)) {
        lcd.print("Invalid");
    }


message:
ESP32 CAM failed to get frame in time

So I think the title says it all. I recently purchased an ESP32 CAM in India for a pretty cheap price.

It looks like an AI Thinker but doesn’t have the tag on the chip itself. Nonetheless, to get it setup before my use case I decided to test the camera. I loaded up the CameraWebServer example and set my camera type to AI thinker.

The code uploads successfully and runs successfully. I can open up the IP address and it shows the page. However whenever I try to get a still or start a stream, it gives this error:

    [E][camera.c:1344] esp_camera_fb_get(): Failed to get the frame on time!
    Camera capture failed

It’s pretty annoying and this happens in both 5V power and 3V power. The camera does physically get a bit hot after loading the website. Oh yeah, I have an OV 2460 Camera attached to the ESP.

Any advice is appreciated. Thanks!

body:
I had tried and tried to get the camera working. However, I decided to concede to the part of me that thought it was a hardware error. I purchased a new OV2640 module and instantly it worked.

I think I learned my lesson in purchasing cheap components. I inspected the old one further. Turns out there was a faulty ribbon cable. Anyways, I hope you aren’t in this situation. Seems like the only solution is to purchase new hardware, and the current issue is faulty hardware.


body:
One possible cause is given here (scroll down to find this specific issue)
https://randomnerdtutorials.com/esp32-cam-troubleshooting-guide/

There appear to be two sets of ESP-32-CAMs, one with and one without the PSRAM.


body:
Solution for if this occurs on a known working ESP-32-cam with PSRAM (i.e. example sketch with face recognition works ok).
If you're using anything other than `PIX_FORMAT_JPEG`, try reducing `xclk_freq_hz`.
In my case, it suddenly worked fine with `PIX_FORMAT_RGB888`, `FRAMESIZE_VGA` and `xclk_freq_hz = 5000000` (4x lower).

( @Vraj P, this might not apply directly to what you found your problem was, but this post gets seen by many searching for this problem. Thanks!).


body: Look I've just had that problem for a month and if you're using esp32- ov2640 look the camera reference because the one I've had was TY 0V2640-V2.0 and what I've saw it's like a cheap copy of the normal camera, so be careful. I had to buy a new one because everything looked like a broken image, although all the config worked fine. Even changing the `PIX_FORMAT` and `xclk_freq_hz` didn't work. The camera was the problem.


body:
This stung me too. I found increasing the frame buffer count helped.

```
camera_config_t config;
config.fb_count = 10;  // Or some other number
```


message:
data classification with arduino

I want to classify my data from 3 sensors with arduino so that every time i enter the specific date or hour, or also it can be a period of time like 10 days ago, it shows me the exact data. In other word i want to classify my data so that whenever i want every detail of data, i would be able to get it by entering the information of year,date,time. I also didn't want my data to be in separate files and time stamps. I want to be able to do that within one file and search inside that file...

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

    RTC_DS1307 rtc;
    const int chipSelect = 10;

    File dataFile;

    String print_time(DateTime timestamp) {
      char message[120];

      int Year = timestamp.year();
      int Month = timestamp.month();
      int Day = timestamp.day();
      int Hour = timestamp.hour();
    int Minute = timestamp.minute();
          int Second= timestamp.second();

          sprintf(message, "%d-%d-%d d:d:d", Month,Day,Year,Hour,Minute,Second);

          return message;
        }

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

          pinMode(chipSelect, OUTPUT);
          if (!SD.begin(chipSelect)){
            Serial.println("Error: SD card would not initiate.");
          }

          rtc.begin();
          if (!rtc.isrunning()){
            Serial.println("Clock is not running");
          }

          dataFile = SD.open("log0.csv", FILE_WRITE);
          if (!dataFile){
            Serial.println("Could not open file.");
          }

        }

        void loop(){
          Datetime now = rtc.now();
          dataFile.println(print_time(now));

          delay(3000);
        }

body:
1. Create a single file (SD logger?)
2. When data is received from a sensor, store it in the file, and store this information:
   1. Date/Time stamp
   2. Which sensor
   3. Sensor data
3. When a request for data is received (probably containing start and end time stamps, parse through the file, and start returning information for those date/time stamps within the requested start/end time stamps.

If step 3 takes too long (and results in missing new sensor measurements), you have to do the read in smaller steps between the reading of sensors.


body:
If you plan to continuously take data at a fixed rate, I suggest you
don't timestamp the individual records. Instead, store the initial
timestamp and the data sampling period in a binary header, followed by
fixed-size binary records. Then, when you want to retrieve the record
for time `t`, you can `fseek()` right to

```c++
uint32_t offset = header_size
                + record_size * (t - initial_time) / sampling_period;
```

If there is a slight chance that you may fail to record some data
points, you may want to have a boolean in each record that tells whether
the data is valid. You can then fill the missing data with invalid
records.

If your Arduino is likely to be turned on and off unpredictably, then
timestamping every record may be a better option, but finding a specific
record will likely be very slow.


message:
Need advice on serial bytes reading optimization

I am doing some device serial data read and publishing values to MQTT. Using ESP8266 for this.

Currenty I request serial device by sending a command and parse all byte values individually, how to do this in better way ?

each byte parse is done in such way:

```
float Heat = (float)data[38];

  sprintf(mqtt_topic, "%s/%s", mqtt_topic_base, "Temp"); mqtt_client.publish(mqtt_topic, String(Temp).c_str());

float Power = (float)data[39];
......
..... and etc...
```

body:
In principle it is ok to use your way, but a simple improvement is to change the magic numbers (38, 39) to constants or define:

    const int offset_heat = 38;

    …

    float Heat = (float)data[offset_heat];

or a define:

    #define OFFSET_HEAT 38

    …

    float Heat = (float)data[OFFSET_HEAT];

If all values are consecutive you can keep a variable to read the values:

    int offset = 38; // Normally starts at 0 assuming you read values from the start

    float heat = (float) readByte(&offset);

    …

    int readByte(uint8_t* offset)
    {
        int value = data[*offset];
        (*offset)++;
        return value;
    }

This increases the offset after reading the value.

Some remarks:

- It's a convention not to use capitals for local variables (so change Heat to heat)
- You don't use the Heat variable in `sprintf`, maybe this is intentional.


message:
Locating a fault in writing a variable

I'm writing this piece of code for Arduino Uno, which takes in input on pin 2 the value of a PIR sensor. In order to debug, in this moment I'm taking the signal on pin 2 from the 5V power supply:

    int inputPinSensor1 = 2; // input pin for sensor 1
    int sensor_1_State = LOW; // we start assuming no motion detected for sensor 1
    int val = 0; // variable for reading the pin status

    void setup() {
      pinMode(inputPinSensor1, INPUT); // declare sensor 1 pin as input

      Serial.begin(9600);
    }

    void loop(){
      detectChange(&inputPinSensor1, &sensor_1_State);
    }

    void detectChange(int* inputPin, int* pirState) {
      // read input value
      val = digitalRead(*inputPin);
      // check if the input is HIGH
      if (val == HIGH) {
        if (*pirState == LOW) {
          // we have just turned on
          Serial.println("Current detected");
          *pirState = HIGH;
        }
      } else {
        if (*pirState == HIGH){
          // we have just turned off
          Serial.println("Current ended");
          *pirState = LOW;
        }
      }
    }

This code should detect the passage from a LOW value to an HIGH value on pin 2, and vice versa. In this way I'm expecting to have an HIGH value on pin 2 when I connect the jumper and a LOW value when I disconnect the jumper. But what I get is two possible behaviors: sometimes I get "Current detected" at the begin of the execution, after which there are no further messages, and sometimes I get a rapid alternation of "Current detected" and "Current ended".

body:
As Majenko says in their comments, a pin that's not connected to anything "floats" and gives unpredictable results.

You either need to connect such a pin to ground through a "pull-down" resistor or to +5V through a "pull-up" resistor. (10KΩ is a good value to start with.)

If you connect the pin to +5V through a pull-up resistor then you would ground it to change it's state. In that case the pin reads HIGH normally, and drops to LOW when triggered. Note that the Arduino has a special mode, INPUT_PULLUP, that connects the pin to an internal pull-up resistor. In that case you don't need an external pull-up resistor.

In your case, connect the pin to ground with a 10KΩ restistor. Then when you want the pin to go high attach the pin to +5V. That will swamp the connection to ground and pull the pin up to just below 5V.


message:
Error: function was not declared in this scope when using a library without classes

I have created a library of functions that doesn't have and mustn't have a class. In order to have functions inside the library that can only be called from the library itself, you just write them into the .cpp file and leave them out of the header file completely. Here is the .cpp file of the library (the header file is empty):

```c++
#include "Lib.h"

// Definition of foo1
static void foo1(){
 foo2();
}

// Definition of foo2
static void foo2() {}
```

When including the library in an empty sketch and compiling it I get the following error message:

>error: 'foo2' was not declared in this scope

What is the problem here?

body:
When creating a library with functions that are not mentioned in the header file, the order of appearence in the .cpp file suddenly becomes relevant. In order for a function to be used by another function, it has to be declared first.

The first possibility in this example would be to define `foo2` before defining `foo1` like this:

```c++
#include "Lib.h"

// Definition of foo2
static void foo2() {}

// Definition of foo1
static void foo1(){
 foo2();
}
```

However, this is not only bad practice, it also doesn't always work. If there is any sort of recursive procedure that makes functions call each other, you can't define both of them before the respective other at the same time.

The more elegant and foolproof way to do this is by **declaring** each function first like you usually would in the header file and then defining what they actually do. The .cpp file of this library would then look like this:

```c++
#include "Lib.h"

static void foo1(); // Declaration of foo1
static void foo2(); // Declaration of foo2

// Definition of foo1
void foo1(){
 foo2();
}

// Definition of foo2
void foo2() {}
```


message:
Seeing consistent serial data loss over USB, have ruled out hardware and rx/tx software. What's left?

I have a [Lasersaur][1], which is an arduino-based open-source laser cutter. Part of its capabilities is raster engraving, where you etch images based on pixel data, rather than vector data. Recently I started experiencing a weird issue where I am losing some of the data that I am sending over serial to the machine, and the end of the image gets cut off. I don't believe those details are relevant to this question, [but you can read my posts here for more info][2].

Basically, on my old Laptop B, engraving works. If I use the exact same USB hardware connection, firmware, frontend software executable, engraving settings, and image file on my current Laptop A, I see bad results. The last ~20 pixels or so of each image line are not etched in, and the only reason I can think for this is that the color data for these pixels were not sent in the first place. Notably, Laptop A used to work a few months ago when I last tried this out. So I'm pretty confident that I've ruled out hardware and rx/tx software as the possible issues.

The only difference between the two machines that I can think of that has changed since then is that I installed the Windows 10 1909 update, as well as some other software that I would have to dig back through to list out. I'd really like to not do a fresh Windows reinstall on my primary machine, but I'm close to that point.

Could something there be causing an issue? I'm out of my depth at this point, and don't know how either the operating system or another program could be affecting serial data transfer, and wouldn't know the first way to narrow it down.

Some more thoughts which may or may not be important:

* There does not seem to be data corruption, only data loss. The rx/tx protocol implements some error detection (sends every byte twice and checks for equality), and I am not seeing error corruption messages that would pop out if that were the case.
* There does not seem to be any randomness. The same behavior happens for images of different widths (leading me to think that the tx buffer isn't filling up), is the same for each image line, and has always been consistent.
* The Arduino in the machine is an Arduino Uno R3. Compilation is done using the Arduino compiler on some custom C code (not though the IDE).

  [1]: https://www.lasersaur.com/
  [2]: https://groups.google.com/d/msg/lasersaur/00z26IPWt-g/xD4fWeHtBAAJ

body:
The driver board for your "Lasersaur" appears to be based around the Adafruit Trinket Pro.

That board, on Adafruit's website, is deprecated, with the following warning:

> Deprecation Warning: The Pro Trinket bit-bang USB technique it uses doesn't work as well as it did in 2014, many modern computers won't work well. So while we still carry the Pro Trinket so that people can maintain some older projets, we no longer recommend it.

So basically the USB interface is naff. It's too slow to keep up with modern computers (hence your old laptop works but your new one doesn't), and you lose data.

You should look into the possibility of upgrading the controller board to something a little more modern and capable.

----

For UNO R3 based boards there is another fundamental flaw: there is a 64 byte receive buffer *and no flow control*.  That means if you send data too fast - faster than the board can process it - data will be lost.


body:
Well, I was able to resolve it, but I’m not sure how. After going through the steps I’ve outlined in my replies to answers here, I tried buying a new Arduino Uno R3, but that didn’t fix anything either. My last step was to do a Windows “Reset” which reinstalls Windows while keeping files but resets settings and programs. After reinstalling and adding back in all the programs I originally had, the serial communication worked again. I really don’t have a good explanation as to why this worked, but at least it did.

Edit: This problem reappeared, and the windows reset did not fix the issue this time.


body:
I have solved the bug, you can see [the writeup][1] on the Lasersaur google group. The short of it was that this was a software bug, which was only being triggered when the hardware conspired to have some timing delays. I'm still unclear why the behavior was inconsistent previously - I must have been on the borderline of the data delays causing an issue or not.

  [1]: https://groups.google.com/g/lasersaur/c/00z26IPWt-g/m/fbyDIQFPBgAJ


message:
Cannot write to HID USB device (Arduino, V-USB, HidSharp)

I am currently prototyping an HID USB device using Arduino Nano and V-USB library. The problem is that although I can read from the device I cannot write to it.
Here is the schema:
[![Schema][1]][1]
As for the firmware I'm using the [hid-serial][2] library.
Here is the Arduino code:
```
#include <HIDSerial.h>

HIDSerial serial;

unsigned char buffer[32];

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

void loop() {
  if(serial.available()) {
    int size = serial.read(buffer);
    if (size!=0) {
      serial.write((const uint8_t*)buffer, size);
      serial.write('\n');
    }
  }
  serial.poll();
}
```
Here is the HID report descriptor:
```
    0x06, 0x00, 0xff,              // USAGE_PAGE (Generic Desktop)
    0x09, 0x01,                    // USAGE (Vendor Usage 1)
    0xa1, 0x01,                    // COLLECTION (Application)
    0x15, 0x00,                    //   LOGICAL_MINIMUM (0)
    0x26, 0xff, 0x00,              //   LOGICAL_MAXIMUM (255)
    0x75, 0x08,                    //   REPORT_SIZE (8)
    0x95, 0x08,                    //   REPORT_COUNT (8)
    0x09, 0x00,                    //   USAGE (Undefined)
    0x82, 0x02, 0x01,              //   INPUT (Data,Var,Abs,Buf)
    0x95, HIDSERIAL_INBUFFER_SIZE, //   REPORT_COUNT (32)
    0x09, 0x00,                    //   USAGE (Undefined)
    0xb2, 0x02, 0x01,              //   FEATURE (Data,Var,Abs,Buf)
    0xc0                           // END_COLLECTION
```
And lastly, here is the code running on host (.NET/C# using HidSharp library):
```
var devices = DeviceList.Local;
var hidDeviceCollection = devices.GetHidDevices(this.vendorId, this.productId).ToList();
var device = hidDeviceCollection.First();
var stream = device.Open();
var buffer = new byte[9];
buffer[0] = 0;
buffer[1] = 42;
stream.Write(buffer);
buffer = stream.Read();
```
When I run the code above despite stream.CanRead being true I receive an exception "Can't write to this device.". However if I change the code to the "Hello World" example provided by the library I can read from the device without issue.

  [1]: https://i.stack.imgur.com/i2bdv.png
  [2]: https://github.com/rayshobby/hid-serial

body:
Found the error.
While the HidSharp was sending output reports, the device driver expected feature reports.
Changing the line

    0xb2, 0x02, 0x01,              //   FEATURE (Data,Var,Abs,Buf)
to

    0x92, 0x02, 0x01,              //   OUTPUT (Data,Var,Abs,Buf)
resolved the issue.


message:
To update GPS after every 30seconds using NeoGPS and NeoSWSerial Libray

I am using Adafruit Ulitimate Breakout GPS module and NeoGPS and NeoSWSerial Library. Now I want the GPS to update in 30seconds once (1time in 30seconds).After it is updated I want to check the location if new location is equal to old location then it should be updated in 60seconds once(1time in 60seconds).If not the location should be new location. It should display the location every 60seconds.
I tried this flow on Adafruit GPS Library, which works but I want to use NeoGPS library and do the same.
Below is my adafruit library code:

    #include <Adafruit_GPS.h>
    #include <SoftwareSerial.h>

    SoftwareSerial mySerial(11, 10);
    Adafruit_GPS GPS(&mySerial);

    #define GPSECHO  true
    uint32_t timer = millis();
    float old_lat,old_lon,new_lat,new_lon;

    void setup()
    {

      Serial.begin(9600);
      delay(1000);
      Serial.println("Adafruit GPS library basic test!");
      GPS.begin(9600);
      GPS.sendCommand(PMTK_SET_NMEA_OUTPUT_RMCGGA);
      GPS.sendCommand("$PMTK220,30000*1F");
      mySerial.println(PMTK_Q_RELEASE);
    }

    void loop()                     // run over and over again
    {
      char c = GPS.read();
      if (GPS.newNMEAreceived()) {
        //Serial.println(GPS.lastNMEA());   // this also sets the newNMEAreceived() flag to false
        if (!GPS.parse(GPS.lastNMEA()))   // this also sets the newNMEAreceived() flag to false
          return;  // we can fail to parse a sentence in which case we should just wait for another
      }

    if (GPS.fix) {

          old_lat = GPS.latitudeDegrees;
          old_lon = GPS.longitudeDegrees;
          if (timer > millis())  timer = millis();
          if (millis() - timer > 60000) {
            timer = millis();
              Serial.println("Location 1 minute:");
              displaytime();
              new_lat = GPS.latitudeDegrees;
              new_lon = GPS.longitudeDegrees;

              if (new_lat == old_lat){
                new_lat = old_lat;
              }
              else{
                new_lat = GPS.latitudeDegrees;
              }
              Serial.print("Final Latitude: ");
              Serial.println(new_lat,6);

              if (new_lon == old_lon){
                new_lon = old_lon;
              }
              else{
                new_lon = GPS.longitudeDegrees;
              }
              Serial.print("Final Longitude: ");
              Serial.println(new_lon,6);

    }
    }
    }

    void displaytime(){
        Serial.print("\nTime: ");
        if (GPS.hour < 10) { Serial.print('0'); }
        Serial.print(GPS.hour, DEC); Serial.print(':');
        if (GPS.minute < 10) { Serial.print('0'); }
        Serial.print(GPS.minute, DEC); Serial.print(':');
        if (GPS.seconds < 10) { Serial.print('0'); }
        Serial.print(GPS.seconds, DEC); Serial.print('.');
        if (GPS.milliseconds < 10) {
          Serial.print("00");
        } else if (GPS.milliseconds > 9 && GPS.milliseconds < 100) {
          Serial.print("0");
        }
        Serial.println(GPS.milliseconds);
    }

This is my NeoGPS Library code in which I am using NeoSWSerial:

    #include <NMEAGPS.h>
    #include <NeoSWSerial.h>// import the serial library

    NeoSWSerial gpsPort(11, 10); // RX is 11 (to GPS tx), TX is 10 (to GPS rx)
    NMEAGPS gps; // the parser
    gps_fix fix; // the struct with all the parsed values

    void setup() {

      gpsPort.begin(9600);
      Serial.begin(9600);
      Serial.println("GPS Start");
    }

    void loop() {

      if (gps.available( gpsPort)) {
          fix = gps.read();
          Serial.println("Latitude:");
          Serial.println( fix.latitude(), 6);
          Serial.println("Longitude:");
          Serial.println( fix.longitude(), 6);

        }
     }

body:
It seems like using the distance feature in NeoGPS would be a good solution for this problem and it should allow you to create a buffer around the original location to filter some of the noise from the GPS readings.

Here's a page with an overview of using Distance in NeoGPS
https://github.com/SlashDevin/NeoGPS/blob/master/examples/NMEAdistance/NMEAdistance.ino


message:
Unable to declare variable in a library that doesn't have a class: multiple definition of the variable

I have created a library `Lib` that doesn't have a class. I want this library to have a variable that can be accessed from outside. The way I would go about this is to just declare them in the header file.

However, if I do this like so:

```c++
int myVariable = 1;
```

with the `.cpp`-file containing only

```c++
#include "Lib.h"
```

I get this error message when compiling an empty sketch that includes this library:

>multiple definition of `myVariable'

and for some weird reason

>Multiple libraries were found for "Lib.h"

on top of that (although, this is something I have encountered before - when there is some error during the compilation, this error may come alongside it, even though there are no multiple libraries; it goes away when the other compilation errors are resolved aswell).

What is causing that error and how to resolve it?

body:
In Lib.h you should declare an

    extern int myVariable;

In Lib.cpp you can define it once

    #include "Lib.h"
    int myVariable=123;
    ...


body:
If you want a "variable" that is used at compile time, for instance to set the size of an array, then a variable is *not* what you want.

Variables change. That's what "variable" means. If you are using it for something at compile time then it can't be variable, since it must never change.

Ergo, you want either a *constant* or a `#define` macro which is replaced with a *literal*.  Both of these can be done in the header, since they both by default have local TU scope:

    const int myVariable = 123;

Or to use a macro:

    #define SAMPLE_ARRAY_SIZE 123


message:
Can I send data from one MKR1000 to another MKR1000

I want to simply send data from one MKR1000 to the other over wifi, both are connected to the same network, but sending the data is where I get stuck, I've looked through tuts everywhere but can't seem to find an answer.. can someone point me to a solution?

I've set up my devices using the tut https://www.arduino.cc/en/Tutorial/Wifi101WiFiChatServer
but the devices don't communicate to each other they only take telnet from the host server(my laptops wifi hotspot)

body:
WiFiClient object wraps a TCP socket. A normal TCP socket is connected to IP address and port. WiFiServer starts a listening socket on a port. If server on listening socket is contacted by a remote client socket, it creates a local socket connected with the remote client socket on a free port and returns a WiFiClient object wrapping the socket. Everything you write or print to a WiFiClient is send to that one remote socket.

If one of your client boards creates a WiFiClient and connects it to IP address and port of the WiFiServer on your 'server' board, then you get there a WiFiClient from server.available() and this two WiFiClient objects are connected. What you write/print on one side you read only from the WiFiClient object on the other side.

client socket

    if (client.connect(serverIP, PORT)) {
      client.print("request\n");
      String response = client.readStringUntil('\n');
      Serial.println(response);
      client.stop();
    }

server side

    WiFiClient client = server.available();
    if (client && client.connected()) {
      String request = client.readStringUntil('\n');
      Serial.println(request);
      client.print("response\n");
      client.stop();
    }


body:
I found a tutorial that explains exactly what [Majenko] and [Juraj] explained,
https://www.instructables.com/id/MKR1000-IoT-Clientserver-Communications/

the library code that the tutorial references is useful, the tutorial is useful to us learning communication

  [Juraj]: https://arduino.stackexchange.com/users/37622/juraj
  [Majenko]: https://arduino.stackexchange.com/users/4143/majenko


message:
Digispark Attiny85 draws more power for digital input than expected

I'm trying to figure out why my attiny85 (on a digistump developer board) draws around 3mA at 3V when setting up a pin as INPUT and connecting it straight to ground. The current is measured with a multimeter between said pin and ground (thus only the current sunk by that pin is measured). I would assume that without a pullup resistor it would consume a lot less but it seems, regardless if I configure the button as INPUT or INPUT_PULLUP the current is the same.

Sketch:

    void setup() {
      pinMode(3, INPUT);
      //According to datasheet pin needs to be low to disable internal pullup
      digitalWrite(3, LOW);
    }

    void loop() {
      digitalRead(3);
      delay(100);
    }

I would like to design a circuit that can detect a normally closed switch being opened, but the idle power consumption is way to high at the moment. I was planing on using a very high external pullup but it seems I can't disable the internal one...

body:
Input pin only needs 1uA to pull it high or low.

What else is hooked up?

The internal pullup, 30K to 50K, would only draw 0.1mA.

Turn it on and try it, measure the Vcc current with the pin open and then Gnd'ed.


body:
The schematics of the digistump developer board shows that PB3 is connected to +5V over two resistors (1.5 k + 66.5) Ohms. That's the reason for the high current (5V / 1560 Ohm = 0.0032051 A). See the schematics https://s3.amazonaws.com/digistump-resources/files/97a1bb28_DigisparkSchematic.pdf

As you mentioned in a reply on my comment above, using PB2 shows the expected behavior of an AT85 IO pin.


body: I removed the soic IC from board and used it on my own board. I mounted two identical SMT boards, one with a generic chinese pdip and the other with the soic removed, both chips soldered, and I used the same battery supply. The soic from digispark consumed 6 times more current than pdip, in sleep mode: 812uA vs 137uA. I suspect of fake chips. In this base, it is hard to speculate.


message:
DC Motor Control L298N

I am trying to control the speed of two motors using L298N. I use "Arduino Nano ATmega 168". I change the analogWrite between 0-255 but I cannot see any difference. When I assign it to something like 120 the motor stops.

The pwm pins of the motor drive is connected to the 7th and 8th pins of the Arduino. My code is like that:

    const int in1=9; //motor 1
    const int in2=10;//motor 1
    const int in3=11;//motor 2
    const int in4=12;//motor 2
    const int p1=7;//pwm pin for motor 1
    const int p2=8; //pwm pin for motor 2

    void setup() {
      // put your setup code here, to run once:
    pinMode(in1,OUTPUT);
    pinMode(in2,OUTPUT);
    pinMode(in3,OUTPUT);
    pinMode(in4,OUTPUT);
    pinMode(p1,OUTPUT);
    pinMode(p2,OUTPUT);
    }

    void loop() {
      // put your main code here, to run repeatedly:
      analogWrite(p1,255);
      analogWrite(p2,130);
      digitalWrite(in1,HIGH);
      digitalWrite(in2,LOW);
      digitalWrite(in3,HIGH);
      digitalWrite(in4,LOW);

    }

PS:

 - My Arduino and Motor Shield have same the ground

 - I use a power supply and not a battery.

I would be happy if anyone could help me)

body:
const int p1=7;//pwm pin for motor 1

const int p2=8; //pwm pin for motor 2

PWM pins on a '168 are 3,5,6,9,10,11


message:
Useless box wiring and code

just want to give a back story first. So i saw this video on youtube about the useless box, and i thought that it would make a great gift for my 7 year old. So i went out and bought everything that the guy posted in his description box. Just want to say that i am very new to Arduino and how these things work. I actually just want to build this as a gift to my son. I know on Stack platforms that before you ask questions you need to try yourself, i have been trying to get this thing working for the past 36 hours, and im not getting anywhere.

So here is a list of the things i have tried so far.

 1. Firstly i bought everything exactly the same as what the guy had, imported it so i know its the same stuff.
 2. I downloaded the code and schematic.
 3. I wired the little board 4 times, to make sure i did it correctly.
 4. I have redrawn the schematic in tinkercad to make sure all the wires are going to the correct places.

Here is the link to my tinkercad drawing the code is in there as well. Please note that on tinkercad i cant get the arduino board not to be plugged in by usb, it is supposed to get power from the external power supply (4AA battries).

https://www.tinkercad.com/things/43WIrlmR1K3-project1

Here is a link to the youtube video:
https://www.youtube.com/watch?v=cpdjQ0gheDQ&t=311s

Here is the schematic he provided:

[![enter image description here][1]][1]
  [1]: https://i.stack.imgur.com/SFNI9.png

 Here is the Code he provided:

     #include <Servo.h>

    Servo handServo;
    Servo boxServo;

    int switchStatus=0, action=1, vot, randNumber=0;
    const int ledPin = 13;
    const int frontSwitchPin = 2;
    const int handServoPin = 5;
    const int boxServoPin = 6;

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

      pinMode(ledPin, OUTPUT);
      digitalWrite(ledPin,HIGH);

      handServo.attach(handServoPin);
      boxServo.attach(boxServoPin);
      handServo.write(180);
      boxServo.write(70);

      //randomSeed(analogRead(0));
    }

    void loop()
    {
      switchStatus = digitalRead(frontSwitchPin);
      //action = random(1,16);

      if (switchStatus == LOW){

        if (action == 1)
        {
          Serial.println("Action 1");
          for (int i = 70; i <= 110; i++)
          {
            boxServo.write(i);
            delay(20);
          }
          for (int i = 180; i >= 35; i--)
          {
            handServo.write(i);
            delay(20);
          }
          delay(1000);
          handServo.write(26);
          delay(200);
          for (int i = 26; i <=180; i++)
          {
            handServo.write(i);
            delay(20);
          }
          for (int i = 110; i >= 70; i--)
          {
            boxServo.write(i);
            delay(20);
          }
          action++;
        }

        else if (action == 2)
        {
          Serial.println("Action 2");
          for (int i = 70; i <= 110; i++){
            boxServo.write(i);
            delay(6);
          }
          delay(550);
          handServo.write(26);
          delay(550);
          handServo.write(180);
          delay(550);
          boxServo.write(70);
          delay(1500);
          for (int i = 70; i <= 110; i++){
            boxServo.write(i);
            delay(6);
          }
          delay(3000);
          boxServo.write(70);
          action++;
        }

        else if (action == 3)
        {
          Serial.println("Action 3");
          for (int i = 70; i <= 110; i++){
            boxServo.write(i);
            delay(6);
          }
          delay(1000);
          boxServo.write(70);
          delay(2000);
          for (int i = 70; i <= 110; i++){
            boxServo.write(i);
            delay(6);
          }
          handServo.write(26);
          delay(550);
          handServo.write(180);
          delay(500);
          boxServo.write(70);
          action++;
        }

        else if (action == 4)
        {
          Serial.println("Action 4");
          for (int i = 70; i <= 110; i++)
          {
            boxServo.write(i);
            delay(20);
          }
          for (int i = 180; i >= 35; i--)
          {
            handServo.write(i);
            delay(20);
          }
          delay(2000);
          handServo.write(26);
          delay(200);
          handServo.write(180);
          delay(400);
          boxServo.write(70);
          action++;
        }

        else if (action == 5)
        {
          Serial.println("Action 5");
          for (int i = 70; i <= 110; i++){
            boxServo.write(i);
            delay(6);
          }
          delay(2000);
          handServo.write(65);
          delay(550);
          handServo.write(40);
          delay(200);
          handServo.write(65);
          delay(200);
          handServo.write(40);
          delay(200);
          handServo.write(65);
          delay(200);
          handServo.write(40);
          delay(200);
          handServo.write(65);
          delay(200);
          handServo.write(40);
          delay(200);
          handServo.write(65);
          delay(200);
          handServo.write(40);
          delay(200);
          handServo.write(65);
          delay(2000);
          handServo.write(26);
          delay(400);
          handServo.write(180);
          delay(400);
          boxServo.write(70);
          action++;
        }

        else if (action == 6)
        {
          Serial.println("Action 6");
          for (int i = 70; i <110; i++)
          {
            boxServo.write(i);
            delay(20);
          }
          delay(1000);
          for (int i = 0; i < 12; i++)
          {
            for (int j = 70; j <= 110; j++){
              boxServo.write(j);
              delay(6);
            }
            delay(200);
          }
          for (int i = 180; i >= 35; i--)
          {
            handServo.write(i);
            delay(30);
          }
          handServo.write(26);
          delay(400);
          handServo.write(180);
          delay(400);
          boxServo.write(70);
          delay(1500);
          for (int i = 70; i <= 110; i++){
            boxServo.write(i);
            delay(6);
          }
          delay(3000);
          boxServo.write(80);
          action++;
        }

        else if (action == 7)
        {
          Serial.println("Action 7");
          for (int i = 70; i <= 110; i++){
            boxServo.write(i);
            delay(6);
          }
          delay(400);
          handServo.write(26);
          delay(1000);
          for (int i = 0; i < 6; i++)
          {
            for (int j = 70; j <= 110; j++){
              boxServo.write(j);
              delay(6);
            }
            delay(200);
          }
          delay(500);
          handServo.write(180);
          delay(400);
          boxServo.write(70);
          action++;
        }

        else if (action == 8)
        {
          Serial.println("Action 8");
          for (int i = 70; i <= 110; i++){
            boxServo.write(i);
            delay(6);
          }
          handServo.write(26);
          delay(2000);
          for (int i = 0; i < 7; i++)
          {
            handServo.write(75);
            delay(100);
            handServo.write(40);
            delay(100);
          }
          delay(500);
          handServo.write(180);
          delay(1000);
          boxServo.write(70);
          action++;
        }

        else if (action == 9)
        {
          Serial.println("Action 9");
          for (int i = 70; i <= 105; i++){
            boxServo.write(i);
            delay(6);
          }
          delay(2000);
          boxServo.write(110);
          for (int i = 180; i >=35; i--)
          {
            handServo.write(i);
            delay(40);
          }
          delay(500);
          handServo.write(26);
          delay(200);
          for (int i = 26; i <=180; i++)
          {
            handServo.write(i);
            delay(40);
          }
          boxServo.write(70);
          delay(2000);
          boxServo.write(100);
          delay(3000);
          boxServo.write(70);
          action++;
        }

        else if (action == 10)
        {
          Serial.println("Action 10");
          for (int i = 70; i <= 105; i++)
          {
            boxServo.write(i);
            delay(100);
          }
          delay(1000);
          for (int i = 0; i < 10; i++)
          {
            for (int j = 70; j <= 100; j++){
              boxServo.write(j);
              delay(6);
          }
            delay(100);
          }
          boxServo.write(110);
          delay(100);
          handServo.write(26);
          delay(650);
          handServo.write(180);
          delay(400);
          boxServo.write(70);
          action++;
        }

        else if (action == 11)
        {
          Serial.println("Action 11");
          for (int i = 70; i <= 110; i++){
            boxServo.write(i);
            delay(6);
          }
          handServo.write(26);
          delay(2000);
          for (int i = 0; i < 3; i++)
          {
            handServo.write(65);
            delay(200);
            handServo.write(40);
            delay(200);
          }
          delay(1500);
          handServo.write(180);
          delay(400);
          boxServo.write(70);
          delay(1500);
          for (int i = 70; i <= 110; i++){
            boxServo.write(i);
            delay(6);
          }
          handServo.write(26);
          delay(3000);
          handServo.write(180);
          delay(400);
          boxServo.write(70);
          action++;
        }

        else if (action == 12)
        {
          Serial.println("Action 12");
          for (int i = 70; i <= 110; i++)
          {
            boxServo.write(i);
            delay(50);
          }
          delay(1000);
          for (int i = 180; i >= 26; i--)
          {
            handServo.write(i);
            delay(50);
          }
          delay(2000);
          handServo.write(26);
          delay(200);
          handServo.write(180);
          delay(400);
          boxServo.write(70);
          action++;
        }

        else if (action == 13)
        {
          Serial.println("Action 13");
          for (int i = 70; i <= 110; i++){
            boxServo.write(i);
            delay(6);
          }
          delay(2000);
          for (int i = 180; i >= 60; i--)
          {
            handServo.write(i);
            delay(40);
          }
          for (int i = 0; i < 3; i++)
          {
            handServo.write(60);
            delay(200);
            handServo.write(40);
            delay(800);
          }
          handServo.write(26);
          delay(2000);
          handServo.write(180);
          delay(500);
          boxServo.write(70);
          action++;
        }

        else if (action == 14)
        {
          Serial.println("Action 14");
          for (int i = 70; i <= 105; i++){
            boxServo.write(i);
            delay(6);
          }
          delay(4000);
          boxServo.write(110);
          handServo.write(26);
          delay(650);
          handServo.write(180);
          delay(500);
          boxServo.write(100);
          delay(4000);
          boxServo.write(70);
          action++;
        }

        else if (action == 15)
        {
          Serial.println("Action 15");
          for (int i = 70; i <= 105; i++){
            boxServo.write(i);
            delay(6);
          }
          delay(1000);
          for (int i = 0; i < 3; i++)
          {
            for (int j = 70; j <= 105; j++){
              boxServo.write(j);
              delay(50);
            }
            for (int j = 105; j >= 70; j--)
            {
              boxServo.write(j);
              delay(50);
            }
          }
          for (int j = 70; j <= 110; j++){
            boxServo.write(j);
            delay(50);
          }
          for (int i = 180; i >= 35; i--)
          {
            handServo.write(i);
            delay(40);
          }
          delay(1000);
          handServo.write(26);
          delay(400);
          handServo.write(180);
          delay(400);
          boxServo.write(70);
          action = 1;
        }

      }

    }

So in my tinkercad when i run the simulation everything works (exept for the motors breaking but i know it because of the extra power its getting from the usb which i can turn off). When you look in the Serial Monitor it runs through all the "Actions" and when you simulate the button that gets pressed by the servo everthing stops and wait until you toggle the switch again and it goes to the next action.

I have done exactly the same and like i said i wired the board 4 times to make sure its exactly the same. When i switch on the project on my board the servos keep spinning and does not stop and wait for the switch, but when i toggle the switch it actually plays the next "Action", but in the times where it is suppose to wait or stop when the switch is in the off position the servos keep rotating looks like in an anti-clockwise rotation.

Please any help would be greatly appreciated.
If you need more info or if anything is unclear please ask me to provide more and i will. I tried to make it as clear as possible. Thanks

body:
> Yes they turn 360

Normal servos turn between 0 and 180° (or a bit more or less). On these servos you can set the angle through `Servo.write()`. But if the servo spins 360° and more, it is a continuous rotation servo. Here the `Servo.write()` value sets the rotation speed, not the angle. A value of `90` let's it stand still. Values below 90 means rotation backwards, above 90 forward. The higher the distance from 90, the higher the rotation speed will be.

In the video the servos are mounted in a way, that they cannot spin 360°, so they must be normal servos (that also fits with the code). If your servos spin more, you unfortunately bought the wrong servo type.

The code sets the idle position of the boxservo to 70 and of the handservo to 180. That means, that with a continuous rotation servo both servos would spin in idle state, the handservo being way faster than the boxservo.

So you would need to buy normal servos for this project.


message:
How to get the overall average of the data received

I have an arduino uno with two sensors. Voltage and current sensors. I need to get the average value of voltage and current each time the data is received. But i don't know how to add up the current and previous values and divide it to how many values that it has received.

Can someone help me, please? I need it for my project

This is the code i have made

    void setup(){
    Serial.begin(9600);
    }
    void loop(){
        int n=5;
        float sum=0;
        float ave=0;
        for(int x=0;x<n;x++){
            float volt=analogRead(A0);
            float voltage = map(volt,0,1023,0,2500);
            voltage/=100;
            Serial.print("Voltage: ");
            Serial.print(voltage,2);
           sum=sum+voltage;
           }
    ave=sum/n;
    Serial.print("Average: ");
    Serial.print(average,2);
    delay(3000);
    }

But this only takes the average of 5 datas. I want to get the average of all data received.

body:
    void setup(){
    Serial.begin(9600);
    }
    void loop(){
        static unsigned long count=0;
        static float sum=0;
        float ave=0;
        int volt=analogRead(A0);
        float voltage = map(volt,0,1023,0,2500) / 100.0;
        Serial.print("Voltage: ");
        Serial.print(voltage,2);
        sum=sum+voltage;
        count++;
        ave=sum/count;
        Serial.print("  Average: ");
        Serial.println(ave,2);
        delay(3000);
    }

This runs quite a while. The average is restarted only with a Reset of your arduino.

Alternatively, you might want to learn about a [moving average][1] (aka low pass filter)

  [1]: https://en.wikipedia.org/wiki/Moving_average


message:
feather 32u4 servo

I am attempting a project where I use a feather 32u4 to control a servo. It is controlled using the buttons on an attached oled featherwing to set the servo to 3 different values. The code that was provided to me produces an error for this board. After messing with similar code, it appears the statement `#include <Servo.h>` produces an error. There is also a note in the messages about Wire.h but that appears to not be a problem any other time.

The error messages are as follows:

    Arduino: 1.6.13 (Mac OS X), Board: "Adafruit Feather 32u4"

    libraries/Servo/avr/Servo.cpp.o (symbol from plugin): In function `ServoCount':
    (.text+0x0): multiple definition of `__vector_17'
    libraries/RadioHead-master/RH_ASK.cpp.o (symbol from plugin):(.text+0x0): first defined here
    collect2: error: ld returned 1 exit status
    Multiple libraries were found for "Wire.h"
     Used: /Users/bsd194.lab102/Library/Arduino15/packages/adafruit/hardware/avr/1.4.13/libraries/Wire
     Not used: /Applications/Arduino.app/Contents/Java/hardware/arduino/avr/libraries/Wire
    exit status 1
    Error compiling for board Adafruit Feather 32u4.

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

I would attach the code but I don't know how to post it without it appearing oddly.

body:
The message `multiple definition of __vector_17` means, that in your code the interrupt vector 17 is defined multiple times. Often this happens, because 2 used libraries use the same hardware peripherals like the timers. Only one library can configure and use the hardware. If 2 try it, you get a compiler error.

On the Atmega32u4 the interrupt with number 17 is the TIMER1 CAPT (Capture interrupt of Timer1)(see the [datasheet][1] of the Atmega32u4, chapter "Interrupts"). The error message says, that the `Servo` library and the `RadioHead` library both define this interrupt. They both try to use the hardware Timer1.

The consequence is, that you cannot simply use these two libraries together. So what to do? This can get rather difficult. You could change one of the libraries to use a different timer (the Atmega32u4 has 4 timers). This may involve extensive changes (mostly changing the register names, but sometimes more complex changes, if the new timer is not the same type). Some libraries directly provide the possibility to use a different timer, but most don't. Fortunate for you, the `RadioHead` library provides a simple way to change the used timer to Timer2, tough you cannot simply do this, since on the 32u4 the next 16bit Timer is Timer3. [This Adafruit forum thread][2] mentions how to set the `RadioHead` library for Timer2 (by uncommenting the define `RH_ASK_ARDUINO_USE_TIMER2` in `RH_ASK.cpp`) and give a hint on how to then change to Timer3: Effectively by Changing all the `2`s in the timer register and bit names to `3`s. To be sure please check everytime, that the corresponding register/bit names really exist (you can see this in the register descriptions in the datasheet).

  [1]: http://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-7766-8-bit-AVR-ATmega16U4-32U4_Datasheet.pdf
  [2]: https://forums.adafruit.com/viewtopic.php?t=118972