body:
I am building an Arduino based flight controller for a quadcopter and have got it flying but it is not performing how I want it to. The drone is flying but when I release the sticks the drone does  not stay perfectly still. There is some random and small oscillations that occur when it is just hovering.

Right now I am using a single PID controller for each axis though functions like this.

    dt=0.005;
 error = *in - *set;

 P = (error * kp);
 I = I + (error * ki)*dt;
 D_M = ((*in - in1)*kd)/dt;
 D_E = ((error - error1)*kd)/dt;
 D=D_M*(1-jerk) + D_E*(jerk);

 I = constrain(I, LOWER_BOUND*0.75, UPPER_BOUND*0.75);
 in1 = *in;
 error1 = error;
 pid = P + I + D;

 pid = constrain(pid, LOWER_BOUND, UPPER_BOUND);
 *out = pid;

The error is the Euler angle and the setpoint is the angle I want it to go to.

I then output the PID controller values to the motors using the Arudino Servo library.

      motor1 = throttle;
      motor2 = throttle;
      motor3 = throttle;
      motor4 = throttle;

      motor1 += rollOUT;
      motor2 += rollOUT;
      motor3 -= rollOUT;
      motor4 -= rollOUT;

      motor1 -= pitchOUT;
      motor2 += pitchOUT;
      motor3 -= pitchOUT;
      motor4 += pitchOUT;

      motor1 += yawOUT;
      motor2 -= yawOUT;
      motor3 -= yawOUT;
      motor4 += yawOUT;

Is there something I am missing about quadcopter PID controllers? Thank you for the help!

title: Quadcopter oscillation using PID

Answers: 1

body:
I'd suggest setting Kd to zero, Kp to a minimal value and letting the integral alone function as the controller. Any response to an error might be slow but the integrator alone will control a process with zero error. After observing the response of the integral for a period of time, hopefully without the problem you referenced, gradually introduce proportional control and watch for the periodic instability. If increasing the proportional gain results in oscillation, reduce the proportional back to a stable value and gradually introduce more derivative gain. I have worked with PID throughout my career and the instability you described sounds like something I'd expect to see originating from the derivative control action. No sensor is perfectly noise free and even if the noise is low amplitude, the rate of change may still be fairly large which will result in a very obvious periodic instability in the flight of your drone.

If this is the case, finding the source of the induced noise may not be easy. Perhaps reducing the derivative gain and using mostly proportional and integral control will effectively filter and attenuate the instability you're noticing. Good luck.


body:
We are currently creating a system which can log student attendance using RFIDs. Currently, we have the RFID Scanner set up (MFRC522 reader and Arduino UNO microcontroller). The database for the student's info and time-logging is also already set up. We are; however, having problems with accessing the data the Arduino is sending. We want the Arduino device to send us the Tag IDs via a USB Connection and have set it up to send the relevant data through the Serial Port. However, we cannot access this data using a Python program with this code.

    import serial

    x = 1
    while(x == 1 ):
        ser = serial.Serial("COM3", baudrate = 9600, timeout = 0)
        if(ser.is_open):
           print("Serial Port in Use")
        else:
           print("Card ID: " + ser.read)

We are attempting to read from Port COM3 (the SP the Arduino uses). If the serial port is in use, the program outputs the "Serial Port in Use" (for testing purposes only, to be removed in final code) and if not, it will output the Card ID. However, through this, we run into the problem of being unable to use the same serial port with the Arduino (we are running on Windows). We tried using a serial port splitter but replacing the "COM3" with the name of the virtual port does not work.

We would prefer not to use Processing and would be open to simply avoiding the use of a serial port completely.

title: How do I grab data from my Arduino device using a Python program?

Answers: 1

body:
It isn't a good idea to open serial in a loop. It can be opened once at the start (or you can retry once per few seconds, if it fails).

Also the method `is_open` should return `true` if the serial was successfully opened so you can use it.

Maybe some working example would be a good way to start.


body:
I'm trying to control the speed of DC Motor using

 1. Arduino R3
 2. NPN Transistor (2N2222A331)
 3. 10k potentiometer
 4. 2M ohm resistor
 5. Diode

I'm not using L298N and I'm also not using L293D.

DC motor is running, but the speed of DC motor doesn't seem to change with changes in potentiometer.
Circuit seems to be alright as DC motor is running.

The code is as follows

    int potPin = A0;
    int motorPin = 9;
    int potValue = 0;
    int motorValue = 0;

    void setup()
    {
     Serial.begin(9600);
     pinMode(motorPin,OUTPUT);
    }

    void loop()
    {
     potValue = analogRead(potPin);
     motorValue = map(potValue, 0, 1023, 0, 255);
     analogWrite(motorPin, motorValue);
     delay(2);
     Serial.print("potentiometer = " );
     Serial.print(potValue);
     Serial.print("t motor = ");
     Serial.println(motorValue);
    }

Whenever I tweak the Potentiometer, I can see the relative changes from Arduino  "Serial Monitor" (both Potentiometer values and Motor values), but the speed doesnt seem to change physically.

Things that I tried

 1. tried different combinations of resistors(100,1k,10k,1M,2M ohm) so as to vary voltage that goes to DC Motor
 2. tried to check with different Output pins like 3,5,9

Nothing works, DC motor speed isn't changing.

**this leads me - to believe that, my analogwrite isn't working.
please help me understand as to what i'm i doing wrong?**

The Circuit is as follows

[![Circuit][1]][1]

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

title: analogWrite is not working - while trying to control DC motor speed

Answers: 3

body:
Well, 2M resistor to the base? If the motor is running with that, the transistor must be broken (shorted). Just try to check if the motor is running with disconnected base.

You can also check PWM output by connecting LED with resistor (no, not 2M ohms, just about 330 ohms). For the transistor 1k should be sufficient maybe little less (depends on motor current and h21e amplification coeficient).

Also there are some versions 2N2222 with emitter and collector swapped. And reversed transistor has much lower current amplification coeficient.

And I hope you are using external power supply, USB is not a good idea. Starting power is usually way too much for the overcurrent protections.

Anyways, this works for me:

    void setup() {
      pinMode(9, OUTPUT);
    }

    void loop() {
      analogWrite(9, map(analogRead(A0), 0, 1023, 0, 255));
      delay(100);
    }

2N2222A + 1k + PC FAN + 12V Fan Power supply.

Connections:
E -> Gnd,
C -> FAN-,
FAN+ -> 12V,
12V GND -> Arduino GND,
Pin 9 -> 1k -> B

On the Arduino side 47k trimmer and the USB

body:
Two things to test:

 1. Have you tried to put an LED (and resistor to protect it) in the motor's place? If the brightness changes, your setup (Arduino+transistor) is working. If not, maybe you've killed your 2N2222 by giving it a wrong diode or something else is wrong.
 2. Have you tried reducing the PWM frequency? An LED can follow a fast change, but a motor can't. Also, by turning on-off the motor less frequently you dissipate less power on your transistor and diode. A quick search gave me this: [this][1].

  [1]: https://playground.arduino.cc/Code/PwmFrequency

body:
Referring to [this datasheet][1] you have connected the transistor the wrong way around. Also, 1M resistor at the base is way too high. Bipolar transistors are **current amplifiers** (amplification at about 50-100 in your case) and with 1MOhm at the base there will be no current through the base at all. I would try with 2k for a beginning.
I hope you have another transistor because this one seems to be broken and I'm pretty sure that it's not a fault in the analog output. If the output stage of the uC was broke there would be no reaction (at least in a correct circuit)

  [1]: https://www.google.com/url?sa=t&source=web&rct=j&url=http://www.next.gr/components-datasheets/2N2222.pdf&ved=2ahUKEwix_suovvDgAhUJJVAKHScsAS0QFjAMegQIBRAB&usg=AOvVaw1xklGtj-dT4MeQx-P3bZ0e "this datasheet"


body:
Can I connect a DS3231 and an MPU6050 by an Arduino Mega 2560? I have connect it:

    MPU 6050               Arduino Mega 2560
    SDA           =        SDA
    SCL           =        SCL
    GND           =        GND
    VCC           =        5V

And I have connected DS3231 to SDA and SCL beside AREF pin:

    DS3231               Arduino Mega 2560
    SDA           =        SDA
    SCL           =        SCL
    GND           =        GND
    VCC           =        5V

The problem is when I connect both of them MPU6050 prints nan, after opening the DS3231 pin from the arduino, MPU6050 prints the correct angles.
Can someone please help me?

Code:

    #include "MPU6050.h"
    #include "Wire.h"
    #include <DS3231.h>
    MPU6050 accelgyro;
    int16_t ax, ay, az, gx, gy, gz;

    DS3231 rtc(SDA, SCL);

    double timeStep, time, timePrev;
    double arx, ary, arz, grx, gry, grz, gsx, gsy, gsz, rx, ry, rz;

    int i;
    double gyroScale = 131;

    void setup() {
      Wire.begin();
      accelgyro.initialize();
      Serial.begin(9600);
      rtc.begin();
    }

    void loop() {
      timePrev = time;
      time = millis();
      timeStep = (time - timePrev) / 1000;
      accelgyro.getMotion6(&ax, &ay, &az, &gx, &gy, &gz);
      gsx = gx/gyroScale;   gsy = gy/gyroScale;   gsz = gz/gyroScale;
      arx = (180/3.141592) * atan(ax / sqrt(square(ay) + square(az)));
      ary = (180/3.141592) * atan(ay / sqrt(square(ax) + square(az)));
      arz = (180/3.141592) * atan(sqrt(square(ay) + square(ax)) / az);
      if (i == 1) {
        grx = arx;
        gry = ary;
        grz = arz;
      }
      else{
        grx = grx + (timeStep * gsx);
        gry = gry + (timeStep * gsy);
        grz = grz + (timeStep * gsz);
      }
      rx = (0.1 * arx) + (0.9 * grx);
      ry = (0.1 * ary) + (0.9 * gry);
      rz = (0.1 * arz) + (0.9 * grz);
      Serial.print("X axis == ");
      Serial.println(arx);
      Serial.print("Y axis == ");
      Serial.println(ary);
      Serial.print("Z axis == ");
      Serial.println(arz);
      Serial.println(rtc.getTimeStr());
      i = i + 1;
      delay(1000);
    }

title: Can I connect a DS3231 and an MPU6050?

Answers: 2

body:
The DS3231 library you are using works (for some bizarre reason) exclusively with its own internal bit-bang implementation of I2C. This cannot be used on the same pins as the hardware Wire library which the MPU6050 uses.

Either move the DS3231 to a different pair of pins, or find a better DS3231 library that uses the Wire library for communication.

body:
Yes. Using i2c, you need to change the address of the MPU6050 because the default is (0x68) which is also the default and only address the DS3231 can use.

Example of changing the address from a personal sketch:

MPU6050 mpu(0x69);

So try:

MPU6050 accelgyro(0x69);


body:
I'm using STM32(generic board) and I want to control bi-color LED(common anode). STM32 pin layout and scheme is below, so please see it.
Now, in theory scheme Works, but in practice it Works halfway. Red LED is connected with `PB8` pin and green LED is connected with `PB3` pin.
Code is simple so I think that problem is not in the code. Red LED Works, but green doesn't work. If I connect green cathode with GND manually, then it Works, otherwise(with STM32) it doesn't.
Later I found that pin `PB3` has `Trace SWO` mark(see pin layout below). I'm not completly sure what `Trace SWO` means, just found that it some kind of debugigng protocol(I guess) but I can't find info can it be used for `digitalWrite` purposes. Is there any way to habilitate `PB3` pin for `digitalWrite`? All other pins are in use.

Code:

    // DOWN
    digitalWrite(PB3, HIGH);
    digitalWrite(PB8, LOW);
    delay(750);

    // UP
    digitalWrite(PB8, HIGH);
    digitalWrite(PB3, LOW);
    delay(750);

[STM32 pin layout](https://www.bing.com/images/search?view=detailV2&id=69E683278A7EF9AC68EF7C923FB9A5FF20165E5A&thid=OIP.pPrFsHEEJy5Szpz6-Q6mpwHaFM&exph=759&expw=1082&q=stm32+pin+layout&selectedindex=0&ajaxhist=0&vt=0&eim=1,2,6)

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

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

**R4 doesn't exist, it's mistake in scheme**

title: digitalWrite on Trace SWO pin

Answers: 0


body:
I am trying to send MPU sensor data to Pubnub IOT platform but not able to do it since there is some unknown problem. There is no error in code but following issue pops up in com port:-

[![COM PORT Results][1]][1]

It looks like sensor reading needs to be in JSON Format but no sure how to do it. I Just need it in raw imu sensor reading for now so how do i get it.

Here is the code:

    #include <ESP8266WiFi.h>
    #define PubNub_BASE_CLIENT WiFiClient
    #include <PubNub.h>
    #define PUBNUB_DEFINE_STRSPN_AND_STRNCASECMP
    #include "MPU9250.h"

    const char *ssid =  "mym404";     // replace with your wifi ssid and wpa2 key
    const char *pass =  "786110786";

    const char * pubkey = "my key";
    const char * subkey = "my key";

    const char * pubchannel = "demo_keyset";
    const char * subchannel = "demo_keyset";

    MPU9250 IMU(Wire,0x68);
    int status;

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

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

           WiFi.begin(ssid, pass);
           while (WiFi.status() != WL_CONNECTED)
              {
                delay(500);
                Serial.print(".");
              }
          Serial.println("");
          Serial.println("WiFi connected");

        /* Start the Pubnub library by giving it a publish and subscribe
           keys */
        PubNub.begin(pubkey, subkey);

        while(!Serial) {}

      // start communication with IMU
      status = IMU.begin();
      if (status < 0) {
        Serial.println("IMU initialization unsuccessful");
        Serial.println("Check IMU wiring or try cycling power");
        Serial.print("Status: ");
        Serial.println(status);
        while(1) {}
      }
    }

    void loop() {
        // read the sensor
      IMU.readSensor();
      // display the data
      Serial.print(IMU.getAccelX_mss(),6);
      Serial.print("\t");

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

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

        delay(1000);
    }

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

What do you guys think?

title: How to interface MPU9250 and NodeMcu?

Answers: 1

body:
The error you're reporting is coming from your call to `PubNub.publish()`. You could have diagnosed the problem by taking outputting and inspecting what you were passing to it.

Your line:

    PubNonSubClient *pclient = PubNub.publish(pubchannel, "String(IMU.getAccelX_mss())");

is not going to work. You're sending the string `"String(IMU.getAccelX_mss())"` to PubNub rather than the value of `IMU.getAccelX_mss()` as a `String`. Take the quotes off it:

    PubNonSubClient *pclient = PubNub.publish(pubchannel, String(IMU.getAccelX_mss()));

If for some reason the number has to be returned as a string, the code would look like:

    PubNonSubClient *pclient = PubNub.publish(pubchannel, "\"" + String(IMU.getAccelX_mss()) + "\"");


body: I have a duemilanove which originally had a 168.  I have some ATMEGA328 P chips and I've put one into the duemilanove.  I am using a Uno as a programmer for the duemilanove.  I am running Arduino 1.8.2 on a PC which I understand doesn't need a capacitor installed on the Uno.  I've uploaded the sketch which makes the Uno an ISP, I have edited the avrdude.conf file, have wired up in accordance with http://www.crash-bang.com/resource/bootload-atmega328/ and the tutorial on this site.  When I run burn bootloader using the preferences set to verbose, the returned signature is correct for the P version of the chip I believe (0x95 0x14) and this is the value I have put into the avrdude.conf file.  However, avrdude is still insisting it is expecting to receive 0x95 0x0F and will not burn the bootloader.  I have no idea where it is getting this value from (I've even tried editing the iom328p.h file...). Any ideas?

title: Uploading bootloader to ATMEGA328 P

Answers: 1

body:
The signature bytes are:

ATmega328 0x1E 0x95 0x14

ATmega328P 0x1E 0x95 0x0F

So it looks you have the wrong bytes for the 328P.


body:
I want to connect multiple (up to 4) MAX30100 or MAX30102 oximeter sensors to an Arduino via I2c. But I could not find a solution to change/assign the I2C address.

[implementing-pulse-oximeter-using-max30100][1]

[datasheet MAX30100][2]

  [1]: https://morf.lv/implementing-pulse-oximeter-using-max30100
  [2]: https://datasheets.maximintegrated.com/en/ds/MAX30100.pdf

title: Connecting multiple MAX30100/30102 via I2C

Answers: 3

body:
LTC4316 is what you need. I haven't used it yet, but I know it from a project that did: [mocap][1]. It is an I2C translator IC.

Of course, if you need those ICs to be far away from each other, use a uC (or a separate Arduino) with all of those, and connect them with a different protocol!

  [1]: https://hackaday.io/project/27519-motion-capture-system-that-you-can-build-yourself

body: Nyos's suggestion of an I2C address translator is the ticket. I hadn't heard of these chips before, so I started searching. I found that the one they recommended may be being phased out. It also looks like it's surface-mounted. I found a TI data sheet that lists a DIP package chip TCA9548APW that lets you map up to 8 I2C devices to different addresses. You might want to check those out as an alternative.

body:
Is there any other way of solving this issue?
I do not want to increase Hardware dependency.

I found out this article - which lets you use multiple i2c devices with the same address by employing different data lines: https://bitbanksoftware.blogspot.com/2019/01/controlling-lots-of-oled-displays-with.html

The Github source: https://github.com/bitbank2/Multi_BitBang

To my knowledge, I, either have to implement this library my own way or us the TCA9548APW chip as described by @Duncan C in the above answer


body:
I've a project which i need to make a door open and close using the fingerprint.

I've successfully made fingerprint works just fine it reads and confirm the fingerprints stored in it but the servo doesn't act at all to my confirmed finger print.

        #include <Servo.h>
        #include <Adafruit_Fingerprint.h>
    #include <SoftwareSerial.h>
    Servo myservo;

    int getFingerprintIDez();
    int pos = 0;
    int id ();
    // pin #2 is IN from sensor (GREEN wire)
    // pin #3 is OUT from arduino (WHITE wire)
    SoftwareSerial mySerial(A12, A13);
    Adafruit_Fingerprint finger = Adafruit_Fingerprint(&mySerial);

    // On Leonardo/Micro or others with hardware serial, use those! #0 is green wire, #1 is white
    //Adafruit_Fingerprint finger = Adafruit_Fingerprint(&Serial1);

    void setup()
    {
    myservo.attach(10);
    while (!Serial); // For Yun/Leo/Micro/Zero/...

    Serial.begin(9600);
    Serial.println("Adafruit finger detect test");

    // set the data rate for the sensor serial port
    finger.begin(57600);

    if (finger.verifyPassword()) {
    Serial.println("Found fingerprint sensor!");
    } else {
    Serial.println("Did not find fingerprint sensor :(");
    while (1);
    }
    Serial.println("Waiting for valid finger...");
    }

    void loop() // run over and over again
    {
    getFingerprintIDez();
    delay(50); //don't ned to run this at full speed.

    }

    uint8_t getFingerprintID() {
    uint8_t p = finger.getImage();
    switch (p) {
    case FINGERPRINT_OK:
    Serial.println("Image taken");
    break;
    case FINGERPRINT_NOFINGER:
    Serial.println("No finger detected");
    return p;
    case FINGERPRINT_PACKETRECIEVEERR:
    Serial.println("Communication error");
    return p;
    case FINGERPRINT_IMAGEFAIL:
    Serial.println("Imaging error");
    return p;
    default:
    Serial.println("Unknown error");
    return p;
    }

    // OK success!

    p = finger.image2Tz();
    switch (p) {
    case FINGERPRINT_OK:
    Serial.println("Image converted");
    break;
    case FINGERPRINT_IMAGEMESS:
    Serial.println("Image too messy");
    return p;
    case FINGERPRINT_PACKETRECIEVEERR:
    Serial.println("Communication error");
    return p;
    case FINGERPRINT_FEATUREFAIL:
    Serial.println("Could not find fingerprint features");
    return p;
    case FINGERPRINT_INVALIDIMAGE:
    Serial.println("Could not find fingerprint features");
    return p;
    default:
    Serial.println("Unknown error");
    return p;
    }

    // OK converted!
    p = finger.fingerFastSearch();
    if (p == FINGERPRINT_OK) {
    sweep();
    Serial.println("Found a print match!");
    } else if (p == FINGERPRINT_PACKETRECIEVEERR) {
    Serial.println("Communication error");
    return p;
    } else if (p == FINGERPRINT_NOTFOUND) {
    Serial.println("Did not find a match");
    return p;
    } else {
    Serial.println("Unknown error");
    return p;
    }

    // found a match!
    Serial.print("Found ID #"); Serial.print(finger.fingerID);
    Serial.print(" with confidence of "); Serial.println(finger.confidence);
    }

    // returns -1 if failed, otherwise returns ID #
    int getFingerprintIDez() {
    uint8_t p = finger.getImage();
    if (p != FINGERPRINT_OK) return -1;

    p = finger.image2Tz();
    if (p != FINGERPRINT_OK) return -1;

    p = finger.fingerFastSearch();
    if (p != FINGERPRINT_OK) return -1;

    // found a match!
    Serial.print("Found ID #"); Serial.print(finger.fingerID);
    Serial.print(" with confidence of "); Serial.println(finger.confidence);
    return finger.fingerID;

    }

    void sweep()
    {
     for(int pos = 0; pos < 180; pos += 25)  // goes from 0 degrees to 180 degrees
     {                                  // in steps of 1 degree
       myservo.write(pos);              // tell servo to go to position in variable 'pos'
       delay(122);                       // waits 122ms for the servo to reach the position
     }

     for(int pos = 180; pos>=1; pos-=25)     // goes from 180 degrees to 0 degrees
     {
       myservo.write(pos);              // tell servo to go to position in variable 'pos'
       delay(122);                       // waits 122ms for the servo to reach the position
     }
    }

title: Servo doesn't move with fingerprint

Answers: 0


body: I just bought an Elegoo Uno R3 today and delved into programming Arduinos. For my first project I'd like to power a 5m LED strip (30 LED/m). I've learned that an individual neopixel needs around 60 mA, and i'm gonna assume this means that to power all 150, I need 9A. I'm extremely new to all this (and electrical stuff in general) and not exactly sure how to go on about giving 9A worth of power to the strips and the Arduino. Any help to get me on the right track would be appreciated.

title: Powering 150 WS2812B LED strips

Answers: 2

body:
Your math looks right to me. You need a 9A power supply if you're going to drive all 150 LEDs at 0 brightness on all 3 channels.

I'd suggest using a separate 500mA 5V regulated power supply for the Arduino. Switching 9A of load on and off on the LED power supply is going to cause quite a bit of variation in the voltage on that 9A supply, and the simplest way to keep the power supply to the Arduino clean is to make the 2 power supplies completely different.

body: Connect the power supply in multiple places to the LED strip. The two ends and the middle at least. That will keep all the current from having to flow thru all of the strip.  If try to power it from just one end, the power traces in the strip might act as a fuse and blow open. Or it might survive, but act like a low-ohm resistor and the chips farther down the string will see less voltage (because voltage down the trace = current x resistance) and may appear dim, or act weirdly, or not turn on at all.


body:
Please excuse any glaring errors in my code, I'm new to both C and python.

I'm trying to send an encrypted message from my arduino uno via a DHT22 sensor and an rf module using the radiohead ask and AESlib libraries to a raspberry pi with a usb RTL-SDR using the rtl_433 library and a python script.

I think (but I could very well be wrong) I have the Arduino side working properly and it feels as though I'm pretty close on the python side, however I don't seem to be decrypting the message properly.

An example of the string before being encrypted might be:

"55.55,24.99,0001"

Here is the code on the Arduino side:

#include <AESLib.h>
#include <SPI.h>
#include <Adafruit_Sensor.h>
#include "DHT.h"
#include <RH_ASK.h>
#include <Base64.h>

#define DHTPIN 2

#define DHTTYPE DHT22   // DHT 22  (AM2302), AM2321
DHT dht(DHTPIN, DHTTYPE);
RH_ASK driver;

bool takeSensorReading = true;
float h;
float t;
String str_humid;
String str_temp;
String str_out;
uint8_t key[] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31};
char data[32];
char endChar[1] = "Ʊ";

void setup() {
  driver.init();
  dht.begin();
  Serial.begin(9600);
}

void loop() {
  delay(5000);

  int messagelength = sizeof(str_out);
  byte plain[messagelength];

  h = dht.readHumidity();
  // Read temperature as Celsius
  t = dht.readTemperature();

  // Convert Humidity to string
  str_humid = String(h, 2);

  // Convert Temperature to string
  str_temp = String(t, 2);

  // Combine Humidity and Temperature
  str_out = str_humid + "," + str_temp + ",0001";

  str_out.toCharArray(data, 32);
  aes256_enc_single(key, data);

  /*aes256_dec_single(key, data);*/
  Serial.println(data);
  int encryptedStringLength = sizeof(data);

  int encodedLength = Base64.encodedLength(encryptedStringLength);
  char encodedString[encodedLength];
  Base64.encode(encodedString, data, encryptedStringLength);
  Serial.print("Encoded string is:\t");
  Serial.println(encodedString);

  driver.send(strcat( (uint8_t *)encodedString, endChar ), 33);
  driver.waitPacketSent();

  takeSensorReading = !takeSensorReading;
}

and here is the python code:

import subprocess
import json
import base64
from Crypto.Cipher import AES

BS = 16
pad = lambda s: s + (BS - len(s) % BS) * chr(BS - len(s) % BS)
unpad = lambda s : s[0:-ord(s[-1])]

def print_no_newline(string):
    import sys
    sys.stdout.write(string)
    sys.stdout.flush()

def decrypt(enc):
    private_key = str(bytearray([0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31]))
    iv = enc[:16]
    cipher = AES.new(private_key, AES.MODE_CBC, iv)
    return unpad(cipher.decrypt(enc[16:]))

p = subprocess.Popen(['rtl_433', '-f', '433720000', '-F', 'json'],stdout=subprocess.PIPE,bufsize=1)
# rtl_433 -f 433720000 -F json
try:
    for line in iter(p.stdout.readline, ""):
        lineStripped = str(line).strip()
        try:
            jsondata = json.loads(lineStripped)
            time = jsondata["time"]
            payload = jsondata["payload"]
            if len(payload) == 33:
                payloadstring = ''
                for a in range(len(payload)):
                    payloadstring += chr(payload[a])
                payloadstring += "AAAAAAAAAA="
                print payloadstring
                encrypted = base64.b64decode(payloadstring)
                print encrypted
                decrypted = decrypt(encrypted)
                print decrypted
        except Exception as err:
            print "oh no, something went wrong"
            print("error: {0}".format(err))
except KeyboardInterrupt:
    p.kill()

p.wait()
p.stdout.close()

Here is an example of the erroneous output of the decrypt function:

"@g�އ�6S���25zD"

Any help you could give me in decoding the message from the Arduino in the python script would be really appreciated.

Thanks

Richard

*EDIT

I thought if it helps I could provide a bit more context around the transmission stages that the message goes through:

After the initial data string is constructed from the temperature and humidity sensor eg "55.55,24.99,0001" that 16 byte message is added to a 32 byte char array and encrypted using the aes128_enc_single method. The encrypted message is then base63 encoded The encrypted char array is then combined with an extra unencrypted character "Ʊ" (which I thought I could use to crudely validate the message) and sent via the radiohead ask send method:

`driver.send(strcat( (uint8_t *)encodedString, endChar ), 33);`

On the pyhton/reciever end I run a sub process `rtl_433 -f 433720000 -F json`

and listen for the output line by line. A example of the output of the rtl_433 command would look something like this:
`{"time": "2019-03-05 00:00:00", "model": "RadioHead ASK", "len": 33, "to": 255, "from": 255, "id": 0, "flags": 0, "payload": [111, 110, 109, 57, 120, 86, 52, 79, 121, 78, 71, 52, 48, 122, 117, 88, 67, 52, 77, 118, 85, 81, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65], "mic": "CRC"}`

rtl_433 converts the message into an array of ASCII or Unicode characters.

I have then tried to convert the characters in the recieved array back into standard characters:
`payloadstring += chr(payload[a])`
added padding to the message:
`payloadstring += "AAAAAAAAAA="`
then base64 decoded the result:
`encrypted = base64.b64decode(payloadstring)`
and then finally decrypt that:
`decrypted = decrypt(encrypted)`

Hopefully that info might be helpful in flagging up where I have gone wrong.

title: Help decrypting AES string from arduino rf module in python

Answers: 1

body:
By inspection only:

You are using an Initialization Vector and CBC mode in your Python code, but no IV and single block encryption in your Arduino code.

I think if you use MODE_ECB in your Python it will ignore the IV and match the Arduino code.

From a look at the [AESLib github][1] it appears your key should be exactly 16 bytes - yours is 32. I haven't looked at the code to see whether it will just ignore the rest, but the Python code definitely won't, so you should probably do what it says and use 16, and adjust your Python code to match.

Since the above wasn't enough to get it working, I would suggest divide-and-conquer: Use an online AES-128 encyrptor/decryptor such as [aesencryption.net][2] or [encode-decode.com][3] or [infoencrypt.com][4] to validate and cross-check your Arduino encryption and Python decryption functions. With a bit of luck you can at least fix them one-by-one, against a known-good reference.  Perhaps with a bit of fiddling you may be able to work out where it's going wrong.

I presume the humidity value may not change much, and I have a feeling that sending several messages with the same start can substantially weaken the encryption but I'm no crypto expert and perhaps it's still adequate for your purposes.

  [1]: https://github.com/DavyLandman/AESLib/blob/master/README.md
  [2]: https://aesencryption.net/
  [3]: https://encode-decode.com/aes128-encrypt-online/
  [4]: https://www.infoencrypt.com/


body:
IDE:1.8.8
Board:Arduino UNO
When I use the code below, I get result of print like this.

    { "result": [ { "ID": "01", "Value": [ "2", "1", "13" ] } ] }

But when I use SoftwareSerial and in the setup to being that the serializeJson result like this:

    {}

I don't know what happens in the softserial with using json library, can someone tell me why?

    #include <SoftwareSerial.h>
    #include <ArduinoJson.h>
    int dir[3];
    char  json[] ="{\"ID\":\"01\",\"Value\":[\"%d\",\"%d\",\"%d\"]}";
    //SoftwareSerial Left(8,9);//左
    /SoftwareSerial Right(6,7); //右
    //SoftwareSerial Up(10,11);//上
    //SoftwareSerial Down(14,15);//下
    //SoftwareSerial Global(8,9);  //建立軟體串列埠腳位 (RX, TX)左
    void setup() {

      Serial.begin(9600);        //設定硬體串列埠速率
     // Up.begin(9600);
     // Right.begin(9600);
      //Global.begin(9600);   //設定軟體串列埠速率
      }

    void loop() {

     dir[0]=2;
     dir[1]=1;
     dir[2]=13;
      if(Serial.read()=='j')
    {
     StaticJsonDocument<256> docc;
      char b[35];
      sprintf(b, json, dir[0], dir[1],dir[2]);
      deserializeJson(docc, b);
      JsonObject object = docc.as<JsonObject>();

      DynamicJsonDocument doc(1024);
     JsonArray result = doc.createNestedArray("result");
      result.add(object);
      result.add(object);
      serializeJsonPretty(doc,Serial);
       }
      }

These are error code

    #include <SoftwareSerial.h>
    #include <ArduinoJson.h>
    int dir[3];
    char  json[] ="{\"ID\":\"01\",\"Value\":[\"%d\",\"%d\",\"%d\"]}";
    //SoftwareSerial Left(8,9);//左
    SoftwareSerial Right(6,7); //右
    SoftwareSerial Up(10,11);//上
    //SoftwareSerial Down(14,15);//下
    SoftwareSerial Global(8,9);  //建立軟體串列埠腳位 (RX, TX)左
    void setup() {

      Serial.begin(9600);        //設定硬體串列埠速率
      Up.begin(9600);
      Right.begin(9600);
      Global.begin(9600);   //設定軟體串列埠速率
      }
    void loop() {
         Global.listen();
          while (!Serial.available()) {}  //等到PC傳送字元才到下一步
         Global.write(2);  //傳送給左邊的板子子id
          while (!Global.available()) {}  //等到左方板傳送字元才到下一步
            dir[0]=Global.read();
            Serial.println( dir[0]);  //左方板向PC傳送字串

           Up.listen();
          while (Serial.read()!='Y') {}  //等到PC傳送字元才到下一步
          Up.write(3);  //傳送給左邊的板子子id
          while (!Up.available()) {}  //等到左方板傳送字元才到下一步
          dir[1]=Up.read();
            Serial.println(dir[1]);  //左方板向PC傳送字串
           // }

         Right.listen();
         while (Serial.read()!='Y') {}  //等到PC傳送字元才到下一步
          Right.write(4);  //傳送給左邊的板子子id
          while (!Right.available()) {}  //等到左方板傳送字元才到下一步
           dir[2]=Right.read();
            Serial.println(dir[2]);  //左方板向PC傳送字串
     if(Serial.read()=='j')
    {
     StaticJsonDocument<256> docc;
      char b[35];
      sprintf(b, json, dir[0], dir[1],dir[2]);
      deserializeJson(docc, b);
      JsonObject object = docc.as<JsonObject>();

      DynamicJsonDocument doc(1024);
     JsonArray result = doc.createNestedArray("result");
      result.add(object);
      result.add(object);
      serializeJsonPretty(doc,Serial);
       }
    }

title: SerializeJson not working when using softserial

Answers: 0


body:
I have hooked up my ultrasonic sensor to my Arduino correctly, I know this because I am getting feedback from it, but when I run this code:

`int mode = 2;
double distance;
double calibration;
void setup()
{
  Serial.begin(9600);
  pinMode(12, INPUT);
}
void loop()
{
  if(mode == 1)
  {
  //Read duration in microSeconds
  long duration = pulseIn(12, HIGH);
  //58 uS per cm for MB1240 XL-MaxSonar
  //Operation Range: 20 cm min (50 cm for accurate)
  distance = duration / 58.0;
  calibration = -20;
  }
  else if (mode == 2)
  {
  //Analog In .49 mV per unit
  double voltage = analogRead(5)*.0049;
 //.49 mV per cm;
  distance = voltage/.0049;
  calibration = 0.0;
  }
  double cmToInch = 0.393701;
  //Analog Seems to be More Accurate due to PWM timing
  Serial.print((distance+calibration)*cmToInch);
  Serial.println(" in");
  delay(100);
}`

I get sporadic results when it is just sitting there without anything moving in front of, let alone around it at all:

[![distance that I from my sensor][1]][1]

What is wrong here? Is it my code, is the sensor just very sensitive, or is it something else?

Thanks in advance.

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

title: How can I fix my HRLV-MaxSonar-EZ ultrasonic sensor so it does not give gibberish feedback?

Answers: 0


body:
I'm working on a project with a starry sky, based on fiberoptics and 5 leds.

The code should work this way:

Start on average brightness, then go up or down according to a set of randomly chosen preset values. (min, max, wait time etc) and switch direction after the wait period on either its min/max is completed. When it reaches the average again, a new set of preset values should be assigned.

The updating of the leds should be done every set interval, so the change speed can be adjusted.

The leds go on, but nothing seems to change after that. Have I done something wrong? No errors given in the Arduino IDE.

(it's my first coding project, there will probably be some beginner mistakes or workarounds)
<!-- language-all: lang-cpp -->

    // Declare pins
    int LED01           = 3;
    int LED02           = 5;
    int LED03           = 6;
    int LED04           = 9;
    int LED05           = 11;

    // Time variables
    unsigned long currentTime;
    unsigned long waitingTime[5];
    unsigned long lastRound;

    // LED Variables
    int brightMin [5]   =       { 0,    0,    0,    0,      0     };    // Minimum brightness
    int brightAvg [5]   =       { 200,  230,  210,  210,    235   };    // Average brightness
    int brightMax[5]    =       { 0,    0,    0,    0,      0     };    // Maximum brightness
    int timeWaitLow[5]  =       { 0,    0,    0,    0,      0     };    // Waiting time
    int timeWaitAvg[5]  =       { 0,    0,    0,    0,      0     };    // Waiting time
    int timeWaitMax[5]  =       { 0,    0,    0,    0,      0     };    // Waiting time
    int increment[5]    =       { 0,    0,    0,    0,      0     };    // Increment in brightness
    int currentBright[5]=       { 200,  230,  210,  210,    235   };    // Current brightness

    // LED Variables Possibilities
    int brightMinPos[5] =       { 0,   20,    40,   0,      20    };    // Minimum brightness possibilities
    int brightMaxPos[5] =       { 240,  250,  230,  225,    250   };    // Maximum brightness possibilities
    int timeLowPos[5]   =       { 3000, 5000, 4000, 40000,  20000 };    // Waiting time on low brightness possibilities
    int timeHighPos[5]  =       { 3000, 1000, 500,  2000,   4000  };    // Waiting time on high brightness possibilities
    int timeAvgPos[5]   =       { 3000, 5000, 4000, 40000,  20000 };    // Waiting time on average brightness possibilities
    int incrementPos[5] =       { 10,    20,    30,    40,      20     };    // increment in brightness possibilities

    // Variables
    bool needsUpdate[5]  =       { true, true, true, true,   true    };  // Does the led need a settings update?
    bool reachedAvg[5]   =       { true, true, true, true,   true    };  // Has it reached the middle brightness?
    bool reachedLow[5]   =       { false, false, false, false,  false};  // Has it reached the Lowest brightness?
    bool reachedMax[5]   =       { false, false, false, false,  false};  // Has it reached the Highest brightness?
    bool waitingAvg[5]   =       { false, false, false, false,  false};  // Is it waiting at the middle brightness?
    bool waitingLow[5]   =       { false, false, false, false,  false};  // Is it waiting at the lowest brightness?
    bool waitingMax[5]   =       { false, false, false, false,  false};  // Is it waiting at the Highest brightness?

    // Directional variables
    bool directionLED[5];

    // Random variables
    long randomNumber;                                                  //  Long to store random number

    // counters
    int i=0;

    void setup() {
      Serial.begin (9600);                                              //  Start serial
      randomSeed(analogRead(A0));                                       //  Set randomseed
      lastRound = millis();

    // Declare outputs
      pinMode (LED01, OUTPUT);
      pinMode (LED02, OUTPUT);
      pinMode (LED03, OUTPUT);
      pinMode (LED04, OUTPUT);
      pinMode (LED05, OUTPUT);
    }

    // Check if it should stop at bottom, middle or top
    void checkStopPoint(){
      for (i=0;i<5;i++){
        if (currentBright[i] <= brightMin[i] && reachedLow == false) {                         // is it at the lowest brightness?
          reachedLow[i] = true;
          waitingTime[i] = millis();
        }else if (currentBright[i] == brightAvg[i] && reachedAvg == false) {                   // is it at the average brightness?
          reachedAvg[i] = true;
          waitingTime[i] = millis();
        }else if (currentBright[i] >= brightMax[i] && reachedMax == false) {                   // is it at the highest brightness?
          reachedMax[i] = true;
          waitingTime[i] = millis();
        }
      }
      i=0;
    }

    void checkResetPoint(){
      for (i=0;i<5;i++){
        if (reachedLow[i] == true && currentTime-waitingTime[i] >= timeWaitLow){
          reachedLow[i] = false;
          directionLED[i] = true;
        }else if( reachedMax[i] == true && currentTime-waitingTime[i] >= timeWaitMax){
          reachedMax[i] = false;
          directionLED[i] = false;
        }else if ( reachedAvg[i] == true && currentTime-waitingTime[i] >= timeWaitAvg){
          reachedAvg[i] = false;
          needsUpdate[i] = true;
        }
      }
      i=0;
    }

    // update LED variables
    void updateLEDVariables(){
      for (i=0; i>=5; i++){
        if (needsUpdate[i] == true){
          randomNumber      = random(5);
          brightMin[i]      = brightMinPos[randomNumber];                   // Set random value for minimum brightness
          randomNumber      = random(5);
          brightMax[i]      = brightMaxPos[randomNumber];                   // Set random value for maximum brightness
          randomNumber      = random(5);
          timeWaitLow[i]    = timeLowPos[randomNumber];                     // Set random value for low waiting time
          randomNumber      = random(5);
          timeWaitMax[i]    = timeHighPos[randomNumber];                    // Set random value for high waiting time
          randomNumber      = random(5);
          timeWaitAvg[i]    = timeAvgPos[randomNumber];                     // Set random value for average waiting time
          randomNumber      = random(5);
          increment[i]      = incrementPos[randomNumber];                   // Set random value for increment value
          randomNumber      = random(2);
          if (randomNumber == 1){
            directionLED[i] = true;
          }else{
            directionLED[i] = false;
          }
          needsUpdate[i]    = false;
          reachedAvg[i]     = false;
        }
      }
      i=0;
    }

    void writeToLED(){
      analogWrite(LED01, currentBright[0]);
      analogWrite(LED02, currentBright[1]);
      analogWrite(LED03, currentBright[2]);
      analogWrite(LED04, currentBright[3]);
      analogWrite(LED05, currentBright[4]);
    }

    void loop() {
      currentTime = millis();
      updateLEDVariables();
      checkStopPoint();
      checkResetPoint();

      if (currentTime - lastRound >= 1){

        for (i=0;i<5;i++){
          if (directionLED[i] == true && !reachedLow && !reachedAvg[i] && !reachedMax[i] && !needsUpdate[i]){
            currentBright[i] = currentBright[i]+increment[i];                         // Go 1 value up
          }else if (directionLED[i] == false && !reachedLow[i] && !reachedAvg[i] && !reachedMax[i] && !needsUpdate[i]){
            currentBright[i] = currentBright[i]-increment[i];                         // Go 1 value down
          }
        }
      i=0;
      writeToLED();
      lastRound = millis();
      }
    }

title: Sketch for 5 randomly fading leds not working as expected; what could be wrong?

Answers: 0


body:
I am using the Arduino IDE version 1.8.8 I am trying to control an [ESP32-wroom][1]. The gpios for pins 16 and 17 are working. I have some relays on GPIO's 18 and 19 that I'd also like to be able to control. I also have no control over GPIO's that are over 17 I've tried 18 through 27 and I can't toggle them.

    #define relayPin3 18
    #define relayPin4 19

    int relayflag = 0;
    void loop() {
      delay(1000);
      if (relayflag == 0){
        digitalWrite(relayPin3, LOW);
        digitalWrite(relayPin4, HIGH);
        relayflag =1;
      }
      else
      {
        digitalWrite(relayPin3, HIGH);
        digitalWrite(relayPin4, LOW);
        relayflag = 0;
      }

    }

I noticed that GPIO's 18 and 19 are also shared with spi ports.

Does the digitalWrite command work for any GPIO or is it in use by another library? Is there some other command to get access to the GPIO's I need to use? Some library I need to modify.

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

  [1]: https://www.espressif.com/sites/default/files/documentation/esp32-wroom-32_datasheet_en.pdf
  [2]: https://i.stack.imgur.com/Wz3bn.png

title: How to use the ESP32 WROOM GPIOS above #18 with arudino ide?

Answers: 1

body:
Found the answer, albeit a simple one. This is my first go around with arudino so it will look ridiculous to those who program microprocessors (including myself)

You need to declare the pin to be an output before use. The inconsistent thing is, this only happens sometimes. For some of the pins you don't need to use pinMode for them to work.

      pinMode(relayPin1, OUTPUT);


body:
I am creating a program to display text on an OLED display and then have it sent to a thermal printer.

The issue is my second char string: word_buffer

When I try to use word_buffer for any reason it crashes the program and nothing will work (the OLED display will not refresh upon uploading the sketch and typing on the keyboard will not update the display).

The program works fine when you omit the code needed for the thermal printer (Adafruit_Thermal.h, SoftwareSerial.h, and other setup).

The sample code is below, I've commented out the section where I try and utilize word_buffer.
If I remove the thermal printer setup code and uncomment that section, the program will run just fine.

Let me know what you think, I've been stuck on this for a while now :/

    #include <Adafruit_SSD1306.h>
    #include <Adafruit_GFX.h>
    #include <Adafruit_Thermal.h>
    #include <PS2Keyboard.h>
    #include <MemoryFree.h>

    #include <SPI.h>
    #include <Wire.h>

    #define LED_PIN 13

    // OLED display
    #define OLED_MOSI  A4
    #define OLED_CLK   A3
    #define OLED_DC    A2
    #define OLED_CS    A0
    #define OLED_RESET A1
    Adafruit_SSD1306 display(OLED_MOSI, OLED_CLK, OLED_DC, OLED_RESET, OLED_CS);

    // printer
    #include "SoftwareSerial.h"
    #define GND_PIN 7
    Adafruit_Thermal printer(&Serial, 4);

    // keyboard
    const int DataPin = 8;
    const int IRQpin =  3;
    PS2Keyboard keyboard;

    #define HIDDEN_BUF 21
    #define VIS_BUF 168
    #define WRD_BUF 32

    char line_buffer[HIDDEN_BUF + VIS_BUF + 1];
    int line_start = HIDDEN_BUF;
    int line_len = 0;
    int word_len = 0;
    char word_buffer[WRD_BUF + 1];

    void setup() {
      keyboard.begin(DataPin, IRQpin);

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

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

      for (int i = 0; i < HIDDEN_BUF + VIS_BUF; i++)
        line_buffer[i] = ' ';

      line_buffer[HIDDEN_BUF + VIS_BUF] = 0;

      for (int i = 0; i < WRD_BUF; i++)
        word_buffer[i] = ' ';

      word_buffer[WRD_BUF] = 0;

      display.begin(SSD1306_SWITCHCAPVCC);
      display.clearDisplay();
      display.setTextSize(1);
      display.setTextColor(WHITE);
      display.setCursor(0, 0);
      display.println(line_buffer + HIDDEN_BUF);
      display.display();

      Serial.begin(9600);
      printer.begin();
    }

    void loop() {

      if (!keyboard.available()) return;

      char c = keyboard.read();

      boolean newline = false;

     if (c == PS2_DELETE) {
        if (line_len > 0) {
          line_len--;
          line_buffer[line_start + line_len] = ' ';
          if (word_len > 0)
          word_len--;
        }
      }

    //  if (word_len > 0)
    //  line_buffer[188] = word_buffer[1];

      if (c >= 33 && c <= 126) {
        word_len++;
        line_buffer[line_start + line_len] = c;
        word_buffer[word_len] = c;
        line_len++;
         }

      if (c == 32) {
        line_buffer[line_start + line_len] = c;
        line_len++;
        for (int i = 0; i <= 32; i++)
          word_buffer[i] = ' ';
        word_len = 0;
      }

      display.clearDisplay();
      display.setCursor(0, 0);
      display.println(line_buffer + HIDDEN_BUF);
      display.display();
    }

title: Problem: char string not working with SoftwareSerial.h

Answers: 0


body: How can I make the code of this project where I will press one time a button,  to turn on the first led (and turn off second led) and when other one press to turn on second led (and turn off the first led).

title: Using two leds with one push button

Answers: 1

body:
You can do this by keeping the 'state' saved in a variable.
Depending on it's [state][1], the button will have a different effect.

After this effect, the state is updated, so that next iteration it will behave according to the other state.

    state = led1
    if(buttonpressed){
       if(state == led2){
         led1On();
         led2Off();
         state = led1;
       }else{
         led1Off();
         led2On();
         state = led2;
       }
    }

  [1]: https://en.wikipedia.org/wiki/Finite-state_machine


body:
I have a project, and I want to use an ATtiny167(ATtiny87), I know that an Arduino can progam ATtiny84 (84/44/24), ATtiny85 (85/45/25), and ATtiny2313 (4313). **but I don't know if it can program an ATtiny87?**

thank you for your help.

title: Can I program an ATtiny87 with Arduino

Answers: 1

body:
There is a json for ATtiny 167 at https://playground.arduino.cc/Main/ArduinoOnOtherAtmelChips

So add that json to your preferenses.


body:
Arduino: 1.8.8 (Windows 10), Board: "Arduino Nano, ATmega328P (Old Bootloader)"

    libraries\TimerOne\TimerOne.cpp.o (symbol from plugin): In function `TimerOne::isrDefaultUnused()':

    (.text+0x0): multiple definition of `__vector_13'

    libraries\Timer1Fast\Timer1Fast.cpp.o (symbol from plugin):(.text+0x0): first defined here

    collect2.exe: error: ld returned 1 exit status

    Multiple libraries were found for "Timer1Fast.h"
     Used: D:\apps\Arduino\libraries\Timer1Fast
     Not used: C:\Users\biril\Documents\Arduino\libraries\pwmTest
    Multiple libraries were found for "TimerOne.h"
     Used: D:\apps\Arduino\libraries\TimerOne
     Not used: C:\Users\biril\Documents\Arduino\libraries\TimerOne-master
    Multiple libraries were found for "LiquidCrystal_I2C.h"
     Used: C:\Users\biril\Documents\Arduino\libraries\LiquidCrystal_I2C
     Not used: C:\Users\biril\Documents\Arduino\libraries\NewliquidCrystal
     Not used: C:\Users\biril\Documents\Arduino\libraries\Arduino-LiquidCrystal-I2C-library-master
     Not used: D:\apps\Arduino\libraries\LiquidCrystal
    Multiple libraries were found for "Wire.h"
     Used: D:\apps\Arduino\hardware\arduino\avr\libraries\Wire
     Not used: D:\apps\Arduino\libraries\Wire
    exit status 1
    Error compiling for board Arduino Nano.

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

title: How to fix this error?

Answers: 0


body: I'm trying to connect an I2C OLED display and an n RF24L01 WiFi module to an ATTiny85. But I only need 1 extra pin. Is it possible to use the same clock wire/pin for the I2C and SPI device? Maybe with some extra code? Thanks a lot!

title: Is it possible to use I2C and SPI ons the same Clock line?

Answers: 0


body:
I've just bought few NXP PCA8561AHN LCD segment drivers to do some tests which unfortunately did not went as expected.

I'm familiar with expanders and segment LED displays but LCDs seem to be way more complicated than I thought and there are no libraries or articles to start with.

According to the datasheet, everything is connected correctly, as follows:

- VLCD: +3.3V
- VDD: +3.3V
- VSS: GND
- RST: pulled down by a 1K resistor
- A0: unconnected
- SCL: pulled up by a 1K resistor and connected to A5/SCL on MCU
- SDA: pulled up by a 1K resistor and connected to A4/SDA on MCU
- PORE: unconnected
- SEG0 to SEG13: LCD segments
- COM0: LCD pin 1 (backplane #1)
- COM1: LCD pin 18 (backplane #2)

PCA8561 draws 35uA when RST is pulled down so it seem to be "active".

Here's how I've tried to initialize the i2C communication with the driver:

    #include <Wire.h>

    #define address 0x38

    const byte numbers[10] = {
      B01000000,
      B01111001,
      B00100100,
      B00110000,
      B00011001,
      B00010010,
      B00000010,
      B01111000,
      B00000000,
      B00010000
     };

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

      Wire.begin();

      Wire.beginTransmission(address);
      Wire.endTransmission();
    }

    void loop() {

      Wire.beginTransmission(address);

      Wire.write(numbers[5]);

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

      Wire.endTransmission();
      delay(250);
    }

[PCA8561 datasheet](https://www.nxp.com/docs/en/data-sheet/PCA8561.pdf)

**PCA8561 pinout**
[![PCA8561 pinout][1]][1]
[1]: https://i.stack.imgur.com/fcCWg.png

    .

**LCD pinout**
[![LCD pinout][2]][2]
[2]: https://i.stack.imgur.com/k773H.png

**Update**

```
void setup() {
  Wire.begin();

  Wire.beginTransmission(address);

  Wire.write(0x00);
  // Wire.write(00000000);
  Wire.write(00101100);
  Wire.write(0x0);

  Wire.write(0x01); // Display_ctrl command (address 01h)
  // Wire.write(00011100);
  Wire.write(010); // frame frequency selection: 96Hz

  Wire.write(0x02); // Display_ctrl_1 command (address 02h)
  // Wire.write(00001100);
  Wire.write(11); // static mode

  Wire.endTransmission();
}

void loop() {
  Wire.beginTransmission(address);

  /*
     Static drive mode
     Using a single backplane, COM0
  */
  Wire.write(0x04); // SEG0 to SEG 7
  Wire.write(B11111111); // all segments ON
  Wire.write(0x05); // SEG8 to SEG15
  Wire.write(B11111111); // all segments ON

  Wire.endTransmission();
}
```

title: How to interface Arduino with NXP PCA8561 LCD segment driver?

Answers: 0


body:
I tried to build a weather station with anemometer and My setup is,
[SwitchDoc Labs' anemometer kit](https://shop.switchdoc.com/collections/weather/products/weatherrack-anemometer-wind-rain-for-weatherpiarduino-weatherplus-raspberry-pi-arduino) (which is equivalent to [sparkfun anemometer kit](https://www.sparkfun.com/products/8942)) connected to the [grove weather-pi board](https://shop.switchdoc.com/collections/weather/products/the-weather-board-w-grove-interface-board-for-weather-instruments-for-raspberry-pi-arduino) with [rtc clock DS3231](https://www.amazon.com/Universal-Solder-DS3231-Arduino-EEPROM-Battery/dp/B07BCPRH6F) installed on which is connected to [arduino UNO](https://store.arduino.cc/usa/arduino-uno-rev3).

According to http://www.switchdoc.com/wp-content/uploads/2016/07/WeatherBoard_CurrentSpecification.pdf and their official tutorial https://www.switchdoc.com/2015/01/weather-arduino-weatherpiarduino/, if I use grove weather-pi board's JP2 connections to connect to the UNO/Mega2560 board then it suggests as following (in my case its UNO)

diagram 1 ![1][1]
diagram 2 ![2][2]

    GroveWeatherPi_board Mega  Uno  Units
        JP2/1 ->         A0   A0  WindVane
        JP2/2 ->         D2   D3  RainBucket
        JP2/3 ->         D5   D2  Anemometer
        JP2/4 ->         GND   GND  GND

And the supposedly working sketch/library is https://github.com/switchdoclabs/SDL_Weather_80422 which only compiles on arduino-IDE without issue if I use the fork https://github.com/soligen2010/Adafruit_ADS1X15 instead of the original https://github.com/adafruit/Adafruit_ADS1X15 with it but even then the wind-speed and wind-direction unit or to say the whole anemometer part just do not work or in other words, do not give any reading. I have tested the units individually up to the arduino pins with LED light on breadboard, they are sending signals/responding and also mounted the whole project on a Mega2560 as well but results remained unchanged.

I am assuming the pin-outs defined in the https://github.com/switchdoclabs/SDL_Weather_80422 are messed up then but how to redefine it in the sketch/library because in the ino sketch file, these are the pin-out definitions for primarily Mega2560

    #define pinLED     13  // LED connected to digital pin 13
    #define pinAnem    18  // Anenometer connected to pin 18 (not used in the diagram!) - Int 5 - Mega   / Uno pin 2
    #define pinRain    2   // Anenometer connected to pin 2 - Int 0 - Mega   / Uno Pin 3
    #define intAnem    5   // int 0 (check for Uno), according to the above two diagrams' comparison, for UNO this pin also goes to the pin 2
    #define intRain    1   // int 1 (not used in the diagram! Then why? Its a TX pin)

Where the pinAnem and intAnem both indicates pin 2 for UNO according to the above two diagrams.

When I connect the I2C vcc pin from grove-weather-board to UNO's 5 volts instead of 3.3 volts as shown, the wind direction gets fixed but still no wind-speed reading.

So what are the corrections I need to do in the [SDL_Weather_80422 library](https://github.com/switchdoclabs/SDL_Weather_80422) or in the connection diagram in this case?

[1]: https://i.stack.imgur.com/5bkUW.png
[2]: https://i.stack.imgur.com/cX8c4.png

title: How to get the weather kit with anemometer working using arduino (UNO)?

Answers: 1

body:
According to the above setup only rain bucket unit works.

And as [jsotola](https://arduino.stackexchange.com/users/40318/jsotola) mentioned both the anemometer and the rain bucket sensors are simple switches, so a simple sketch can be written that reads the switch state and light LED (pin13) if the switch is activated and turns off LED if switch is not activated and that can be done for each of the switches separately.

But instead I took a shortcut.

Fixes:

1. The wind vane part (on analog pin A0) starts working only when I connect the I2C vcc pin to ***5 volts*** pin instead of 3.3 volts pin of UNO.

2. Had to ditch the https://github.com/switchdoclabs/SDL_Weather_80422 library's wind_speed reading method and adopting and merging into the http://cactus.io/hookups/weather/anemometer/davis/hookup-arduino-to-davis-anemometer-wind-speed code and adding up the wind_gust function from https://github.com/sparkfun/Weather_Shield/blob/master/Firmware/Weather_Shield_Weather_Station_V12/Weather_Shield_Weather_Station_V12.ino makes the anemometer with rain-bucket with the exact same setup fully functional.


body:
I'm new to Arduinos but researched thoroughly before buying one. Just for context I'm an IT Professional with 20 years in the game, I'm comfortable with Linux/Unix, Windows, Raspberry Pi's, electronics, hardware, software and monitoring/switching COM ports.

I've purchased my first Arduino (actually a Elegoo Uno R3 clone) and have just tried it out of the box connected to two different systems; one Windows 7 64bit Enterprise the other Kubuntu. Despite having the correct COM port selected on both I'm getting similar error messages:

    **avrdude: ser_open(): can't open device "\\.\COM15": The system cannot find the file specified.**

or

    **avrdude: ser_open(): can't open device "\\.\COM6": Access is denied.**

    Problem uploading to board. See http://www.arduino.cc/en/Guide/Troubleshooting#upload for suggestions.

Yes I have tried different COM ports.

Yes I have tried turning off Firewalls

Yes I have tried different USB cables.

I have a solid green LED and a intermittently blinking orange LED.

The suggested Troubleshooting guide + many Forum Threads do not seem to cover this exact error I'm encountering - well they do but they tend to be people with the simple issue of them not selecting the correct COM port or having the same COM port tied up with another task. Then choose the correct port and it works. I'm confident I have the correct COM port and when I click Get Board Info it pulls down the correct board information and serial number etc.

On the Linux system I was seeing a similar behavior with slightly different wording: Permission Denied

On my Windows 7 system I run as a Standard User (as one should, not as an Administrator), but regardless I have tried running the Arduino application normally and as an Administrator user but it has the same result. And it seems strange that it encounters the same style of error across multiple different operating systems.

Have I just been really unlucky and got a dud for my first Arduino or am I missing something obvious?

Thanks for your time and help.

title: First Arduino Uno - Immediate Problems

Answers: 1

body:
On Linux "Permission Denied" generally means one of two things:

1. You're not in the `dialout` group (or you haven't logged out and logged in since), or
2. Something else is using the serial port.

For 1:

    sudo usermod -a -G dialout ashley
    <log out or reboot>

For 2:

The most common culprit is `ModemManager`. The simplest cure is to uninstall it:

    sudo apt-get remove modemmanager


body:
C:\Users\MGMCETIT\Desktop\Dumpster\Dumpster.ino: In function 'void loop()':

C:\Users\MGMCETIT\Desktop\Dumpster\Dumpster.ino:40:28: warning: ISO C++ forbids converting a string constant to 'char*' [-Wwrite-strings]

     if(esp8266.find("+IPD,"))

                            ^

title: I have this compilation error:

Answers: 0


body:
I'm a Arduino newbie. I have an Electric meter with an RS485 output. I want to get the MeterID value over the RS485 module and the Arduino. I just have document from manufacturer.

    Sent by computer : 68 99 99 99 99 99 99 68 01 02 67 F3 C3 16.
    Return from meter : FE 68 99 99 99 99 99 99 68 81 08 67 F3 A6 9B 34 4B 33 33 6F 16.

My Arduino code:

    #include <SoftwareSerial.h>

    #define SSerialRX        10
    #define SSerialTX        11
    #define SSerialTxControl 3
    #define RS485Transmit    HIGH
    #define RS485Receive     LOW

    SoftwareSerial RS485Serial(SSerialRX, SSerialTX);
    byte request[] = {0x68, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x68, 0x01, 0x02, 0x67, 0xF3, 0xC3, 0x16};
    int byteRead;

    void setup()
    {
      Serial.begin(9600);
      RS485Serial.begin(1200);
      pinMode(SSerialTxControl, OUTPUT);
      digitalWrite(SSerialTxControl, RS485Receive);
      delay(20);
      Serial.println("Get Meter Address App");
    }
    void loop()
    {
      digitalWrite(SSerialTxControl, RS485Transmit);
      RS485Serial.write(request, sizeof(request));
      delay(2000);
      digitalWrite(SSerialTxControl, RS485Receive);
      delay(2000);
      if (RS485Serial.available())
      {
        byteRead = RS485Serial.read();
        Serial.println(byteRead, HEX);
      }
    }
Serial Monitor show:
[![enter image description here][1]][1]

I'm using combo like this topic [modbus-rtu-controller-monitoring-with-arduino-and-rs485-module][2]. My code is in C# below. I used the code before and it worked fine, but on the computer I use a COM port (Baudrate 1200, data 8bits, Parity EVEN, Stopbit 1) with an RS485-R232 converter:

    #Send data
    dataOUT = WriteData("68 99 99 99 99 99 99 68 01 02 67 F3 C3 16");
    serialPort_Meter.Write(dataOUT, 0, dataOUT.Length);

    #WriteData method
    private static byte[] WriteData(string hex)
    {
    return hex.Split(' ').Select(s => Convert.ToByte(s, 16)).ToArray();
    }

    #Read data
    private static string ReadData(SerialPort serial)
    {
    byte[] buffer = new byte[serial.BytesToRead];
    serial.Read(buffer, 0, buffer.Length);
    StringBuilder sb = new StringBuilder();
    for (int i = 0; i < buffer.Length; i++)
    sb.AppendFormat("{0:X2} ", buffer[i]);
    return sb.ToString();
    }

  [1]: https://i.stack.imgur.com/CM66Q.jpg
  [2]: https://arduino.stackexchange.com/questions/50645/modbus-rtu-controller-monitoring-with-arduino-and-rs485-module

title: Electric meter with Arduino and RS485 module

Answers: 1

body:
Using [readBytes][1] would do the same as your C# code. `readBytes` is blocking. It will wait for every byte until timeout. Default timeout is 1 second. If the count of bytes is smaller then the size of the buffer, it will wait a second after the last byte received. You can set the timeout with `RS485Serial.setTimeout(500);` (500 milliseconds for example).

    void loop()
    {
      digitalWrite(SSerialTxControl, RS485Transmit);
      RS485Serial.write(request, sizeof(request));
      RS485Serial.flush();
      digitalWrite(SSerialTxControl, RS485Receive);
      int recvLen = RS485Serial.readBytes(buffer, sizeof(buffer));
      for (int i = 0; i < recvLen; i++) {
        Serial.println(buffer[i], HEX);
      }
    }

  [1]: https://www.arduino.cc/reference/en/language/functions/communication/stream/streamreadbytes/


body:
I have an Arduino connected to a 4-20 mA sensor through a current to voltage converter. When connected to the power supply the sensor reading fluctuates, as soon as I also connect it to a USB port it stabilizes and gives a correct reading (tested with other reader).

My main code is:

```c++
#include <Arduino.h>
#include "Display.h"

#define MINIMUM_DEWPOINT -100
#define MAXIMUM_DEWPOINT 20
#define AVG_READING_SIZE 20

float dewPoint;
uint8_t recordIndex = 0;
uint16_t analogReadingValue[20];
int sensorMin = 0;
int sensorMax = 1023;
int sensorValue = 0;

void setup()
{
 Serial.begin(9600);
 Display::init();

 for(uint8_t i = 0;i<AVG_READING_SIZE;i++)
 {
  analogReadingValue[i] = 0;
 }
}

uint16_t getAvg(uint16_t *arr,uint8_t numberOfElements)
{
 uint32_t sum = 0;
 for (uint8_t i = 0 ; i < numberOfElements ; i++)
 {
  sum += arr[i];
 }
 return  (uint16_t)(sum / numberOfElements);
}

void loop()
{
 analogReadingValue[recordIndex] = analogRead(A0);
 dewPoint = map(getAvg(analogReadingValue,AVG_READING_SIZE), sensorMin, sensorMax, MINIMUM_DEWPOINT, MAXIMUM_DEWPOINT);
 recordIndex++;

 if(recordIndex==AVG_READING_SIZE)
 {
  recordIndex = 0;
 }

 Display::displayDewpoint(dewPoint);
 Serial.println(dewPoint);
 Serial.println(getAvg(analogReadingValue, AVG_READING_SIZE));
 delay(2000);
}
```

My circuit diagram is:
[![enter image description here][1]][1]

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

title: Arduino analogRead fluctuates from sensor unless USB connected

Answers: 2

body: Apparently 5V reference on the 5V pin was the issue as 5V was only supplied to the Vin pin and it was referencing to 0V. Swapping the power supply from Vin to 5V solved the issue

body: You need a decoupling ceramic capacitor between A0 and GND. 100nF should work just fine.


body:
I am trying to send MPU9250 sensor data to Pubnub IOT platform using node mcu, but not able to do it since the sensor data is not in JSON format. I know about publishing string but don't know about variable.

About Pubnub Library - https://github.com/pubnub/arduino

This is the part which I need help in:-

    IMU.readSensor();

    PubNonSubClient *pclient = PubNub.publish(pubchannel, IMU.getAccelX_mss());

But above line has error so how do i send imu sensor data to pubnub? All connections are right and sensor is working since I tested it.

title: How to upload sensor data on pubnub IOT with JSON Format?

Answers: 1

body:
This is the format which helped me to upload the data successfully. I didn't knew what JSON format was and got stuck. In case if someone stumbles on a similar problem.

    char buf[5] = {};

    sprintf(buf, "\"%d\"", IMU.getAccelX_mss());

    PubNonSubClient *pclient = PubNub.publish(pubchannel, buf);


body:
I have an analog light sensor working on my Micro Pro Leonardo board. I want to reach a part of my code which include keyboard presses where it monitors to see when an LED flashes and then continues the code from there.

Could someone give me a code example of how I can do that?

Currently I'd have something like....

      Keyboard.write(KEY_RETURN);
      delay(800);
      Keyboard.write(KEY_TAB);
      delay(150);
      Keyboard.write(KEY_TAB);
      delay(150);
      Keyboard.write(' ');
        }

    //Code here to wait until LED flashes, registers as 30 or less on the light sensor. Then carry on with code below once this happens

      BootKeyboard.press(KEY_LEFT_GUI);
      BootKeyboard.press('r');
      delay(40000);
      BootKeyboard.releaseAll();
etc

I know the light sensor is `AnalogValue = analogRead(A0);` and I assume it's some kind of "If" statement which loops until the value because less than what is defined but have no idea how this would be written.

title: Light Sensor - how to wait for specific setting then continue on Leonardo?

Answers: 1

body:
One method:

while (analogRead(A0) < setting){
// sit in this loop taking readings until get one that is >= to setting
}


body:
I want to receive data from GPS Neo 6m to Arduino and want to sent through LoRa (E32 433T30D).

GPS RECEIVE AND LORA SEND code

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

    static const int RXPin = 4, TXPin = 5;
    static const int loraRXPin = 2, loraTXPin = 3;
    static const uint32_t GPSBaud = 9600;
    static const uint32_t loraBaud = 9600;

    // The TinyGPS++ object
    TinyGPSPlus gps;

    // The serial connection to the GPS device
    SoftwareSerial ss(RXPin, TXPin);
    SoftwareSerial lora(loraRXPin, loraTXPin);

    void setup(){
      Serial.begin(9600);
      ss.begin(GPSBaud);
      ss.println("KATHE");
      lora.begin(loraBaud);
      lora.println("ASHOK");
    }

    void loop() {
      // This sketch displays information every time a new sentence is correctly encoded.
      while (ss.available() > 0){
        gps.encode(ss.read());
        if (gps.location.isUpdated()){
          ss.listen();
          Serial.print("Latitude= ");
          Serial.print(gps.location.lat(), 6);
          Serial.print(" Longitude= ");
          Serial.println(gps.location.lng(), 6);
          lora.listen();
          lora.print("Latitude= ");
          lora.print(gps.location.lat(), 6);
          lora.print(" Longitude= ");
          lora.println(gps.location.lng(), 6);
        }
      }

      }

    LORA RECEIVE CODE is

    #include <SoftwareSerial.h>

    SoftwareSerial mySerial(2,3); // RX, TX

    void setup() {
      // Open serial communications and wait for port to open:
      Serial.begin(9600);
      while (!Serial) {
        ; // wait for serial port to connect. Needed for native USB port only
      }

      Serial.println("Goodnight moon!");

      // set the data rate for the SoftwareSerial port
      mySerial.begin(9600);
      mySerial.println("Hello, world?");
    }

    void loop() { // run over and over
      if (mySerial.available()) {
        Serial.write(mySerial.read());
        //Serial.println(" ");
      }
      if (Serial.available()) {
        mySerial.write(Serial.read());

      }
    }

Here I'm not getting gps data to the LoRa receiver.
Please help me to overcome this problem.

title: Gps with Lora (E32 433T30D)

Answers: 1

body:
Lora we can connect directly to the arduino serial ports(0,1)- Lora Tx is connected to the arduino Rx and Lora Rx is connected to the arduino Tx. (this is for receiving data from arduino and must be connected these pins after uploading the code).
(2,3) of other arduino to receive data to arduino from Lora.
For sending there is no code like Bluetooth. And for receiving the following code helps you..

#include <SoftwareSerial.h> SoftwareSerial mySerial(2,3); // RX, TX void setup() { // Open serial communications and wait for port to open: Serial.begin(9600); while (!Serial) { ; // wait for serial port to connect. Needed for native j for the SoftwareSerial port mySerial.begin(9600); mySerial.println("Hello, world?"); } void loop() { // run over and over if (mySerial.available()) { Serial.write(mySerial.read()); //Serial.println(" "); } if (Serial.available()) { mySerial.write(Serial.read()); } }


body:
   This is my Master's code.

    #include <nRF24L01.h>
    #include <RF24.h>
    #include <RF24_config.h>
    #include <SPI.h>

    RF24 radio(7, 8);

    const byte address[6] = "00001";
    char text[20] = "";
    int flag;
    char *p;
    int i;

    void print();
    void read();
    void rfwrite();
    void setup() {
      Serial.begin(9600);
      radio.begin();
      radio.setDataRate(RF24_1MBPS);
      radio.setChannel(1);
      radio.openWritingPipe(address);
      radio.setPALevel(RF24_PA_MIN);
      radio.stopListening();

      flag = 0;
      p = text;
    }

    void loop() {

      if (Serial.available()) {
        read();

      }
      if (flag) {
        print();
        rfwrite();

      }

    }

    void print() {
      Serial.println(text);
      flag = 0;
    }

    void read() {
      p = &text[0];
      for (i = 0; Serial.available(); p++, i++) {
        *p = Serial.read();
      }
      text[i + 1] = '\0';
      flag = 1;
    }

    void rfwrite() {

      radio.startWrite(text, strlen(text)+1);

    }

Slave code:

    #include <nRF24L01.h>
    #include <RF24.h>
    #include <RF24_config.h>
    #include <SPI.h>

    RF24 radio(7, 8); //ce,csn

    const byte address[6] = "00001";
    char text[20] = "";
    int  i;

    void write_to_array();
    void print();
    void setup() {
      Serial.begin(9600);
      radio.begin();
      radio.setDataRate(RF24_1MBPS);
      radio.setChannel(1);
      radio.openReadingPipe(0, address);
      radio.setPALevel(RF24_PA_MIN);
      radio.startListening();
    }

    void loop() {
      while (radio.available()) {

        write_to_array();
        print();

      }

    }

    void write_to_array() {
      radio.read(text, strlen(text)+1);

    }

    void print() {
      Serial.println(text);

    }

I edited the code and made it with an array like @Kwasmich said. But now some end characters are not getting printed. When I type `1234567890-=` into the transmitter, only `1234567890-` gets printed. When I type a new set of characters following that, the missing `=` gets printed. Also, this happens only on the second transmission after I upload the code to the Arduino. The first set of characters are received and printed correctly. How do I fix this? Will flushing the buffer help(I doubt this because the first transmission is received correctly)?

title: nRF24L01 - leaves out end characters during transmission

Answers: 2

body:
**This is not a proper solution explaining why the issue occurred in the first place but merely a workaround to anyone encountering the same problem.**

There is another function in the RF24 library called startWriting(). The description in the library was not clear about the differences between this and write(). But I noticed that the last character was missing with the use of startWriting(). So I simply changed

    radio.read(&text, sizeof(text));
in the master to

     radio.read(&text, sizeof(text+1));
and voila!
The code now does its intended purpose!!

body:
You are riding on a wave of undefined behavior. sizeof returns the size of the underlying type. In your case char. Which is 1. What you really need is the propper allocated array `char text[32] = ""` and the required length of the string using `strlen(text) + 1`. +1 to also transmit the nul terminator of the string.

The maximum string Length that can be transmitted using nRF24L01 is 32 bytes. Because of the mandatory nul termination of a string you can send at most 31 characters as a valid string.

Fun fact: The same limitation of 31 characters applies to file name langths on the classic Mac OS at least up to 7.x and also on the Amiga DOS/Workbench.


body:
Does anyone knows how to calibrate AJ-SR04M using the Arduino? I am working on AUV. underwater reading from current code; it is giving continuous 20cm while moving inches. [http://shop2.hanjindata1.cafe24.com/product/aj-sr04m-ultrasonic-ranging-module/206/][1]

  [1]: http://shop2.hanjindata1.cafe24.com/product/aj-sr04m-ultrasonic-ranging-module/206/

title: Ultrasonic sensor underwater calibration

Answers: 1

body:
If I understand your question correctly, your problem is probably that the working range of the [AJ-SR04M][1] sensor is **20cm - 500cm**.

The sensor uses the same transducer to create the sound pulse and to listen for the echo.  It needs time to switch from one mode to the other, which explains why your sensor can't measure distances of less than 20cm.

The speed-of-sound in water is about 5x the speed of sound in air.  More specifically, at 20 degrees Celsius the speed-of-sound in air is approximately 343 meters per second, while the speed-of-sound in water is approximately 1482 meters per second.

This will cause the sensor to 'under-report' the distance in water.  The minimum distance will also be approximately 5x the minimum distance in air.

As an aside, you will also need to make allowance for the differences in the characteristic impedance and absorption between sound and water.

It's worth reading the paper [Underwater Sound][2] by P. Vigoureux (Proceedings of the Royal Society of London. Series B, Biological Sciences, Vol. 152, No. 946) for a discussion of all the factors involved.

  [1]: https://www.santy.cz/senzory-c24/arduino-hc-sr04-modul-vzdalenost-mereni-vodotesny-waterproof-i320/
  [2]: https://www.jstor.org/stable/75361?seq=1#page_scan_tab_contents


body:
I was trying to make a code which did something every time a light dependent resistor was covered up by using interrupts so I could be running a different code at the same time.
This was my finalised code:

    #define LIGHT 2

    void setup() {
        Serial.begin(9600);
        pinMode(LIGHT, INPUT);
        attachInterrupt(digitalPinToInterrupt(LIGHT), fall, FALLING);
    }

    void loop() {
        Serial.print("Hello");
        Serial.println();
        delay(1000);
    }

    void fall(){
        Serial.print("Light Covered!");
        Serial.println();
    }
I have tested my ldr circuit (5V into the ldr with a 10k pulldown resistor) and it reliably sits over the digital read boundary so I don't need to use analog read. It also seems to have no bounce as if I read it by outputting a message every time it reads it as high and then waiting until it goes low it only reads once every time I cover it and uncover it. However for some reason the code above which uses interrupts seems to print light covered 3-7 times every time I cover it. I am quite new to arduinos and C although I have used python for a while so sorry if it is a silly noob mistake.

title: Multiple readings from one change on a light sensor with interrupts

Answers: 0


body:
**The background:**

----

I bought a "dumb" 8-pin 4x4 keypad for use in a project. (This one: https://www.sparkfun.com/products/14881
It has a wire connected to each row, and a wire connected to each column. When you press a key, it connects a row pin and a column pin. You have to use GPIO outputs to send +5V down one row/column at a time, and then use inputs to look for a HIGH on a corresponding set of pins from the other dimension, which indicates a connection between a specific row/column pair.)

I found a framework, MultitapKeypad, that at first appeared perfect. It is a nice clean C++ object with a simple main method, getKey(), that returns a struct with information about the key the user pressed. It detects long presses and repeat presses, things I plan on using.

However, when I looked into it I found things were not as good on the inside. The getKey method uses a while (no key pressed) loop that loops forever. The author's solution to not locking up the Arduino any time you are waiting for a keypress is to provide a callback function that the library calls from the while loop.

The idea of turning a sketch's control flow completely upside down and having to do all your app's event handling from the callback of a keypad class just seems wrong. Then control flow from the app's main loop has to go through the keypad's callback when I'm waiting for keys, or through some other flow otherwise.

The framework also makes use of delay() in it's debouncing, another no-no for apps that manage multiple things at once.

I was therefore thinking of writing my own keypad handler.

My current project, a power controller for lights, chargers, and a humidity controlled warm air dryer will run all of those things simultaneously. It has a back-lit LCD for a display, and uses a motion sensor and photoresistor to turn lights on when it detects motion in low light.

It puts the LCD to sleep if it doesn't detect motion or any user input from it's various switches for an extended period.

When I integrate a keypad into the project I would also like to add keypresses to the list of things that keeps the display awake. I don't see an easy way to do that with the LCD library I was using.

----

**My proposed design:**<br>

I was thinking of wiring the keypad with all of the row pins connected to a 9th pin with diodes, anodes pointed towards the 9th pin. I'd set that 9th pin up in INPUT_PULLUP mode and attach it to an interrupt, set to trigger on FALLING signal (or perhaps CHANGE. See below.) The row pins would all also be configured as INPUT_PULLUP. The column pins would all be set up as outputs, and driven LOW.

When the user pressed a key, it would connect one of the column pins to a row pin. That would pull that row pin's input LOW, and also pull the interrupt pin LOW, triggering the ISR (Interrupt service routine).

In the ISR I would use port registers to switch all the column pins to HIGH, and then toggle one column pin at a time back to LOW, looking for a row pin to also drop LOW. If one and only one column going LOW triggers one and only one row to go LOW, I know only one button is pressed, and know the row/column combo, and hence the key that was pressed. If multiple columns trigger a row, or more than one row drops to LOW, I know more than one key is pressed. (I could use that info to report multi-key presses if I need to, although >2 keys at a time gets messy fast.)

Once I have a key I could add the key code for that key to a simple ring buffer and set a "key ready" flag. (My ring buffer might contain structs with more than just a key code, like up/down events, time stamps, etc.)

The rest of my sketch could then query my keypad for "key ready" and read one or more keys as needed. I'd provide housekeeping functions for clearing the key buffer, a way to detect buffer overflows, etc.

I guess I'd actually want interrupts on both falling and rising state change, so I could detect key up events and track the duration of key presses.

I'd also need to add debouncing of some sort or another. I could use a simple RC filter on each input pin, but I don't have a lot of room left on my project breadboard and that would require 4 capacitors and 8 resistors.

From what I've read the millis() function is a little slow and best avoided in ISR routines. Is there a fast alternative to get the current clock value directly in an ISR? If so I could use software to debounce the keys.

Are there any obvious flaws in my plan? Does using an ISR like this sound reasonable? The Keypad actually doesn't short the row/column pins together. It uses variable resistances between the row/column combinations, I guess so that you can use a voltage divider and an analog input to figure out which key was pressed based on the measured voltage. The docs for the keypad say the resistance for a row-column pair varies from 10 to 625 ohms. I'm assuming that the key resistance is low enough that even with signal diodes in the circuit, the closed switch resistance should be enough to pull my interrupt pin and my row pins to LOW.

I suppose I could also tie all the columns and all the rows together, hook it to a voltage divider, and see if I could decode the key using an analog input. That would let me do all that decoding with a single pin.

Alternatively, are there other keypad frameworks that handle 3x4 and 4x4 keypads and offer things like repeated taps, long taps, and allow you to trigger events on ANY key press (So I could keep my LCD display awake.)

title: Does this sound like a good approach to decoding a dumb keypad?

Answers: 1

body:
[![enter image description here][1]][1]I made a simple RF remote control using a very similar method with a 4x4 kepyad, with diodes connected together to trigger an interrupt and read a keypress. After any keypress, the interrupt woke the processor (unmodified 8 MHz Promini with Atmega328P), it used keypad.h library to detect the pressed key, sent that out via a short RF burst (433 MHz transmitter) using the library (8 years ago now, drawing a blank on the name) that became the Radiohead library (find it on github), then went back to sleep. Lasts about a month on 2000mAH (or so?) LiPo battery that is secured to the bottom of the board.

As I recall, I had to write the outputs opposite of their normal state before going to sleep mode for the interrupt to work correctly, then restore them before reading the keypad.h value. Then put them back in opposite state before going back into sleep mode.  Works well, but I only transmit one key at a time.  I don't have complete details here, can post them when I get home later.  You can see a picture of the remote at the bottom of this site - sorry about the scrolling, I managed to overwrite my index.html file that had link/tabs to jump to the various areas that my son did up for me.  http://www.crossroadsfencing.com/BobuinoRev17

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


body:
I am using an arduino to create a device that outputs a specific current and voltage. I was wondering if there are any devices out there such as dc/dc buck boost converters that can be controlled by arduino to output desired powers. I am looking for something rated for at least 50 watts  that can carry at least 3 amps of current.

Thank you all in advance!

title: Can you use an Arduino to control the output current and voltage of a DC/DC converter?

Answers: 1

body:
Yes, and it's actually far simpler than most realize. I've tried digitpots, but they are quite un-linear and only handle 5v, unless you spend $$$. Early on, i had soldered an LDR in parallel to a buck converter's adjustment pot, and fed that PWM. It worked to somewhat adjust the vout, but had a lot of ripple and was not linear. I had gotten an MCU-controlled linear PSU going, that wasn't too hard, but i always wanted a buck. Just recently, i've found an awesome method and built several MCU-controlled SMPSs.  You don't have to have any special parts or de-solder anything!

Basically, you:

  * use a buck/boost (or dual) with a built-in V-adj potentiometer.
  * use a lowpass to convert the MCU's PWM output into a 0-vcc signal.
  * feed smoothed PWM voltage to a unity gain opamp to buffer available current.
  * create a common ground between MCU and SMPS.
  * feed the buffered 0-vcc control through a resistor into the pot's wiper, ~200-1k.
  * the amount of "injected" voltage will be inversely proportional to the SMPS's output voltage.

Since most SMPS's feedback is in the area of 1-2.5v, the 0-3.3/5v output of the MCU works well to provide or take away feedback from the regulator. The best part about this scheme is that output voltage regulation is maintained by the SMPS's hardware, the MCU just sets an offest. In short, you can set it to 10v via the MCU, attach a big load, and the voltage stays at 10v!

I've used this technique on the xl4005 and the xl4015, but i would imagine it would work for just about any common driver package.


body:
I'm not sure if this is correct place to post this, if not PLEASE redirect me to the proper page, as this matter is quite pressing to me.

My entire day was spent researching different methods of inter-Arduino communication, and for my project, using 4G/LTE/LTE-M is clearly the route I need to take. However, I cannot find an answer to my problem:

I see a lot of information about how to continuously upload information to a IoT service/provider, or to a dashboard website. That's great. Problem is, I need an Arduino with a LTE shield to talk to another Arduino with a LTE shield. Suddenly the internet shuts down and I can find next to nothing about communicating between two Arduino's using LTE shields, much less keeping that connection active.

Of course this could be accomplished by uploading data to a IoT site via Arduino A, and retrieving stored information via Arduino B, but I'm afraid that will induce too much latency into my system. I need this to be as FAST as possible.

The module I have my eye set on currently is this one: https://www.cooking-hacks.com/documentation/tutorials/4g-gps-lte-wcdma-hspa-3g-gprs-shield-arduino-raspberry-pi-waspmote-tutorial/#step10

Is there a way to connect directly to another LTE device? How to I keep that connection always active? I know this question is a little broad, but I don't even know where to look! Internet connectivity is not my strong suit. From what I've gathered, I need to set up one Arduino as a server and the other as client. UDP may be the option I'm looking for, but I'm not totally sure. Every single tutorial/explanation I've seen is connecting directly to a webpage or other online service and NOT another LTE device.

Any help or direction is greatly appreciated, thank you!

title: How to achieve active 4G LTE communication?

Answers: 0


body:
So I just got my two ESP8266/ESP-12E WiFi development boards in the mail as I am trying to set up a few home automation devices in my house. I've gotten much further than I thought I would today, considering this is my first foray into working with circuits that involve microprocessors/WiFi, but I've run into a problem that I can't find a solution to myself.  Forgive me if there is another question similar to this, but I could not find it and this seems like the best place to ask.

I am using a tutorial/template program that Rui Santos from Random Nerd Tutorials was kind enough to create ( https://randomnerdtutorials.com/esp8266-web-server/ ), and although we have (as far as I can tell) identical boards, operating systems and Arduino code, I keep getting an HTML page that is text only, with none of the CSS or HTML elements showing.  It should look like this:

[![expected outcome][1]][1]

However, I am getting a page that looks like this:

[![outcome][2]][2]

His serial monitor is giving this response:

[![his serial monitor][3]][3]

My serial monitor is giving me this response:

[![my serial monitor][4]][4]

  [1]: https://i.stack.imgur.com/5d5OA.png
  [2]: https://i.stack.imgur.com/531q1.png
  [3]: https://i.stack.imgur.com/jgXDf.png
  [4]: https://i.stack.imgur.com/hkodX.png

I've tried putting `client.println("Content-type:text/html");` in a few places to see if it would help display the page, but to no avail.  Any help with getting this little program/website running would be greatly appreciated.

Thanks for your time!

title: My ESP8266 web server is only displaying text, even after ensuring content type is text/HTML

Answers: 2

body:
Don't use the low-level tools to handle http, use the built-in http tools. They  make creating http responses trivial. No more concatenating headers or worrying about client status; it provides a nice clean function ex:` server.send(404, "text/plain", message);` and nice subscription method: `server.on()`.

Checkout its usage on one of the Arduino ESP8266's built-in examples:
https://github.com/esp8266/ESPWebServer/blob/master/examples/HelloServer/HelloServer.ino

body:
The use of HTTP here is fairly straight forward so I think printing out your own HTTP headers is OK, you just need to be very specific with the order and send exactly what the browser expects. Without seeing your code, my guess is that you're sending out a blank line to the client somewhere prior to the 'Content-type: text/html' line being sent or that you're not printing an empty blank line somewhere after the Content-type line is being sent. If your browser (the client) doesn't receive the HTTP protocol commands that it expects in the order that it expects, then it will default to displaying EVERYTHING you send it as either plain text or an HTML document. To illustrate exactly what is supposed to be sent to the browser in this example:

    HTTP/1.1 200 OK
    Content-type:text/html
    Connection: close

    <HTML>....

Note that there should be a empty line printed out after the Connection: close line and before you send any HTML. There should be nothing else sent to the client prior to the HTTP/1.1 200 OK line being sent and before your HTML code starts. If you don't follow the protocol, your browser will probably default to displaying everything plain text as you're seeing.

Something else I noticed in the example code, there is no space between Content-type: and text/html. This is unusual, but I guess it [doesn't break the protocol][1] and Firefox and Chrome handle it ok in my testing. Still, it could cause issues if a browser doesn't handle that properly so you might just try adding a space between the header and it's value.

  [1]: https://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html#sec4.2


body: I need to measure linear speed of a body which travels 1000 m forward and backward recursively. How can I use an MPU6050 with Arduino Nano to measure the linear speed of a moving object? (the object does not have any rotation). I tried my best, but I was not able to measure linear speed, can I get sample source code?

title: How can I use an MPU6050 with Arduino to measure linear speed?

Answers: 0


body:
I am working with an XBee module, so naturally, I started my void loop with AT command testing.

    void loop() {
        digitalWrite(Sleep_Rq,LOW);

A +++ with a guard time of 1 sec before and after it, sets xbee module in command mode.

    delay(1000);
    xbeeSerial.write("+++");              // Enter Command Mode
    delay(1000);

This part of the code, puts the serial data into string variable x in the form of a String.

    while(xbeeSerial.available()) {
        x = xbeeSerial.readString();
    }

Serial.println() is returning OK onto the serial monitor.

    Serial.println(x);

But when I compare x with OK nothing happens, 1 doesn't appear on the serial monitor.

    if(x=="OK")
      {
       Serial.println(1);
      }
    }
I tried swapping "OK" with 4F4B (ascii equivalent of OK), 20299 (decimal value). I also  tried changing datatype of x from String to word and compared x with 0100111101001011.
I also tried changing the IF condition as,

    if(Serial.println(x)=="OK")
        {
         Serial.println(1);
        }
and many more techniques with no luck to be found.

title: Serial.read() doesnt work in IF statement

Answers: 1

body:
Your problem is that you are assuming that all you see in the Serial Monitor is all there is. You see "OK", so you expect to compare the text that comes in with "OK".

However it's not. Serial communication (at least, text based serial communication) generally includes some kind of line ending marker. That could be any combination of Carriage Return (`\r`) and/or Line Feed (`\n`). Different devices use different combinations.

As it turns out the XBee uses '\r' as the line ending marker.

There are two ways of dealing with it:

1. Include the line ending in your comparison (`"OK\r"`), or better,
2. Incorporate the line ending in the reading.

The second point there involves the use of `readStringUntil()`:

    String x = xbeeSerial.readStringUntil('\r');

That is a more reliable way of reading the response since it reads everything up to the line ending, rather than reading until it times out with nothing else to read. You should find your whole program runs smoother with that method.


body:
I have a project where I have to combine 4 sensors and get data wireless via Bluetooth (HC05). I just want help with combining just 1 sensor sketch and the Bluetooth sketch. I want the data from the temperature sensor to be displayed on my phone.

Temperature sensor code:

    #include <OneWire.h>
    #include <DallasTemperature.h>

    #define ONE_WIRE_BUS 2

    OneWire oneWire(ONE_WIRE_BUS);

    // Pass our oneWire reference to Dallas Temperature.
    DallasTemperature sensors(&oneWire);

    void setup(void)
    {
      // start serial port
      Serial.begin(9600);
      Serial.println("Dallas Temperature IC Control Library Demo");

      // Start up the library
      sensors.begin();
    }

    void loop(void)
    {
      // call sensors.requestTemperatures() to issue a global temperature
      // request to all devices on the bus
      Serial.print(" Requesting temperatures...");
      sensors.requestTemperatures();
      Serial.println("DONE");

      Serial.print("Temperature is: ");
      Serial.print(sensors.getTempCByIndex(0));
      delay(1000);
    }

    Bluetooth code:

    #include <SoftwareSerial.h>
    SoftwareSerial BT(11, 10);
    int ledPin = 8;
    int state = 0;

    void setup()

    {
    pinMode(ledPin, OUTPUT);
    Serial.begin(9600);
    BT.begin(9600);
    }

    void loop() {
      if(BT.available() > 0){
      state = BT.read();

      }
        if (state == '0'){
          digitalWrite(ledPin, LOW);
          BT.println("LED: OFF");
          state = 0;
        }
        else if (state == '1'){
          digitalWrite(ledPin, HIGH);
          BT.println("LED: ON");;
          state = 0;

        }
    }

title: Need help combining two sketches (HC05 and temperature)

Answers: 1

body:
Instead of writing it all out, I give some tips:

- First combine the content of both `setup` functions. You can remove duplicate lines (e.g. `Serial.begin(9600);` is needed only once. Keep the order in a logical way.

- Than combine the content of both `loop` functions. However, the delay could cause a problem. Replace this by keeping a variable with the current time, and check when it's at least a second ago you checked the temperature sensor, if so, measure the sensor (and update the variable to the current time).

So you get something like:

    unsigned long lastSensorMeasurement;

    void setup()
    {
       // Combination of both setup functions

       lastSensorMeasurement = millis();
    }

    void loop()
    {
       // Process sensor
       if (lastSensorMeasurement + 1000 >= millis())
       {
          // Code for sensor as in loop
       }

       // Process Bluetooth
       // Code for bluetooth as in loop
    }