body:
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;
    }

title: Arduino ultrasonic sensor weird output

Answers: 3

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


body:
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?

title: Multiple MPU9250 Synced

Answers: 1

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


body:
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!

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

Answers: 1

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");
    }


body:
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!

title: ESP32 CAM failed to get frame in time

Answers: 5

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
```


body:
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);
        }

title: data classification with arduino

Answers: 2

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.


body:
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...
```

title: Need advice on serial bytes reading optimization

Answers: 1

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.


body:
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".

title: Locating a fault in writing a variable

Answers: 1

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.


body:
Just starting a project and wanting to connect Lolin D32 Pro board with OLED SH1106. The screeen works with my Arduino Nano no problem however I can't seem to get it working on the D32 Pro.
I tried different pins on the D32 and different libraries, no luck.

My code example is below and I connect pin 21 of D32 board to the sda pin of the screen and pin 22 of the d32 board to the scl pin of the screen. VCC & GND also are connected correspondingly
```
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SH1106.h>

#define OLED_SDA 21
#define OLED_SCL 22

Adafruit_SH1106 display(21, 22);

void setup()   {
  Serial.begin(115200);
  Serial.println("setup");
  /* initialize OLED with I2C address 0x3C */
  display.begin(SH1106_SWITCHCAPVCC, 0x3C);
  Serial.println("begin");
  display.clearDisplay();
  Serial.println("clear");

}
void loop() {
    Serial.println("loop");

  /* set text size, color, cursor position,
  set buffer with  Hello world and show off*/
  display.setTextSize(2);
  display.setTextColor(WHITE);
  display.setCursor(0,0);
  display.println("Hello, world!");
  display.display();
  delay(2000);
  display.clearDisplay();
}
```

Please help me out with the code example or something to read. I suspect I am missing something around D32 Pro board pins

title: Lolin D32 Pro board with OLED SH1106

Answers: 0


body:
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?

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

Answers: 1

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() {}
```


body:
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

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

Answers: 3

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


body:
I want to link a PAR quantum sensor (either Licor or Skye Instruments) to Arduino to log PAR, in order to measure light in a forest.
I have an Arduino Uno + data logging shield (with RTC, SD card and ADS1115) and have connected the PAR sensor via A0 to measure differential voltage (A0 –– S+ | S- –– GND | A1 –– GND). Code as follows:

```
  ads.setGain(GAIN_TWOTHIRDS);
  adc0 = ads.readADC_Differential_0_1();
  Voltage = (adc0 * 6.144)/pow(2, 15);
  Voltage = Voltage*1000; // conversion to millivolts
```

When I wire the Arduino to itself to measure a differential voltage (A0 –– 3V and A1 –– GND), it measures beautifully.

Furthermore, when I use a voltmeter to test the Voltage across the + - wires from the sensor, I get sensible readings.

Put the two together – nonsense. I get noisy V readings that don't make sense. When I cover the sensor my V is actually going up, not down as it should! I have tried changing the GAIN, but unfortunately this makes no difference to the problem.

I have been looking at [PARduino][1] for help/inspiration, but they include an amplifier in their setup, which is expensive and I'm not sure is necessary / would solve my problem.

Very new to Arduino. Any and all advice would be very much appreciated.

  [1]: https://academic.oup.com/treephys/article/34/6/640/2338115

title: Logging PAR with quantum sensor and Arduino

Answers: 0


body:
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

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

Answers: 1

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.


body:
Using ESP32 I'm making air pollution quality meter. For that I need MQ7.h library which is of version 1.0.4 MQUnified sensor library, which supports all sensors.

I am using MQ7 carbon monoxide sensor... but that shows error `no such file MQ7...`.

The link for library I will share with you [..github.com/miguel5612/MQSensorsLib..][1].. This link has "mqunified" for all sensors. I just need it to support my code which have written for MQ7:

    #include <SPI.h>
    #include <Wire.h>
    #include <Adafruit_GFX.h>
    #include <Adafruit_SSD1306.h>
    #include <ArduinoJson.h>
    #include <PubSubClient.h>
    #include <WiFi.h>
    #include <math.h>
    #include "MQ7.h"
    #define SCREEN_WIDTH 128 // OLED display width, in pixels
    #define SCREEN_HEIGHT 64 // OLED display height, in pixels
    // Declaration for SSD1306 display connected using software SPI (default case):
    #define OLED_MOSI   13
    #define OLED_CLK   14
    #define OLED_DC    12
    #define OLED_CS    15
    #define OLED_RESET 27
    #define WIFI_ssid "rtpl1"
    #define WIFI_PASSWORD "startupindia007"
    #define TOKEN "yXrewssGkRD8jgjPqW70"
    #define MQ135 35
    #define MQ135_DEFAULTPPM 392 //default ppm of CO2 for calibration
    #define MQ135_DEFAULTRO 41763 //default Ro for MQ135_DEFAULTPPM ppm of CO2
    #define MQ135_SCALINGFACTOR 116.6020682 //CO2 gas value
    #define MQ135_EXPONENT -2.769034857 //CO2 gas value
    #define MQ135_MAXRSRO 2.428 //for CO2
    #define MQ135_MINRSRO 0.358 //for CO2
    #define MQ135_PULLDOWNRES 5000
    #define ADC_REFRES 1024
    uint16_t mq135_a ;
    MQ7 mq7(34,3.3);
    char thingsboardServer[]="demo.thingsboard.io";
    String temperature, humidity, line, dust, mq135, mq7_CO;
    float pm;
    String latitude = "18.5457" , longitude = "73.7847";
    int measurePin =  36;
    int ledPower = 3;
    int samplingTime = 280;
    int deltaTime = 40;
    int sleepTime = 9680;
    float voMeasured = 0;
    float calcVoltage = 0;
    float dustDensity = 0;
    Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, OLED_MOSI, OLED_CLK, OLED_DC, OLED_RESET, OLED_CS);
    WiFiClient wifiClient;
    // Initialize DHT sensor.
    PubSubClient client(wifiClient);
    int status = WL_IDLE_STATUS;
    unsigned long lastSend;
    StaticJsonDocument<200> jsonBuffer;

    void getPPMData()
    {
      mq135_a = analogRead(MQ135);
      long res = adc_getresistence(mq135_a, MQ135_PULLDOWNRES);
      long mq135_ro = mq135_getro(res, MQ135_DEFAULTPPM);
      double d = mq135_getppm(res, MQ135_DEFAULTRO);
      int accStatus=0;
      int reading=analogRead(32);
      Serial.println(reading);
      float t ;
      t=((reading*3.3*10)/4095);
      digitalWrite(ledPower,LOW); // power on the LED
      delayMicroseconds(samplingTime);
      voMeasured = analogRead(measurePin); // read the dust value
      delayMicroseconds(deltaTime);
      digitalWrite(ledPower,HIGH); // turn the LED off
      delayMicroseconds(sleepTime);
      // 0 - 3.3V mapped to 0 - 1023 integer values
      // recover voltage
      calcVoltage = voMeasured * (3.3 / 1024);
      dustDensity = 241.708 * calcVoltage - 0.1;
      dust = String(dustDensity);
      temperature = String(t);
      mq135 = String(d);
      mq7_CO = String(mq7.getPPM());
      display.clearDisplay();
      display.setTextSize(1); // Draw 2X-scale text
      display.setTextColor(WHITE);
      display.setCursor(0, 0);
      display.print(F("CO2 PPM - "));
      display.println(mq135);
      display.print(F("CO PPM - "));
      display.println(mq7_CO);
      display.print(F("PM2.5 PPM - "));
      display.println(dust);
      display.print(F("TEMP - "));
      display.println(temperature);
      // Prepare a JSON payload string
      String payload1 = "{";
      payload1 += "\"temperature\":"; payload1 += temperature; payload1 += ",";
      payload1 += "\"humidity\":"; payload1 += humidity; payload1 += ",";
      payload1 += "\"CO2 PPM\":"; payload1+= mq135; payload1 += ",";
      payload1 += "\"CO PPM\":"; payload1 += mq7_CO; payload1 += ",";
      payload1 += "\"PM2.5 PPM\":"; payload1 += dust;
      payload1 += "}";
      // Send payload
      char telemetry1[100];
      payload1.toCharArray( telemetry1, 100);
      client.publish( "v1/devices/me/telemetry", telemetry1 );
      String payload2 = "{";
      payload2 += "\"latitude\":"; payload2 += latitude; payload2 += ",";
      payload2 += "\"longitude\":"; payload2 += longitude;
      payload2 += "}";
      char telemetry2[100];
      payload2.toCharArray( telemetry2, 100);
      client.publish( "v1/devices/me/telemetry", telemetry2 );
      display.print(F("Payload Sent to Thingsbaord"));
      display.display();
      Serial.println( telemetry1 );
    }

    void InitWiFi()
    {
      Serial.println("Connecting to AP ...");
      WiFi.begin(WIFI_ssid, WIFI_PASSWORD);
      display.clearDisplay();
      display.setTextSize(1); // Draw 2X-scale text
      display.setTextColor(WHITE);
      display.setCursor(10, 0);
      display.println(F("Connecting to AP"));
      // attempt to connect to WiFi network
      while (WiFi.status() != WL_CONNECTED) {
        display.print(F("."));
        display.display();      // Show initial text
        delay(500);
        Serial.print(".");
      }
      display.clearDisplay();
      display.setTextSize(1); // Draw 2X-scale text
      display.setTextColor(WHITE);
      display.setCursor(0, 0);
      display.println(F("Connected to AP"));
      Serial.println("Connected to AP");
    }

    void reconnect() {
      // Loop until we're reconnected
      display.clearDisplay();
      while (!client.connected()) {
        status = WiFi.status();
        if ( status != WL_CONNECTED) {
          WiFi.begin(WIFI_ssid, WIFI_PASSWORD);
          display.setTextSize(1); // Draw 2X-scale text
          display.setTextColor(WHITE);
          display.setCursor(0, 0);
          display.println(F("Connecting to AP"));
          while (WiFi.status() != WL_CONNECTED) {
            delay(500);
            Serial.print(".");
            display.print(F("."));
            display.display();
          }
          display.clearDisplay();
          display.setTextSize(1); // Draw 2X-scale text
          display.setTextColor(WHITE);
          display.setCursor(0, 0);
          Serial.println("Connected to AP");
          display.println(F("Connected to AP"));
          display.display();
        }
        display.clearDisplay();
        display.setTextSize(1); // Draw 2X-scale text
        display.setTextColor(WHITE);
        display.setCursor(0, 0);
        Serial.print("Connecting to ThingsBoard node ...");
        display.print(F("Connecting to ThingsBoard node ..."));
        // Attempt to connect (clientId, username, password)
        if ( client.connect("ESP32 Demo Device", TOKEN, NULL) ) {
          Serial.println( "[DONE]" );
          display.println(F("Connected to Thingsboard node"));
          display.display();
        }
        else {
          Serial.print( "[FAILED] [ rc = " );
          display.print(F("Connection failed - "));
          display.println(client.state());
          Serial.print( client.state() );
          Serial.println( " : retrying in 5 seconds]" );
          display.print(F(": retrying in 5 seconds"));
          display.display();
          // Wait 5 seconds before retrying
          delay( 5000 ):
        }
      }
    }

    /*
     * get the calibrated ro based upon read resistance, and a know ppm
     */
    long mq135_getro(long resvalue, double ppm) {
      return (long)(resvalue * exp( log(MQ135_SCALINGFACTOR/ppm) / MQ135_EXPONENT ));
    }

    /*
     * get the ppm concentration
     */
    double mq135_getppm(long resvalue, long ro) {
      double ret = 0;
      double validinterval = 0;
      validinterval = resvalue/(double)ro;
      if(validinterval<MQ135_MAXRSRO && validinterval>MQ135_MINRSRO) {
        ret = (double)MQ135_SCALINGFACTOR * pow( ((double)resvalue/ro), MQ135_EXPONENT);
      }
      return ret;
    }

    /*
     * convert an adc value to a resistence value
     */
    long adc_getresistence(uint16_t adcread, uint16_t adcbalanceresistor)
    {
      if(adcread == 0){
        return 0;
      }
      else{
        return (long)((long)(ADC_REFRES*(long)adcbalanceresistor)/adcread-(long)adcbalanceresistor);
      }
    }

    void setup() {
      Serial.begin(115200);
      if(!display.begin(SSD1306_SWITCHCAPVCC)) {
        Serial.println(F("SSD1306 allocation failed"));
        for(;;); // Don't proceed, loop forever
      }
      Serial1.begin(9600, SERIAL_8N1, rxPin, txPin);  //UART for pulse sensor Interfacing with Arduino
      //dht.begin();
      delay(10);
      InitWiFi();
      client.setServer( thingsboardServer, 1883 );
      display.println(F(thingsboardServer));
      display.display();
      delay(100);
      // Serial.println(thingsboardServer);
      lastSend = 0;
      pinMode(MQ135, INPUT);
      analogReadResolution(10);
      pinMode(ledPower,OUTPUT);
      pinMode(measurePin,INPUT);
    }

    void loop() {
      if ( !client.connected() ) {
        reconnect();
      }
      if ( millis() - lastSend > 500 ) { // Update and send only after 1 seconds
        getPPMData();
        lastSend = millis();
      }
      client.loop();
    }

  [1]: https://github.com/miguel5612/MQSensorsLib....this

title: MQ7.h: No such file or directory

Answers: 0


body:
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);

        }
     }

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

Answers: 1

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


body:
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?

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

Answers: 2

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


body:
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)

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

Answers: 2

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


body:
Here's my Code so far:
<!-- language-all: lang-cpp -->

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

    void loop() {
      float a;
      float angle;
      int setpoint;
      a = analogRead(A1);
      angle = map(a, 0, 1023, 0, 180);

      if ( (angle>0) && (angle<70) )
      {
        setpoint=50;
      }
      if ( (angle>70) && (angle<110) )
      {
        setpoint=90;

      }
      if ( (angle>110) && (angle<180) )
      {
        setpoint=130;

      }

      Serial.print(setpoint);
      Serial.print(",");
      Serial.println(angle);
    }

I'm using an Arduino Genuino.

How can I get the servo motor to move to the setpoints and stop when the angle is between the eligible range?

just wanted to update showing how i solved this problem using the following code.

  ```
void setup() {
  pinMode(5,OUTPUT);
  pinMode(6,OUTPUT);
  Serial.begin(9600);
}
void loop() {
  float a;
  float b;
  float desired_angle;
  float actual_angle;
  float error;
  float motor;
  float setpoint;

  a=analogRead(A1);
  desired_angle=map(a,0,1023,0,180);

  b=analogRead(A2);
  actual_angle=map(b,125,920,0,180);

   if ( (desired_angle>0) && (desired_angle<70) )
  {
    setpoint=50;
  }
  if ( (desired_angle>70) && (desired_angle<110) )
  {
    setpoint=90;

  }
  if ( (desired_angle>110) && (desired_angle<180) )
  {
    setpoint=130;

  }

  error=(setpoint-actual_angle);
  motor=desired_angle/270*255;

  if (error>0)
  {
    digitalWrite(5,LOW);
    analogWrite(6,motor);
  }
  if (error<0)
  {
    digitalWrite(6,LOW);
    analogWrite(5,-1*motor);
  }

  Serial.print(actual_angle);
  Serial.print(",");
  Serial.println(setpoint);

}
```

title: Trying to get a servo motor to move to certain setpoints when a control potentiometer shows certain values

Answers: 0


body:
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...

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

Answers: 3

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.


body:
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)

title: DC Motor Control L298N

Answers: 1

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


body:
I have an autonomous wall-tracking robot that uses relative angle changes from a I2C-connected MPU6050 module along with ultrasonic 'ping' sensors for motor speed control to acquire and then track a specific wall offset distance.  The problem I'm having is that occasionally the MPU6U050's DMP module will stop loading new data into its FIFO.  This can take 2 minutes or 5 hours, but eventually it will happen.  Here's what I know (or think I know)

 - AFAICT, I have to have the motors running to get it to fail.
 - Installing bypasses on the motor terminals per Pololu guidance for their D20 metal-geared motors significantly improved the situation (i.e. much longer times between failures), but did not completely solve the problem.
 - The Arduino I2C bus and at least part of the MPU6050 appears to remain functional after a failure; at least, I can still call mpu.testConnection() and get a positive response.
 - Resetting the mpu, the FIFO, the DMP or any combination thereof does not seem to help. Resetting the Arduino DOES restore MPU6050 functionality (after all the setup stuff, including mpu.Initialize()).

As I write this question, I just had another long-term test fail at a little over 3 hours (198 minutes).

Has anyone else experienced this sort of problem with the MPU6050 in a motor-driven system?  Any ideas about how to really track down the failure mechanism?

TIA,

Frank

title: MPU6050 with Arduino I2C Unreliable with Motor Noise

Answers: 0


body:
I have installed an AutoPID library (by ryan downing version 1.0.3) to my arduino IDE, but im not sure which parts i will have remove to get the PID to control the servo angle.

Thanks for the reply, but i know i have not used the library in the sketch but i am unsure how to combine it, i have an example code for how to use the AutoPID, i will add it below.

```
void setup() {
  pinMode(5,OUTPUT);
  pinMode(6,OUTPUT);
  Serial.begin(9600);
}
void loop() {
  float a;
  float b;
  float desired_angle;
  float actual_angle;
  float error;
  float motor;
  float setpoint;

  a=analogRead(A1);
  desired_angle=map(a,0,1023,0,180);

  b=analogRead(A2);
  actual_angle=map(b,125,920,0,180);

   if ( (desired_angle>0) && (desired_angle<70) )
  {
    setpoint=50;
  }
  if ( (desired_angle>70) && (desired_angle<110) )
  {
    setpoint=90;

  }
  if ( (desired_angle>110) && (desired_angle<180) )
  {
    setpoint=130;

  }

  error=(setpoint-actual_angle);
  motor=desired_angle/270*255;

  if (error>0)
  {
    digitalWrite(5,LOW);
    analogWrite(6,motor);
  }
  if (error<0)
  {
    digitalWrite(6,LOW);
    analogWrite(5,-1*motor);
  }

  Serial.print(actual_angle);
  Serial.print(",");
  Serial.println(setpoint);

}
```
and here is the example code

```
#include <AutoPID.h>

// PID settings and gains
#define OUTPUT_MIN 0
#define OUTPUT_MAX 255
#define KP 0.12
#define KI 0.8
#define KD 0.003

// Variables
double analogReadValue, setPoint, outputVal;

// Input/output variables passed by reference, so they are updated automatically
AutoPID myPID(&analogReadValue, &setPoint, &outputVal, OUTPUT_MIN, OUTPUT_MAX, KP, KI, KD);

// Setup timeStep
void setup() {
  myPID.setTimeStep(500);
}

void loop() {
  setPoint = analogRead(A3);          // Set our desired point (read the POT)
  analogReadValue = analogRead(A1);   // Read our output voltage
  myPID.run();                        // Run the PID
  analogWrite(6, outputVal); // Write the PID result to the output
}
```

title: How would i add PID control to this servo motor control program. potentiometer

Answers: 0


body:
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

title: Useless box wiring and code

Answers: 1

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.


body:
seems I have some issues in my code as I subscribe for specific mqtt topic and also read same value via serial and publish it to mqtt. It takes time for device connected to serial to change setting and I'am reading its state to quickly. How to optimize code that during subscribed topic value change serial read would be susspended or specific value data byte read ignored for some time.
Main code parts:

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

```
    const char* mqtt_topic_base = "panasonic_heat_pump/sdc";
    const char* mqtt_set_quiet_mode_topic =

"panasonic_heat_pump/SetQuietMode";
        byte inCheck = 0;

    #define MAXDATASIZE 256
    char data[MAXDATASIZE];
    int data_length = 0;

    // log message to sprintf to
    char log_msg[256];

    // mqtt topic to sprintf and then publish to
    char mqtt_topic[256];

    // mqtt
    WiFiClient mqtt_wifi_client;
    PubSubClient mqtt_client(mqtt_wifi_client);

    void send_command(byte* command, int length)
    {

      int bytesSent = Serial.write(command, length);
      sprintf(log_msg, "sent bytes    : %d", bytesSent); log_message(log_msg);

      // wait until the serial buffer is filled with the replies
      delay(1000);

      // read the serial
      readSerial();

      sprintf(log_msg, "received size : %d", data_length); log_message(log_msg);
    }

    // Callback function that is called when a message has been pushed to one of your topics.
    void mqtt_callback(char* topic, byte* payload, unsigned int length) {
      char msg[length + 1];
      for (int i=0; i < length; i++) {
        msg[i] = (char)payload[i];
      }
      msg[length] = '\0';
    // set 0 for Off mode, set 1 for Quiet mode 1, set 2 for Quiet mode 2, set 3 for Quiet mode 3
        if (strcmp(topic, mqtt_set_quiet_mode_topic) == 0)
         {
        String set_quiet_mode_string(msg);
        int quiet_mode = (set_quiet_mode_string.toInt() + 1) * 8;
        int checksum = 512 - (241 + 108 + 1 + 16 + quiet_mode);

        sprintf(log_msg, "set Quiet mode to %d", quiet_mode / 8 - 1); log_message(log_msg);
        byte command[] = {0xf1, 0x6c, 0x01, 0x10, 0x00, 0x00, 0x00, quiet_mode, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, checksum};
        send_command(command, sizeof(command));
         }

     if (strcmp(topic, mqtt_topic_base) == 0)
      {
        log_message("Updating..");

        update_everything();
      }
    }

    void update_everything()
    {

      get_heatpump_data();

    }

    void get_heatpump_data() {
        byte command[] = {0x71, 0x6c, 0x01, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12};
        send_command(command, sizeof(command));

        int quiet_mode_state = (int)(data[7]);

        char* quiet_mode_state_string;
        if (quiet_mode_state == 73) {
          quiet_mode_state_string = "0";
        } else if (quiet_mode_state == 81) {
          quiet_mode_state_string = "1";
        } else if (quiet_mode_state == 89) {
          quiet_mode_state_string = "2";
        } else if (quiet_mode_state == 97) {
          quiet_mode_state_string = "3";
        } else if (quiet_mode_state == 73) {
          powerfull_mode_state_string = "OFF";
        } else if (quiet_mode_state == 74) {
          powerfull_mode_state_string = "30min";
        } else if (quiet_mode_state == 75) {
          powerfull_mode_state_string = "60min";
        } else if (quiet_mode_state == 76) {
          powerfull_mode_state_string = "90min";
        } else {
          quiet_mode_state_string = "Unknown";
        }
        sprintf(log_msg, "received quiet mode state : %d (%s)", quiet_mode_state, quiet_mode_state_string); log_message(log_msg);
        sprintf(log_msg, "powerfull mode state : %d (%s)", quiet_mode_state, powerfull_mode_state_string); log_message(log_msg);

        sprintf(mqtt_topic, "%s/%s", mqtt_topic_base, "quiet_mode_state"); mqtt_client.publish(mqtt_topic, quiet_mode_state_string);
        sprintf(mqtt_topic, "%s/%s", mqtt_topic_base, "powerfull_mode_state"); mqtt_client.publish(mqtt_topic, powerfull_mode_state_string);

    }

    void loop() {
      // Handle OTA first.
      ArduinoOTA.handle();

      if (!mqtt_client.connected())
      {
        mqtt_reconnect();
      }
      mqtt_client.loop();

      update_everything();
      delay(5000);
    }

    void readSerial()
    {
        if(Serial.available() > 0){

          log_message("serial available");
        Serial.readBytes(data, 203);
        while(Serial.available()){
          delay(2);
          Serial.read();
        }

      }
    }

title: ESP8266 mqtt publish + subscribe + serial read

Answers: 0


body:
I have built and coded a low power NRF24L01 transmitter and receiver, for purposes of transmitting the temperature of the transmitter's environment. I have used an Atmega328P chip for the project. The project itself works well, but after some time, around 10 days or so, the transmitter goes silent.
During my initial troubleshooting, I have concluded that the system hangs up during NRF transmission, and since it's stuck in the transmission phase, it eats up all the battery and dies. For this, I'm also transmitting battery usage, and I have added watchdog timers in my temperature sensing and transmission phases. This has not solved my problem, and I'm stuck as of now.

Some bits of code:
My low power cycle:

     while (1) {
      wdt_reset();  //watchdog timer added for 8S. See the beginning of loop func for timer settings.
      Serial.print("Loop Start ");
      delay(50);
        //Blink only at every wakeup
        digitalWrite(redLed, HIGH);
        setTime = millis() + ( 1 );
        while ( millis() <= setTime ) {
        }
        digitalWrite(redLed, LOW);
        //Blink only at every wakeup

        Serial.println("Powerdown begins");
          delay(50);
        LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF);
        sleepCounter++;
        Serial.println("Powerdown over");
          delay(50);
         wdt_enable(WDTO_4S);     // enable the watchdog
      //Reenabling radio for test purposes

    //end of radio edit
             Serial.print("Slept for ");
             Serial.println(sleepCounter);
        if ( sleepCounter >= postPeriod || sleepCounter == -1 || interruptState == true ){       ///|| true ) {
          sleepCounter = 0;
          interruptState = false;

          break;

        }

      }

      //Serial.println(micros());
      //Serial.println("DEBUG nRf Test");

      radio.begin();
    //  radio.powerUp(); //power up the nRF24

      digitalWrite(redLed, HIGH);

      Set_nRFTX_Data (1);

      nRF_Send ();

In the Set_nRFTX_Data() function, I'm writing my temperature value to the buffer, as such :

       nRF_BufferTX [23] = b1;             // 24th byte the first byte of a two-byte value for precision (msb)
        nRF_BufferTX [24] = b2;              // 25th byte the second byte of a two-byte value for precision (lsb)

And in the nRF_Send() function, I'm sending it over NRF:

    void nRF_Send () {

      radio.closeReadingPipe(address);
      radio.openWritingPipe(address);
      radio.stopListening();

      bool isDataTransfer;
      radio.write(nRF_BufferTX, 32);

      radio.openReadingPipe(1, address);
      radio.startListening();
    }

If anyone's interested, I may share circuit specifications as well.

title: NRF24L01 based project freezes for no good reason

Answers: 0


body:
I'm trying to do OTA firmware updates for the Arduino Due with the ESP32.
Now so far I'm able to get the firmware from a website and transfer it over UART.

Now I'm looking to get the firmware and upload it to the Arduino due. My understanding is that I have to write it at 0x00080000 and from there I can write al the binary information.

The problem is that I have no idea how to:

 1. Get the Arduino DUE in programming mode
 2. Write to the Arduino DUE (which pins to use, what protocol...)

Can someone give me some pointers as to where to start with this? I have been reading through the documentation of the SAM3x8e, but I don't get any wiser.

title: Program the Arduino Due with the ESP32

Answers: 0


body:
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.

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

Answers: 1

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