text:
Bluetooth module with lowest latency to communicate with PC
I am making a haptic feedback glove using Arduino and HC-05 bluetooth module to communicate with PC.
There are rotary encoders on the finger which send value to PC through Arduino mega. The PC returns the force to be excerted on the finger back to Arduino which then controls the motor. The communication between Arduino and PC is established through an HC-05 module wired to Arduino and connected to PC wirelessly over bluetooth. Through COM-Port of Arduino-IDE, serial communication is established.
When the program runs, the PC (Unity) sends the force to Arduino but there is a huge latency in the order of tens of milliseconds. After Unity calculates the force, Arduino receives this force after at least 30ms (I have not measured the accurate value). In order to make sure the delay is a result of bluetooth communication, I connected the Arduino to PC using USB and the latency was reduced. This points to the fact that the delay is caused by the bluetooth.
I did some research into that and found that there is something called BLE as opposed to classic bluetooth which decreases the delay. According to this link, HC-05 which uses classic bluetooth has a latency of 100ms and BLE has a latency of 6ms.
I want to buy a bluetooth module that has BLE capability like HM-10. Before that, I wanted to know if I have understood the information correctly: i.e buying an HM-10 would decrease communication gap. Is there any alternatives to bluetooth communication (such as ethernet or wifi) which would provide low or lower latency?


text:
Not getting any signal from myoware EMG muscle sensor. The signal LED (Red LED) on the sensor is always ON
This is my first time using EMG Sensor.
I'm trying to read EMG signals from Myoware Muscle Sensor.
When I use analogRead to read analog value, the value is almost same. There is not much change in the analog value.
EMG Sensor I'm using: Myoware Muscle sensor from Advancer Technologies.
Arduino Board: Arduino Mega.
When Sensor is turned ON, the Signal LED (Red LED) on the emg sensor is always ON. (I don't know if it is supposed to be always ON or not )
I have tried placing emg sensor on both forearm and biceps, but no change in the analog value.
I really dont know what is wrong here.
This is the code:
void setup() {
  Serial.begin(9600);
}

void loop() {
  int sensorValue = analogRead(A5);
  //float millivolt = (sensorValue/1023)*5;

  Serial.print("Sensor Value: ");
  Serial.println(sensorValue);
  delay(1);
}

You are performing integer division in (sensorValue/1023)*5; this will result in 0 for any sensorValue less than 1023.  It would help to know what values were coming out of analogRead(A5)

I am getting values in the range 676 to 680 at all time. I'm not using the milliVolt value. For now I just want to  get analog values depending on the muscle contraction.

Eventually, forcing to float, ... change to :  float millivolt = (sensorValue/1023.0 ) * 5.0 ; ?

Yes I will. But for that I have to get the correct analog reading first.

I see this board ... https://learn.sparkfun.com/tutorials/myoware-muscle-sensor-kit/all but it is not the "same" ? I did not find your board.

Yes I'm using this board

Are you sure that the board in the picture above is "complete" ? It seems that it is only the MyoWare Cable board ? How did you wire the two boards ? https://cdn.sparkfun.com/assets/learn_tutorials/4/9/1/MyowareCable_ShieldStackedMuscleSensor.jpg ?

Sorry I missed to say that, When I designed the circuit in Fritzing, there was no myoware sensor board. Only cable board was available. So I choose it. Actually I'm using only the myoware sensor board.

source: Stack Exchange

license: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/4.0/

sort: votes


text:
How to drive two Stepper motors and use an Ultrasonic sensor together?
I am working on an autonomous robot using two 4-pin stepper motors, HC-SR04 ultrasonic sensor, 2 L298N motor drivers (one for each motor), and an Arduino Uno. My problem is that when I use the stepper motors with the Stepper library, only one motor works at a time. My solution was to control the one step at a time in a short period of time, which worked, however, this introduces a new problem. The ultrasonic sensor requires a delay to work, but this makes the movement of the robot quite slow and jittery as it works only by one step at a time. When I remove the delay from the ultrasonic sensor, it starts returning the correct value, but then also returning 0 right after each correct value. My solution was to ignore the returned 0, but this is not ideal.
How can I use two stepper motors at the same time and use an Ultrasonic sensor?
Here is my code:
#include <Stepper.h>
#include <Ultrasonic.h>

/*
 * Pass as a parameter the trigger and echo pin, respectively,
 * or only the signal pin (for sensors 3 pins), like:
 * Ultrasonic ultrasonic(13);
 */
 Ultrasonic ultrasonic(13, 12);
 int distance;

 int driveSpeed = 100;
 int stepsPerRevolution = 200;
 int leftMotorStep = 0;
 int rightMotorStep = 0;

 // Time interval between steps for both motors
 const int stepInterval = 10;  // Adjust as needed

 // Last step time for each motor
 unsigned long leftMotorLastStepTime = 0;
 unsigned long rightMotorLastStepTime = 0;

 Stepper rightMotor(stepsPerRevolution, 8, 9, 10, 11);
 Stepper leftMotor(stepsPerRevolution, 4, 5, 6, 7);

 void setup() {
   Serial.begin(9600);
   rightMotor.setSpeed(driveSpeed);
   leftMotor.setSpeed(driveSpeed);
 }
 void loop() {
   distance = ultrasonic.read();

   Serial.print("Distance in CM: ");
   Serial.println(distance);
   delay(250); //This delay makes the motors behave strangely

   if (distance < 15) {
     Serial.println("AVOIDING OBSTACLE!");
     // Perform obstacle avoidance behavior
     avoidObstacle();
   } else if (distance < 30) {
     Serial.println("APPROACHING OBSTACLE!");
     // Perform slow approach behavior
     slowApproach();
   } else {
     Serial.println("DRIVING!");
     // Perform normal driving behavior
     drive();
   }
 }

 void avoidObstacle() {
   // Stop the robot
   halt();

   // Rotate the robot to avoid the obstacle
   leftM();

   // Delay to allow the rotation to complete
   delay(1000);
 }

 void slowApproach() {
   // Slow down the motors
   int slowSpeed = 50;
   rightMotor.setSpeed(slowSpeed);
   leftMotor.setSpeed(slowSpeed);

   // Move the robot forward slowly
   forwardM();

   // Delay to allow the slow approach
   delay(1000);
 }

 void drive() {
   // Set the motors back to the normal speed
   rightMotor.setSpeed(driveSpeed);
   leftMotor.setSpeed(driveSpeed);

   // Move the robot forward
   forwardM();
 }

 void forwardM() {
   rightMotor.step(1);
   leftMotor.step(1);
 }
 void leftM() {
   rightMotor.step(1);
   leftMotor.step(-1);
 }
 void rightM() {
   rightMotor.step(-1);
   leftMotor.step(1);
 }
 void reverseM() {
   rightMotor.step(-1);
   leftMotor.step(-1);
 }
 void halt() {
   rightMotor.step(0);
   leftMotor.step(0);
 }

first, stop using delay()

When I don't use delay(), the Ultrasonic sensor returns 0 after every value (as mentioned int the post).

stop using the delay() function to introduce a delay ... see the blinkWithoutDelay example sketch in the Arduino IDE

Thank you, this definitely helps!

may be of interest ... https://wokwi.com/projects/327381547863769683

Try this code.
Here is a simulation. https://wokwi.com/projects/366108641014000641
Click on the sensor to set the distance in the simulation
NOTE: centimeters is cm, not CM.
Not tested on hardware.

// https://arduino.stackexchange.com/questions/93302/how-to-drive-two-stepper-motors-and-use-an-ultrasonic-sensor-together

#include <Stepper.h>
#include <Ultrasonic.h>

/*
 * Pass as a parameter the trigger and echo pin, respectively,
 * or only the signal pin (for sensors 3 pins), like:
 * Ultrasonic ultrasonic(13);
 */

 Ultrasonic ultrasonic(13, 12);

 int distance;

 int slowSpeed          =  100;
 int driveSpeed         = 1000;
 int stepsPerRevolution =  100;
 int leftMotorStep      =    0;                         // current step speed and direction
 int rightMotorStep     =    0;

 int stepSpeed          =   10;                         // this is the motor speed

 const int stepInterval =    1;                         // Time interval between steps for both motors

 unsigned long leftMotorLastStepTime  = 0;              // Last step time for each motor
 unsigned long rightMotorLastStepTime = 0;

 Stepper rightMotor(stepsPerRevolution, 8, 9, 10, 11);
 Stepper leftMotor (stepsPerRevolution, 4, 5,  6,  7);

 void setup() {
   Serial.begin(9600);
   rightMotor.setSpeed(1);
   leftMotor. setSpeed(1);
 }

 void loop() {

  distance = ultrasonic.read();

  Serial.print("Distance in cm: ");
  Serial.print(distance);  Serial.print("\t");

  switch (distance) {                              // used switch/case for cleaner looking code
    case 0 ... 14:
      Serial.println("avoid");
      avoidObstacle();                             // Perform obstacle avoidance behavior
      break;

    case 15 ... 29:
      Serial.println("approach");
      slowApproach();                              // Perform slow approach behavior
      break;

    default:
      Serial.println("drive");
      drive();                                     // Perform normal driving behavior
      break;
  }

  rightMotor.step(rightMotorStep);                 // this actually moves the motors
  leftMotor .step(leftMotorStep);
}

 void avoidObstacle() {
   halt();                                          // Stop the robot
   leftM();                                         // Rotate the robot to avoid the obstacle
 }

 void slowApproach() {
   rightMotor.setSpeed(slowSpeed);                  // Slow down the motors
   leftMotor. setSpeed(slowSpeed);
   forwardM();                                      // Move the robot forward slowly
 }

 void drive() {
   rightMotor.setSpeed(driveSpeed);                 // Set the motors back to the normal speed
   leftMotor. setSpeed(driveSpeed);
   forwardM();                                      // Move the robot forward
 }

 void forwardM() {
   rightMotorStep =  stepSpeed;                     // select direction of step only
   leftMotorStep  =  stepSpeed;                     // do not move motor
 }                                                  // actual stepping is done at end of loop()
 void leftM() {
   rightMotorStep =  stepSpeed;
   leftMotorStep  = -stepSpeed;
 }
 void rightM() {
   rightMotorStep = -stepSpeed;
   leftMotorStep  =  stepSpeed;
 }
 void reverseM() {
   rightMotorStep = -stepSpeed;
   leftMotorStep  = -stepSpeed;
 }
 void halt() {
   rightMotorStep =  0;
   leftMotorStep  =  0;
 }

Thank you, this is really helpful!

all_licenses: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/4.0/


text:
How can I play sound on Arduino with an SD card?(I have a problem with the sound)
I am working on a "personal assistant" with Arduino and I am having trouble playing sound from an SD card... I am using a shield called "Easy Shield UNO" by Simkeim, and it has an SD card reader on it. It does work because I tested it through the Serial monitor, but when I try to play sound, nothing happens. (The speaker does work) Can someone please help me check my code or something to see what is wrong?
Here is the code I found online, I only changed it a bit...
#include "SD.h"
#define SD_ChipSelectPin 10
#include "TMRpcm.h"
#include "SPI.h"

TMRpcm tmrpcm;

void setup(){
 tmrpcm.speakerPin = 7;
 Serial.begin(9600);

 tmrpcm.setVolume(255);
}
void loop() {
  if(!SD.begin(SD_ChipSelectPin)) {
    Serial.println("SD card not found");
    return;
}
  else{
    Serial.println("SD card reading sucess");
    tmrpcm.play("test1.wav");
  }
}

A) Please add a link to the shield. B) Have you tried using a sample sketch that comes with the library to ensure everything works as expected?

I bought the shield while we were living in China, so it is a Chinese website. https://i-item.jd.com/59763201006.html. Yes  I tried using a sample sketch, everything works, but the sound is just two long static sounds

When I change the name of the file, then the speaker does nothing, but when I use the real name of the file, the speaker makes squeaky sounds

I see three problems with your code:

It doesn't make much sense to begin the SD card again and again in loop(). Please move that part to setup() or somewhere, where it isn't called on every loop iteration.

You shouldn't call tmrpcm.play() in every loop() iteration. It doesn't wait for the song to be finished. It just starts the playing (which is controlled by a timer interrupt) and exits. And every call of it will start the file again at its start. So by calling it again and again in fast succession you don't leave enough time for the file to actually be played, until you play again from start. To prevent that you can use an if statement to only start, if there isn't a file playing currently:
  if(!tmrpcm.isPlaying()){
      tmrpcm.play("test1.wav");
  }

You are choosing pin 7 as output pin, but you cannot choose the pin freely, because it has to be connected to the used Timer and thus being PWM capable. Thats not the case for pin 7. In the wiki of the TMRpcm library you can find the following line under "Functions":
  audio.speakerPin = 11;     set to 5,6,11 or 46 for Mega, 9 for Uno, Nano, etc.

So please connect your speaker to pin 9 and use tmrpcm.speakerPin = 9;.

Hi, thanks for the help! I did change it like you said, but it still makes that static sound... I also tried an example TMRpcm code, but my speaker still just makes a static sound? Do you think that could be related to the code or the file? Because I did try it with two other speakers and they did the same...

@RenierJr. I've looked again at the library and found, that you cannot freely choose the used pin. It has to be PWM capable and belong to the used Timer (defaults to Timer1). I added a paragraph about that in my answer

Thanks chrisl!! I did try the example code and it used pin 9, now it works, but there is a lot of static playing with the music. I will try to change the sampling rate to see if that works... Thanks again for the time you spent to help me!


text:
When I open a COM port some pins on Arduino Uno goes low for about 2 seconds
I have no idea why this is happening, but after I open COM port to talk with my Arduino (I click "Open" in RealTerm), the state of some pins goes from high to low for about 2 seconds and then goes back to high. Here's my code:
void setup()
{
  pinMode(5, OUTPUT);
  digitalWrite(5, HIGH);
  Serial.begin(9600);
}

void loop()
{
}

In this case pin 5 will behave this way. I've checked it also for pin 6 and pin 8 and they behave in the same manner. I suppose more pins act like that. Why is this happening?

That's because opening the connection to the UNO will automatically trigger a reset of the ATmega chip, hence your sketch will be executed from scratch, ie setup() will be called again then loop().

@jfpoilpret you should put that as an answer!

What you see is expected: that's because opening the USB connection to the UNO will automatically trigger a reset of the ATmega chip of the board, hence your sketch will be executed from scratch, ie setup() will be called again then your loop() repeatedly.
Hence what you observe in detail:

open USB connection from PC
open USB connection on Arduino UNO
UNO USB chip (an ATmega16u2) triggers a RESET of the MCU (an ATmega328P-PU)
On reset, the MCU sets all pins to INPUT, i.e. high impedence, hence no voltage can be measured on any pin
Then the bootloader starts, performs some intialization and starts your sketch
Your sketch executes first setup(), so your pin is put in OUTPUT mode and set to HIGH: its voltage is thus measurable (5V)
your sketch loop() gets executed "forever" i.e.until a new reset or power supply disconnection

Indeed.  Worth noting though is that this reset-on-open is ultimately due to a configurable behavior of how the PC operating system's serial API manages the control lines - though this is usual default.  Additionally, it can be disabled at the arduino end by overpowering the reset capacitor with a stronger pullup.

What is the logic behind resetting upon connection? What exactly happens when I click "Open"?

That is because the bootloader must be started in order to check if connection was open in order to upload a new sketch. This is because USB can be used for both situations: upload a sketch, or just communicate with the running sketch.

The arduino is reseting because of the serial port initializing. If you want to avoid it, you can put a 120 ohm resistor between 5v and reset.
Source

license: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/3.0/


text:
PWM and attachInterrupts issues
I'm trying to control the speed of a DC current motor with PWM.
I use an arduino UNO to send PWM signal to a mosfet Velleman vma411 to change the average tension of a my motor which is wired to stabilized power supply (about 10V).
In order to get the rotational frequency of my motor, I have a hall effect sensor next to the rotational axis. Each half turn the sensor changes value (either 0 or 5V).
To detect the changes I use attachInterrupt() to detect the changes.
When the arduino is not sending any PWM signal, the frequency measured is perfectly fine (I verified it using an oscilloscope). BUT when I send PWM signal to my motor, the frequency makes no more sense (about 1 value out of 3 is 10 times higher than the expected one).
To solve this issue I tried three different things :

putting a capacitor (between 100 microF and 2200 microF) between the arduino and the mosfet sig port,
using a average value of the last 10 measured frequencies,
adding a numerical filter,
using one ground pin for the mosfet and a different one for the sensor port,

Nevertheless any of those ideas really worked for me.
I suppose this may be due to some electrical reflection issues? Maybe should I change my mosfet or use a L298N?
Thanks in advance
My code which goal is to measure accurately the rotational frequency while sending a PWM signal to the mosfet:
/*
alimentation du capteur : 4V
mesure précise jusqu'à au moins 10V
*/

//ports
int rotation_port = 3;
int mosfet_sig_port = 11;
int debug_port = 10;

//mesures :
volatile long t_new;
volatile long t_old;
volatile long res;
volatile float frequence;
volatile float old_frequence;

// asser
float rapport_cyclique = 127; //entre 0 et 255

void setup() {
  pinMode(rotation_port, INPUT_PULLUP); // pour interrupt
  attachInterrupt(digitalPinToInterrupt(rotation_port), capteur_hall_changement, FALLING);
  pinMode(debug_port, OUTPUT);
  pinMode(mosfet_sig_port, OUTPUT);
  Serial.begin(115200);
  old_frequence = 100;
}

void capteur_hall_changement() {
  t_new = micros();
  res = 1.0 / (t_new - t_old) * 1000000;
  if (res/old_frequence <= 1.5) {
    frequence = res;
    old_frequence=frequence;
  }
  t_old = t_new;
  Serial.println(frequence);
}

void loop() {
  // Envoi du signal PWM sur la sortie numérique mosfet_sig_port
  analogWrite(mosfet_sig_port, int(rapport_cyclique));
}

Do not Serial.println() in interrupt context. 2. frequence and old_frequence are redundant (they are always the same). 3. What is the rationale for if (res/old_frequence <= 1.5)?

the goal of if (res/old_frequence <= 1.5) is to remove the measures that should not appear. I want to measure a frequency of around 100Hz and some measures are giving a 200Hz frequency for no reason, so the goal was to numerically filter them.

When you use interrupts your PWM can work bad so don't use them both at the time.

Exactly. You would have to manually implement PWM in this case


text:
Sending analog sensor data to laptop at 1kHz via USB
I am reading analog sensor data using Arduino nano, and the required sampling rate is around 1kHz. I am using the AnalogReadSerial example provided by Arduino with a delay of 1ms, so I am expecting to get around 1000 samples per second or slightly less due to the ADC conversion delay. However, the maximum number of samples I am able to get in my laptop a little bit less than 200 samples per seconds. I have tried increasing the baud rate to 115200 but that was not helpful. Am I missing something here, or is there something I need to do to get my data at the required sampling rate?
Below is AnalogReadSerial code I used for reference:
// the setup routine runs once when you press reset:
void setup() {
  // initialize serial communication at 9600 bits per second:
  Serial.begin(115200);
}

// the loop routine runs over and over again forever:
void loop() {
  // read the input on analog pin 0:
  int sensorValue = analogRead(A0);
  // print out the value you read:
  Serial.println(sensorValue);
  delay(1);        // delay in between reads for stability
}

record the value of millis() before and after int sensorValue = analogRead(A0); ... then print the two  values

@jsotola I used micros(), and it takes 116 microseconds.

115kBaud should actually be enough. 1000 Messages with about 6 bytes each (a 4 digit number and CR/LF) use 6000 bytes or 60000 bits/second. How fast can you get if you remove the delay?

Running your code on my Uno gives me 791.5 samples/s. Maybe your laptop is too slow to cope with the data rate?

Rookie mistake from me, I had to accordingly adjust the baud rate of my laptop's USB port using ssty because the default was 9600. Right now, I am getting data at a rate similar to yours @Edgar Bonet, which is better but still a little bit shy of the required rate. @PMF your calculations make sense and this baudrate should be within my laptop's and Arduino nano's limits, which is still confusing to me. I will remove the delay and check if that makes any difference.

since serial uses ascii, it might be less data to send the delta between each reading than the whole number. eg. 128,129,127 is 11 chars, 128,1,-2 is only 8 chars.

As I said in a comment, your code on my Uno gives me
791.5 samples/s. This is about 1263 µs per sample:

about 110 µs for analogRead(), including 104 µs for the
conversion proper
presumably 1000 µs for delay(1)
153 µs for the rest of the code, mostly formatting sensorValue
in ASCII

According to these timings, if it were not for the call to delay(),
the Arduino should be able to complete the loop in one millisecond, and
still have 737 µs to spare. The simplest way to achieve this is to
follow the Blink Without Delay strategy:
void loop() {
    static uint32_t last_conversion_time = micros();
    if (micros() - last_conversion_time >= 1000) {
        last_conversion_time += 1000;
        Serial.println(analogRead(A0));
    }
}

This does give me 1000 samples per second. Note that
last_conversion_time is updated by adding 1000 µs rather than
setting it to micros(), so this is actually a variation on the Blink
Without Delay strategy. Updating last_conversion_time in this fashion
ensures that whenever the program gets late and misses the exact
microsecond it wanted, the small timing errors do not accumulate.
For the maximum possible timing accuracy, it would be more appropriate
to trigger the ADC by a timer, but that approach is more complex and
requires carefully reading the datasheet of the microcontroller.

I would not call it BlinkWithoutDelay strategy. It is different. It would be better to initialize last_conversion_time with micros() so it doesn't have to catch up with 1ms increments the time lost in setup() .

@Juraj: I edited the answer to account for your comments. I would usually prefer letting last_conversion_time be initialized to zero, unless setup() is really slow (not the case here): this saves the cost of a guard variable and a test at each loop iteration. But then, maybe I tend to micro-optimize too much...


text:
Trouble understanding min and max parameters for the Servo motor

This picture is from arduino.cc .  Could someone please help me understand these parameters min and max? I was using TinkerCad taking input for the angle using a potentiometer (having mapped correctly the input from (0 to 1023) to (0 to 180) ) but i don't see any change when i vary either min or max in my code. The servo still goes to 180-deg position when input is 1023.

it is the pulse width of the control signal that has to be sent to the servo when commanded to move to its minimum and maximum positions

In your question you're referencing the servo library. You mention mapping ranges of 0-1023 (the sampling range of your potentiometer) and 0-180 (the degrees of rotary travel of the average hobby servo).
There is an additional important concept to get familiar with as you learn about servos. That is the Pulse Width Modulated (PWM) signal that the Arduino (or any other controller) uses to communicate with the servo to set what angle of rotation it should assume. PWM is used a few different ways in electronics, but in this scenario it is being used as a servo control signal, and the pulse width (measured as a time duration) communicates the required angle to the servo. The library you're referencing helps users by translating between angles and PWM pulse lengths. But under the covers servos always (close enough for our conversation anyway) receive a signal based on PWM.
Another complicating factor is that servos vary greatly. There is a loose convention that says that a pulse width of 1500 micro-seconds is centre position, 1000 micro-seconds is the minimum -90 degress (or 0 degrees depending on how you look at it), and 2000 micro-seconds is the maximum +90 (or 180) degrees. These match the defaults that @Bra1n notes in their answer.

(Diagram by Wikimedia user Hforesti - https://commons.wikimedia.org/wiki/File:Sinais_controle_servomotor.JPG, CC BY-SA 4.0, https://commons.wikimedia.org/w/index.php?curid=101951622)
But that convention is broken all the time. Some servos are capable of less than or greater than 180 degrees. Others use different pulsewidths to specify the maximum and minimum rotations. It's for this reason that the library allows the minimum and maximum pulsewidth (expressed in micro-seconds) to be specified for the particular physical servo being attached. This allows the library to correctly map to its range of travel.
Everytime you use a new type of servo (or consider buying one for a new project) you'll need to look at its datasheet to get the important information about how that servo works.
One last thought about traps for new players, I've also seen servo libraries which express the maximum and minimum servo PWM values in the range of 0-4096. Some people also express this as a % duty cycle (mixing the language of those other purposes I mentioned PWM is also used for). Knowing that these all map back to a PWM pulse width is useful for making sense as you learn more about servos. Good luck!

It's hard coded in the servo library (well it is on the ESp8266 version I used).
// The following values are in us (microseconds).
// Since the defaults can be overwritten in the new attach() member function,
// they were modified from the Arduino AVR defaults to be in the safe range
// of publicly available specifications. While this implies that many 180°
// servos do not operate the full 0° to 180° sweep using these, it also prevents
// unsuspecting damage. For Arduino AVR, the same change is being discussed.
 #define DEFAULT_MIN_PULSE_WIDTH      1000 // uncalibrated default, the shortest duty cycle sent to a servo
 #define DEFAULT_MAX_PULSE_WIDTH      2000 // uncalibrated default, the longest duty cycle sent to a servo
 #define DEFAULT_NEUTRAL_PULSE_WIDTH  1500 // default duty cycle when servo is attached

I discovered this when a servo attached to an ESP8266 was only moving half the expected angle so I modified the library (saving it as MyServo) and used that instead. You need to be careful when doing this as you can strip the servo gears if you try to move the servo outside its capable range.

Well I am a very beginner! Could you please guide me how I can learn this? What you said is a bit too advanced for me to understand. ( please bear with me). But I want to surely know what I should do to not strip my servo gears ( so what should min and max ) be set to? Maybe you could give some  detailed references.


text:
Why is my buzzer always on?
I wanted to make a buzzer go off when the distance measured by the ultrasonic sensor becomes more than 100cm. The things used in this project are a 4x4 keypad, an hc-sr04 ultrasonic sensor, and a passive buzzer all connected to a keyestudio mega 2560.
What happens is that the moment I upload the code/turn on the Arduino, the buzzer turns on despite a solid object being within a 100cm range. And the buzzer almost randomly stops for a couple of seconds and continues. It won't turn off, even when I press the appropriate key on the keypad.
This is the code I have written, thanks
    #include <Key.h>
    #include <Keypad.h>

    const int trigPin = 11;    //output to sensor
    const int echoPin = 12;    //input from sensor
    const int buzzPin = 13;    //output to buzzer

    const byte ROWS = 4;
    const byte COLS = 4;

    long duration;    //travel time of sound waves
    int distance;    //distance at which an object is

    char hexaKeys[ROWS][COLS] = {
      {'1', '2', '3', 'A'},
      {'4', '5', '6', 'B'},
      {'7', '8', '9', 'C'},
      {'*', '0', '#', 'D'}
    };

    byte rowPins[ROWS] = {9,8,7,6};
    byte colPins[COLS] = {5,4,3,2};

    Keypad customKeypad = Keypad(makeKeymap(hexaKeys), rowPins, colPins, ROWS, COLS);

    void setup() {
      // put your setup code here, to run once:
      pinMode(trigPin, OUTPUT);
      pinMode(echoPin, INPUT);
      pinMode(buzzPin, OUTPUT);
      Serial.begin(9600);
    }

    void loop() {
      // put your main code here, to run repeatedly:

      char customKey = customKeypad.getKey(); // gets key values from keypad

      if(customKey) {
        Serial.println(customKey);
       }

      digitalWrite(trigPin, LOW);    //reset the sensor by turning it off for 2 microseconds
      delayMicroseconds(5);

      digitalWrite(trigPin, HIGH);    //generate ultrasound wave by turning it on for 10 microseconds
      delayMicroseconds(50);
      digitalWrite(trigPin, LOW);

      duration = pulseIn(echoPin, HIGH);    //time it takes for sound to get back
      distance = duration*0.034/2;    //plug into formula for distance

      Serial.println(distance);

    if (distance <= 100){
     digitalWrite(buzzPin, LOW);
      }
    if (distance >= 100){
      digitalWrite(buzzPin, HIGH);
      if (customKey != 7){
        digitalWrite(buzzPin, HIGH);
        delay(2000);
        digitalWrite(buzzPin, LOW);
        delay(1000);
      if (customKey == 7){
        digitalWrite(buzzPin, LOW);
}
}
}
 }

indent the braces at the end of your program properly ... you may notice that they are in the wrong places

what is printing in serial monitor?


text:
My circuit is being goofy with regards to my PIR sensor
Here is the code I've written so far. I am making a circuit with a couple of motors and 3 sensors. My plan is for the PIR Motion sensor, distance sensor, and photoresistor to tell the motors to stop when they're triggered. When I set the if proximity = LOW, the LED lights up whether I move the sensor or not. But when it's set to HIGH, the LED won't light up even if motion is detected. I've tested it separately from the rest of the code and it doesn't do this. Is there something wrong with how I've got my simultaneous loops?
int inches = 0;
const int ledPin1=11; // blue LED
const int ledPin3 = 9; // red LED
const int servoPin = 4; // blade motor
const int MOTION_PIN = 2; // Pin connected to motion detector
const int ledPin2 = 10; // green LED
const int photoPin = 3; // photoresistor connected to digital pin 2
const int motorPin = 13; // motor for the wheels connected to digital pin 13
int cm = 0;

long readUltrasonicDistance(int triggerPin, int echoPin) // setting up the distance sensor, this code is pre-set up along with the circuit
{
  pinMode(triggerPin, OUTPUT);  // Clear the trigger
  digitalWrite(triggerPin, LOW);
  delayMicroseconds(2);
  // Sets the trigger pin to HIGH state for 10 microseconds
  digitalWrite(triggerPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(triggerPin, LOW);
  pinMode(echoPin, INPUT);
  // Reads the echo pin, and returns the sound wave travel time in microseconds
  return pulseIn(echoPin, HIGH);
} // long

void setup()
{
  Serial.begin(9600); // loop time
  pinMode(ledPin1, OUTPUT); // sets the blue LED as an output
  pinMode(ledPin3, OUTPUT);
  pinMode(MOTION_PIN, INPUT);
  pinMode(ledPin2, OUTPUT);
  pinMode(servoPin, OUTPUT); // blade
  pinMode(photoPin, INPUT); // light sensor
  pinMode(motorPin, OUTPUT); // wheels
} // end setup

void loop() {

    dist();
    motion();
}

void dist()
{
  // measure the ping time in cm
  cm = 0.01723 * readUltrasonicDistance(7, 7);
  // convert to inches by dividing by 2.54
  inches = (cm / 2.54);
  Serial.print(inches);
  Serial.print("in, ");
  Serial.print(cm);
  Serial.println("cm");
  if (cm<150) // if an object (another person) approaches within 1.5 meters
  {
  digitalWrite(ledPin1, HIGH); // turn on the blue LED, symbolically represents roomba reaction to go around or stop
  } // end loop
}

void motion()
{
  int proximity = digitalRead(MOTION_PIN);
  Serial.println(proximity);
  if (proximity == HIGH) // If the sensor's output goes high, motion is detected
  {
        Serial.println("Motion detected!");
        digitalWrite(ledPin2, HIGH);
  }

}

you are adding multiple layers of confusion to your code ...  ledPin2 refers to pin 10, not pin 2 ...     it makes more sense to name it something like greenPin

So, proximity is always LOW, which means MOTION_PIN is always 0. Maybe your PIR sensor isn't connected to pin 2, or maybe it needs a pull-up or pull-down resistor on its data pin.


text:
Adafruit CC3000 WiFi Module working together with MFRC522 RFID Module Issues both SPI over Arduino
I'm asking if how can I implement this one. I'm aware about multiple devices being connected over SPI, like having to select individual SS pin for each. Adafruit's CC3000 works fine alone along with the default Adafruit library. CC3000 uses SPI. MFRC522 RFID module by sonmicro (bought at Sparksfun) uses SPI too. It works fine too, independently. But whenever I connect them together, only WiFi works perfectly. I dont want to turn on and off the wifi to make way for the RFID to communicate since it takes some time for it to be connected in a wireless network. I want the two to work synchronously (or having to be scheduled but really fast that's unnoticeable by the user)
here's my code as of now. i cannot post it here as strange things happen i don't know why haha https://drive.google.com/file/d/0B0bZsYo0xMH8YV9uWXJaRFdPT3M/view?usp=sharing
I'm thinking of replacing the RFID with SonMicro's SM130 RFID Module w/ SparkFun Eval board with UART (convertible to I2c) or Adafruit's PN532 with I2c by default. Are these okay to be paired with SPIs like the CC3000? Or should I change CC3000 with the Official WiFi module (UART) or WiFly Module (SPI-to-UART)

I couldn't get your code to download so this might be wrong, but it sounds like the modules are running different SPI modes: http://en.wikipedia.org/wiki/Serial_Peripheral_Interface_Bus#Mode_numbers
I had this problem a few years ago. You'd expect SPI to be SPI, but it comes in four different flavours and they won't talk to each other on the same bus. Unfortunately there's no solution but to replace the modules; the Arduino can only run one SPI bus, so can only talk to one of these modules at a time.
However you can run UART and I2C or UART and SPI concurrently by using SoftwareSerial (don't use the native Tx/Rx pins, bad things happen).
So your best bet is to switch to modules that use I2C or UART. Personally I'd use UART, simply for the simplicity of having two separate connections and a higher data rate.

thanks for the tip. I'll be trying that. but how would I use UART with SPI? THere are pin assignments that the two share. I'm thinking using of SparkFun's SM130 Eval Board with the CC3000, but CC3000 have SPI so 11,12,13 are exclusive for SPI, although it has ICSP header also for SPI, (would this header make the pins 11,12,13 free?)

You can use SoftwareSerial (http://arduino.cc/en/Reference/softwareSerial) to declare new UART connections from almost any pin (on the Uno, some limitations on other boards). I can't remember if the SPI on the ICSP header is simply the same as pins 11,12,13 or if it's used for the Atmega16U2. Either way it's not going to free up 11,12,13.

all_licenses: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/3.0/


text:
TTGO TS I²C adress
I'm working on a project using TTGO TS wich communicate wih arduino via I²C protocole
How can I find the adress of TTGO TS board used in I²C communication ?

you would find out the address by reading the instruction manual, or the datasheet

You could also use an I2C scanner (google it, there are dozens of them out there).

The TTGO TS uses an ST7735 display. This is not an I2C device. Instead it uses its own custom serial protocol. Since the DC pin is broken out for you it uses the 4-wire serial interface which is simplest to use with SPI.
It's confusing that they use the terms SCL and SDA, which makes you think it's I2C, but it's not.

Like @romkey said, use a I²C scanner to find the address of the device, for example this one from the Arduino website. Connect the device to the Arduino board, upload the code and look up the I²C address of your device.


text:
Load cell weight distribution on rectangular shape instead of square
I have built a simple scale using 4 so called 50kg load cells.

They are connected in a bridge and mounted on wooden feet of a square shaped box. All as a proof of concept which worked quite ok. The readings are all OK and deviation of +/- 2kg is totally acceptable for my project. I followed this discussion which also explains how the connection should be made properly using 4 cells.
How to get weight data from glass electronic bathroom scale sensors?
Now I want to keep the load cells on the feet but change the shape of the scale and instead of a square use a rectangle with the following sides.

In such a form a weight distribution will not be centered all the time. The object to be weighed can shift to the right or to the left.

Will this affect the measurements in a negative way or will the HX711 controller still take care of it and show the correct results?
Will the measurements still be correct using 4 cells? If not what would be the proper way of weighing a rectangular shaped load?
Would it more appropriate to measure the load with 2 cells on the right and two cells on the left and then sum it up?

why would the shape make a difference? ... the length of the cables may or may not be a problem

you say that you built the scale ... why are you asking and not testing? ... i do not see a question about any problems

For the total measured weight the load center is not relevant. If - for example - the load center is 3/4 to the right, the right load cells will measure more weight, while the left are measuring less. The overall weight has to be equal to load center in the middle

Newton's second law says that if a force acts on a mass, that mass will accelerate at a rate proportional to the force and inversely proportional to the mass.
All that means for your scale is that if you are not being accelerated up or down, the net vertical force on your body must be 0. Since your body has weight, and the net vertical force on your body is 0 (you aren't accelerating, are you? :) then the downward force must be balanced by an exactly equal upward force. That upward force is the sum of the upward forces exerted by each load cell. Their contributions may individually change depending on where you stand, but their sum must exactly equal your weight.
Note that we have said nothing about the placement of the cells! If your platform allows it, you could move one of the cells 6 (or 60 or 600) feet away from the the others, for instance. The total upward force must still be the same.
So the bottom line is:
F_lc1 + F_lc2 + F_lc3 + F_lc4 == your weight
no matter where you place the cells.

Thanks, this is exactly the answer I was expecting to hear . Clear, precise and involving physics! Of course I was almost sure it was like but needed a confirmation.

I'd just like to point out that this refers to a different Newton. It isn't me.


text:
How to fade LED in a defined time using FastLED
I'm using FastLED library, Arduino Nano and 5 addressable LEDs (WS2812B).
I'd like to create the sequence in the image attached. (all in white color for example)
I know how to turn ON each LED every 0.2 sec and I know how to fade.
I don't know how to make sure each LED goes from 0% brightness to 100% in 0.4 sec + start fading in the next LED after 0.2 sec.
Here is a fading LED:
void loop() {
  uint32_t cur_ms = millis();
    if (cur_ms - fade_ms > 200) {
        fade_ms = cur_ms;
        brightness += 5;
        leds[0] = CHSV(255, 0, brightness);
    }

FastLED.show();
// delay(10);

}
Can anyone help me figure it out?

Hi Welcome to ASE. Just an Idea. You can use the remaining millis() and the current brightness value to compute the next needed jump or reduction in the brightness

I'd appreciate if you could supply a snippet

can you share the complete code snippet of what you have worked on? Also, The below answer is really really good. You might be in a hurry now, but bookmark it and come back when you have time.

One of the SimpleTimer libraries such as this one by Marcello Romani (which I mention because I have used it; there are others). It creates a timers object that has 10 (in this case) software-based timers with a variety of operating modes (run once, run x times, run forever, e.g.).
The basic idea (for a 1-LED example) is that you write a function (known as a "callback" to step up the brightness of an LED by one step. Let's call it stepUp().
You write another callback function to turn off the LED and start a timer that will call stepUp() at whatever interval you choose for as many times as it takes to reach 100%. Let's call this one cycleLED().
In your setup(), you'll start another timer that will call cycleLED() as often as you want that process to run - every 1200 mSec in this case - and for as many times (or forever) as you choose.
In your loop() function, you'll need a call to your timer object's .run() function as often as possible - that is what makes the timers work, and it is the timers that will call your callback functions to make your LEDs behave as you want them to.
So far, we one fading-up LED, and I'd recommend you implement this much at first.
There are two ways to go from here. You can write the above pair of callbacks for each LED, but they will be nearly identical and why write maintain the same code, several times over? Or you can use another feature of the library - a pointer-to-void argument to the callback function - in which you can pass any value, such as an LED's number or address, so that one callback could operate on the specified LED.
If you go with first option, your setup() function will need to to start 5 timers, one for each cycleLED() function (which would need to have distinct names, of course), and those timers start-times will need to be staggered.
With the second option, you would write a third callback, allCycles() that sequences the starts of each cycleLED() in turn. In this case, your setup() function would only need to start a timer to repeatedly call allCycles().
There's a lot there, if these are new concepts. If so, it will be a lot easier to experiment with the SimpleTimer library doing something trivial at first, like flashing (not fading) one LED, then several LEDs, until this way of coding timed events feels less foreign.

Thank you, but this isn't helpful.
It should be very simple & clean code.
I should use this: "if (cur_ms - x_ms > y_ms)" twice.
One for incrementing the brightness and one for increasing the index to the next LED.
I also need a struct/array to create different brightness value for each LED.

It really doesn't get much cleaner than that. You can of course, write layers of if (cur_ms - x_ms > y_ms) and keep all of the code visible all of the time, but modular code is generally easier to understand, write correctly, debug, and maintain. You're welcome.

@yuvix_man how is Jroberts answer not helpful? Jrobert laid out everything clearly. Writing actual (clean) code is up to you, which should be easy after this explanation.


text:
Using the touchscreen.getpoint causes program to instantly crash
this code runs fine until I add in the if statement surrounding the draw screen() method. upon clicking the screen, the program instantly crashes, turning the screen white. any help would be appreciated.
"
// IMPORTANT: Adafruit_TFTLCD LIBRARY MUST BE SPECIFICALLY
// CONFIGURED FOR EITHER THE TFT SHIELD OR THE BREAKOUT BOARD.
// SEE RELEVANT COMMENTS IN Adafruit_TFTLCD.h FOR SETUP.

#include <Adafruit_GFX.h>    // Core graphics library
#include <Adafruit_TFTLCD.h> // Hardware-specific library

#include <stdint.h>
#include "TouchScreen.h"
#define YP A2  // must be an analog pin, use "An" notation!
#define XM A3  // must be an analog pin, use "An" notation!
#define YM 8   // can be a digital pin
#define XP 9   // can be a digital pin

// The control pins for the LCD can be assigned to any digital or
// analog pins...but we'll use the analog pins as this allows us to
// double up the pins with the touch screen (see the TFT paint example).
#define LCD_CS A3 // Chip Select goes to Analog 3
#define LCD_CD A2 // Command/Data goes to Analog 2
#define LCD_WR A1 // LCD Write goes to Analog 1
#define LCD_RD A0 // LCD Read goes to Analog 0

#define LCD_RESET A4 // Can alternately just connect to Arduino's reset pin

// When using the BREAKOUT BOARD only, use these 8 data lines to the LCD:
// For the Arduino Uno, Duemilanove, Diecimila, etc.:
//   D0 connects to digital pin 8  (Notice these are
//   D1 connects to digital pin 9   NOT in order!)
//   D2 connects to digital pin 2
//   D3 connects to digital pin 3
//   D4 connects to digital pin 4
//   D5 connects to digital pin 5
//   D6 connects to digital pin 6
//   D7 connects to digital pin 7
// For the Arduino Mega, use digital pins 22 through 29
// (on the 2-row header at the end of the board).

// Assign human-readable names to some common 16-bit color values:
#define  BLACK   0x0000
#define BLUE    0x001F
#define RED     0xF800
#define GREEN   0x07E0
#define CYAN    0x07FF
#define MAGENTA 0xF81F
#define YELLOW  0xFFE0
#define WHITE   0xFFFF

Adafruit_TFTLCD tft(LCD_CS, LCD_CD, LCD_WR, LCD_RD, LCD_RESET);
// If using the shield, all control and data lines are fixed, and
// a simpler declaration can optionally be used:
// Adafruit_TFTLCD tft;
int six;
int hundred;
int twenty;
int ten;
int four;
int eight;
int two;
int twelve;
TouchScreen ts = TouchScreen(XP, YP, XM, YM, 300);
void setup()
{
  Serial.begin(9600);
  Serial.println(F("TFT LCD test"));
  tft.reset();
  uint16_t identifier = tft.readID();

  tft.begin(identifier);
  tft.fillScreen(BLACK);

  six = random(1, 6);
  eight = random(1, 8);
  twenty = random(1, 20);
  hundred = random(1, 100);
  four = random(1, 4);
  ten = random(1, 10);
  two = random(1, 2);
  twelve = random(1, 12);

  tft.setTextColor(WHITE);  tft.setTextSize(4);
  drawNumbers();

}

void loop() {

  six = random(1, 6);
  eight = random(1, 8);
  twenty = random(1, 20);
  hundred = random(1, 100);
  four = random(1, 4);
  ten = random(1, 10);
  two = random(1, 2);
  twelve = random(1, 12);
  if (ts.getPoint().z != 0) {
    drawNumbers();
  }

}

void drawNumbers() {
  tft.setCursor(0, 0);
  tft.fillScreen(BLACK);
  tft.println("D2: " + String(two));
  tft.println("D4: " + String(four));
  tft.println("D6: " + String(six));
  tft.println("D8: " + String(eight));
  tft.println("D10: " + String(ten));
  tft.println("D12: " + String(twelve));
  tft.println("D20: " + String(twenty));
  tft.println("D100: " + String(hundred));

}"

this library seems largely ill documented, but this seems egreigous if its not on my end.

how can you possibly know that the program crashed?

Welcome to SE/Arduino! Please take the [tour] to learn how this site works. -- Check what ts.getpoint() returns. -- As it seems, the "Touchscreen" module is some local library. Would you mind to provide a link, please? [Edit] your question, don't add a comment.

Updated:

Provided info not revelant.

I would approach the problem like this. What if anything is returned by getPoint.
  if (ts.getPoint().z != 0) {
    drawNumbers();
  }

To
  auto pt = ts.getPoint().z;
  Serial.print("Point: ");
  Serial.println(pt);

  if (pt != 0) {
    drawNumbers();
  }

This would tell me if I am getting a value back or if it is a problem elsewhere.
Hope this helps.

hi, first of all, thanks for replying.
That method itself doesn't seem to be the issue, it'll run fine on its own. The issue is when the if statement and the touchscreen getpoint method is invoked the program crashes. I am able to print using that method without issue.

Ignore my original answer. After some extra testing the String class now now supports your use. I shall instead add a tip.

@cptcrabcakes Sorry, I think my original answer was not upto date. I have amended.

The serial monitor is reporting point data back, which makes me think this isnt a true crash, just the graphics library freaking out.

@cptcrabcakes You may get better quaility help if you can provide info such as the platform you are using like Uno, Nano etc, and details of the screen in the question.

Someone marked the answer down as not useful despite the fact it helped diagnose the error was elewhere? Ok.

Figured it out
the TFT screen im using forces the sharing of pins being used for analog and digital together. By starting my draw method with pinMode() i set the pins to be treated as the touchscreen's
void drawNumbers() {
    pinMode (XM, OUTPUT);
  pinMode (YP, OUTPUT);
  tft.setCursor(0, 0);
  tft.fillScreen(BLACK);
  tft.println("D2: " + String(two));
  tft.println("D4: " + String(four));
  tft.println("D6: " + String(six));
  tft.println("D8: " + String(eight));
  tft.println("D10: " + String(ten));
  tft.println("D12: " + String(twelve));
  tft.println("D20: " + String(twenty));
  tft.println("D100: " + String(hundred));

}


text:
how accurate is the calculation in stm32?
I have a project plan in which there are calculations that require high precision, which later will have calculations with numbers after commas such as 245.5431657288. from some of the information that I read to make the project a success it must use 32 bytes, initially I wanted to use arduino due, but for some reasons I was more interested in using STM32 but my knowledge of STM32 is not much, especially in terms of the level of precision calculation, therefore I ask is STM32 suitable for my project? I hope my question can be understood, thank you.

not an arduino question

numbers after commas ...  do you mean numbers after the decimal point? ... a comma is , ... those are called decimal places ... 245.5431657288 has 10 decimal places in the fractional part

you could convert to integer by multiplying ... 245.5431657288 becomes 2455431657288, which is hexadecimal 23B B321 B748 ... that fits into 43 bits

There are multiple arduino compatible devices based on STM32 architecture. Understanding the precision of the various CPU offerings is key to making proper design choices. I believe this question is on topic.

There is an intro to floating point units(fpu) for STM32 MCUs at https://www.st.com/resource/en/application_note/dm00047230-floating-point-unit-demonstration-on-stm32-microcontrollers-stmicroelectronics.pdf

You have to look for a platform that supports double-precision floating point, i.e. 64-bit floats. According to RowanP's link, some STM32 do. Or you could do 64-bit fixed point on any Arduino, but that may not be easy.

The hardware does not affect the precision. The software affects the precision. The hardware affects the efficiency of processing at different precisions.

The hardware makes no difference to the accuracy of calculations. That is purely down to the software - whether you use single or double precision floats, whether the compiler flags disable double precision to save space (as some 8 bit configurations do), etc.
The choice of hardware only affects the efficiency of the processing at different precisions, such as if there is an FPU, or what precision the FPU can operate at (using precisions outside the range of the FPU will only affect speed not precision).
Both the stm32 and due are ARM based MCUs, so any differences will be down to what additions there are in any specific chip (such as FPU).

As far as I know, only the AVR compiler by default disables double precision. For other architectures, I would assume that if the hardware has no (or limited) FPU support, the compiler would emit emulation code (as was common for x86 as well, before they included FPUs)

I just checked the gcc for AVR: That compiler has software support for double. I'm not sure if the Arduino tool suite uses the gcc compiler; however it would be possible to use the gcc compiler with Arduino Uno and similar devices instead of the "official" one.

@MartinRosenau Depending on what version of the core it may have a command line option enabled that forces singe-precision when double is used.


text:
CONTROLLINO MEGA – Timeout communicating with programmer
I’ve been using my CONTROLLINO MEGA since long time ago, but today I uploaded a sketch and now the board is not working. Everytime I try to uploud a sketch, ARDUINO IDE remains in “uploading..” mode and after a while this message appears:
avrdude: stk500v2_ReceiveMessage(): timeout
avrdude: stk500v2_ReceiveMessage(): timeout
avrdude: stk500v2_ReceiveMessage(): timeout
avrdude: stk500v2_ReceiveMessage(): timeout
avrdude: stk500v2_ReceiveMessage(): timeout
avrdude: stk500v2_ReceiveMessage(): timeout
avrdude: stk500v2_getsync(): timeout communicating with programmer
avrdude done. Thank you.
I have selected the correct board on the correct COM port (I’ve been using the board for months with no problem).
The sketch that I uploaded before this problem is:
SoftwareSerial serie(CONTROLLINO_D12, CONTROLLINO_D13);
void setup() {
Serial.begin(9600);
serie.begin(9600);
void loop() {
serie.listen();
while (serie.available() > 0) {
char inByte = serie.read();
Serial.write(inByte);
}
Serial.println();
}

Any Idea?? I've checked this topic alredy Did I Brick my Controllino?,
but dont know how to apply the solution on my CONTROLLINO MEGA
Thank you!!

Is the "RST" led in front of your controllino on?


text:
How Can I Get My ESP32 to Work with a 3.5-inch ILI9486-Based RPi Display Using SPI in Arduino IDE?
I'm working on a project where I need to connect my ESP32 (WROOM) to a 3.5-inch, 480x320 resolution LCD designed for the Raspberry Pi, which uses the ILI9486 driver (as suggested by the lcd wiki). I’m currently trying to use the TFT_eSPI library with SPI mode, but I’m having trouble getting the display to respond correctly. These are my pins connections:

#include <TFT_eSPI.h>  // Include the TFT library

TFT_eSPI tft = TFT_eSPI();  // Create an instance of the display

void setup() {
    // Initialize the display
    tft.init();
    tft.setRotation(1);  // Adjust rotation as needed

    // Clear the screen with a color (e.g., black)
    tft.fillScreen(TFT_BLACK);

    // Display text to test
    tft.setTextColor(TFT_WHITE, TFT_BLACK);  // White text on black background
    tft.drawString("Hello, ESP32!", 50, 100, 4);  // Draw text at (50, 100) with font size 4}
    void loop() {
    // Optional: Add more display functions here if needed
    }

This code is working fine with 2.8 inches 320x240 and ILI9341 drivers but not with 3.5 inches (320x480) display with ILI9486 drivers (also not with ILI9341). Guide me I am not expert in this.

What is your User_Setup.h settings?

User_Setup.h

Are you sure your display has ILI9486 driver? For 320x480 display, it could also supported by ILI9488 or ST7796 driver chip. Have you try any of those? Check with the vendor's website or ask them what chip the display is using.

Fixed the issue. Problem was 1 connection. Moved RST display connection from GPIO4 to EN on ESP32 and in User_Setup TFT_RST -1. Thanks everyone for your response.


text:
Power Arduino MKR GSM 1400 via VIN
I am working on a project with Arduino MKR 1400 GSM and I would like to power the arduino board using an external power source (https://www.reichelt.de/raspberry-pi-netzteil-5-1-v-3-0-a-usb-type-c-eu-stecker-s-rpi-ps-15w-bk-eu-p260010.html?PROVID=2788&gclid=CjwKCAjwy7CKBhBMEiwA0Eb7ah0tvjJTgi1IruE69oZEm51ONn9dgkCZK45JE1EU5hNgoXfJ1CA8NBoCJLgQAvD_BwE) via the VIN pin without an additional 3.7V battery.
I have copied the code that I am using and the board resets and restarts every time the board tries to initiate GSM connection (gsmAccess.begin(PINNUMBER) == GSM_READY). According to the documentation, this operation needs more current and the board restarts when it does not get enough current for this operation and 5V 3A power supply should be enough to power the board for cellular transmission without the need for an additional battery. However, I am not able to start GSM connection with this power source. I have cut the micro USB end and connect GND from the power source to GND on the arduino board and VCC from the power source to 5V/VIN on the arduino board. As mentioned, the board is not able to initiate the GSM connection with this set up.
I have gone through all the suggestions on the forum and I have not been able to resolve this. Could you please let me know the best way to power the arduino MKR 1400 GSM via VIN such that GSM connection is initiated.
The board works with the additional 3.7V battery (https://www.amazon.de/VinCorp-2500mAh-Stecker-Empf%C3%A4nger-Quadrocopter/dp/B0863PZPSM/ref=asc_df_B0863PZPSM/?tag=googshopde-21&linkCode=df0&hvadid=447410901006&hvpos=&hvnetw=g&hvrand=1221952135560228729&hvpone=&hvptwo=&hvqmt=&hvdev=c&hvdvcmdl=&hvlocint=&hvlocphy=9044320&hvtargid=pla-925522392231&psc=1&th=1&psc=1)
Please let me know if you need more information from my side.
Please ignore the values given for the variables server and path
#include <MKRGSM.h>
#include <ArduinoHttpClient.h>
#include <ArduinoJson.h>
// PIN Number

const char PINNUMBER[]     = "";

const char GPRS_APN[]      = "";
const char GPRS_LOGIN[]    = "";
const char GPRS_PASSWORD[] = "";

GSMClient client;
GPRS gprs;
GSM gsmAccess;
String currentBarcode;

char server[] = "test.net";
char path[] = "/test";
int port = 80;

StaticJsonDocument<200> jsonBuffer;
HttpClient httpClient = HttpClient(client, server, port);
JsonObject root = jsonBuffer.to<JsonObject>();
int count = 0;

void setup() {
  Serial.begin(9600);
  boolean connected = false;
  while (!connected) {
    if ((gsmAccess.begin(PINNUMBER) == GSM_READY) &&
        (gprs.attachGPRS(GPRS_APN, GPRS_LOGIN, GPRS_PASSWORD) == GPRS_READY)) {
      connected = true;
    } else {
      delay(1000);
    }
  }
}

void loop() {
  root["boxid"] = "Test";
  root["gtin"] = "Test";
  if (client.connect(server, port)) {
    postToWia(root);
    delay(1000);
  } else {
  }

  if (!client.available() && !client.connected()) {
    client.stop();
    for (;;)
      ;
  }
}

void postToWia(JsonObject& data) {
  String dataStr = "";
  serializeJson(data, dataStr);
  httpClient.beginRequest();
  httpClient.post(path);
  httpClient.sendHeader("Content-Type", "application/json");
  httpClient.sendHeader("Content-Length", dataStr.length());
  //httpClient.sendHeader("Authorization", "Bearer " + String(device_secret_key));
  httpClient.beginBody();
  httpClient.print(dataStr);
  httpClient.endRequest();

}

Do you have a multimeter? Are you able to measure the current draw on the VIN pin at the time of the GSM connection. Firstly using the battery (working scenario) then using the modified wall wart (failing scenario).

Thank you for the response, the multimeter fluctuates between 400mA and 600mA when I power the arduino using the modified wall wart (rated 5V, 3A). When I connect an additional battery (3.7V LiPo battery) to this set up, the multimeter reads 900mA and the GSM handshake is successful. Is it possible that the flow of current is regulated when powered through the VIN pin. As mentioned, I would like to remove the dependency on the battery. Please let me know if you need more information from my side.

USB C wall warts can be pretty sophisticated these days (e.g., with USB power delivery variable output). Are you sure that after chopping off the USB-C plug, that your wall wart is still making 3A available? Do you have a test load you could try it on? I >think< the RPi wall wart you referenced is an old school straight supply, but given your failure scenario it might be good to test?

The MKR 1400 GSM (https://store-usa.arduino.cc/products/arduino-mkr-gsm-1400) is specifically designed to take a higher current in the VIN pin for the scenario you describe. My suspicion is that the limitation is the modified wall wart, not the Arduino.

I have tried this with different adapters as well. I used a samsung adapter(5V, 2A), apple charger (5V, 1A) and Amoner adapter (5V, 3A) without any success.

Fiddling with this sort of problem is why I invested in a bench power supply. A handy bit of kit for testing and figuring out power requirements.

Thank you for the response, do you have any recommendation how I can achieve the required current in my setup. According to the documentation this should work however, I am not sure what I am doing wrong.

I think you are on the right track. Maybe try your Amoner adapter and again measure the current drain. Adding some pictures of your setup and the details of your measurements to your question may assist someone else to identify what’s going on .


text:
Peculiar behaviour of arduino pro micro
I am working with an arduino pro micro and I am facing a peculiar problem. The project I am working with includes arduino MKR NB 1500 as well. I am transferring data from MKR NB 1500 to arduino pro micro through Serial1(Rx/Tx pins). I have added the sample code that i am using on both boards
program in arduino MKR NB 1500
void setup() {
  Serial1.begin(9600);
}
void loop() {
  Serial1.print("printing");
  delay(2000);
}

program in pro micro
#include "Keyboard.h"

void setup() {
  Serial1.begin(9600);
  Keyboard.begin();
}

void loop() {
  Keyboard.write(Serial1.read());
}

I would like to transfer some data from MKR NB 1500 to pro micro which emulates a keyboard and prints the data in a editor. I am powering the arduino MKR NB 1500 via USB using its native USB port. The pro micro works as expected when I connect both these boards to USB ports in the same laptop. (Output: printingprintingprintingprinting)
However, the pro micro prints garbage values when I connect the MKR NB 1500 to a USB port belonging to a different laptop. (Output: a10joh<qqj<zstjo)
Is there any reason for such a behavior. Please let me know if you need more information from my side or if i have not made myself clear.

Have you connected the grounds? Also you should check Serial1.available() on the pro micro.

Thank you for your response. Connecting the grounds seems to be working, i will do few more tests. Could you please let me know why this is the case. I am new to working with arduino it would be helpful in the future.

https://majenko.co.uk/blog/our-blog-1/the-importance-of-sharing-grounds-12

if (Serial1.available()) is missing. The MKR can emulate keyboard too. with the same library

I am connecting the native USB port on the MKR board to a barcode scanner. The MKR board in this case is acting as a USB Host as a result I cannot use the MKR board to emulate a keyboard.

The data I would like to transfer to pro micro comes from the barcode scanner.

Connecting the grounds seems to be working, i will do few more tests. Could you please let me know why this is the case ... it is an electric circuit issue ... would you expect a lightbulb to light if you connected only one wire between the bulb and a battery?

Ground is the reference point for the microcontrollers to measure and output voltage. The actual place of their ground (as electrical potential) may be different, so the output voltage of the other microcontroller will not make much sense. When connecting the grounds you make sure, that both microcontrollers use the same reference point and thus can talk to each other

you can use a barcode scanner with SPI interface

You have to connect ground between the modules. Without common ground the logic level of signal can't be measured. While both boards were powered over USB from the same laptop the boards had common ground.

read returns -1 if nothing is available so check if some character was received:
void loop() {
  if (Serial1.available()) {
    Keyboard.write(Serial1.read());
  }
}

btw: The MKR can emulate a keyboard too with the Keyboard library.


text:
ADC stops working at small delays (MCP3464)
I have tried debugging for a couple days with no luck, so this question is a cry for help.
I am trying to configure an external ADC (MCP3464 datasheet). The ADC uses SPI communication and I am getting a response from it when I set the delay to 1000ms. If I lower this below 100ms, the ADC does not update and prints the last value stored in the ADC register.
Here is the relevant part of the code, although I have attached the whole file in case you would like to check command bytes etc.
void adcSimple(){

    unsigned char convStatus;
    uint16_t adcData;
    // chip Select pin LOW to read/write to ADC
    digitalWrite(adcChipSelectPin,LOW);
    convStatus = SPI.transfer(readConversionData);
    // extracts remaing bytes and append to adcData 16 bit integer (15bits plus sign)
    adcData = SPI.transfer(0);
    adcData <<= 8;
    adcData |= SPI.transfer(0);
    // chip select pin hgih to stop read/write to ADC
    digitalWrite(adcChipSelectPin, HIGH);

    // start next conversion
    writeData(&startConversionFastCmd, 1);

    Serial.println(adcData);
}

void setup(){
  Serial.begin(115200);
  while (! Serial);
  spiInit();
  adcInit();
  // set ADC Multiplexer to channel 0
  writeData(&muxRegisters[0][0], 2);
  delay(1000);
}

void loop(){
  adcSimple();
  delay(1000);
}

The adcSimple() function reads the ADC register address and appends it to the 16 bit adcData variable.
writeData(&startConversionFastCmd, 1);

The line above then restarts the ADC conversion (not the whole device) which is required to update the ADC register. For some reason this does not update the ADC register when there is insufficient delay in the loop.
  // Check the data ready bit
  if ((convStatus & 0x04) == 0x04)
  {
     Serial.println("ADC not ready!!!");

  }

I have run a test on convStatus, and this shows the ADC is not ready when the delay is short (around 100ms). I just don't understand why it takes so long (1000ms is equivalent to light years when running on 6MHz clock!)
Any suggestions would be greatly appreciated. Maybe someone has had a similar problem before?
Thanks,
Will

"attached the whole file", I seem to have missed it.  Where does writeData come from?  Or adcInit?

SOLVED: I lowered the oversampling rate (See table 5-6 of datasheet) and thus increased the data rate. Thanks for the response timemage

No problem. Unfortunately now you have an unanswered question that's unlikely to be answered.  If you wanted, you could flesh-out your answer-in-comment and post it as an answer proper.  With only your own answer, you have some latitude, in my opinion anyway, in editing the question to match.  Basically, you can leave behind a useful question/answer combo for a future reader with an Arduino and an MCP3464.

Can you please share the file because I'm facing writing and reading register for the same adc.
Also I'm not able to confirm that spi is initialized or not

I have added the MCP3464 library/driver to github - https://github.com/WillPowellUk/MCP3464-ADC


text:
How to control multiple servo motors simultaneously using protothreading?
So I'm trying to control 4 servo motors simultaneously using the Protothreads library by Ben Artin, but I am starting with 2 just to see if it works.
I have succeeded in getting two LEDs to blink at the same time but at different frequencies.
When I try to connect the 2 servo motors using exactly the same technique as the LEDs to get them to sweep simultaneously, they don't work together. Only one works.
Below is the code I am using:
#include <protothreads.h>
#include <Servo.h>

Servo myservo1;
Servo myservo2;

int pos1 = 0;
int pos2 = 0;

////////////////////////     T H R E A D    1     /////////////////////////

pt ptServo1;
int servoThread1(struct pt* pt) {
  PT_BEGIN(pt);
  for(;;) {
    for (pos1 = 0; pos1 <= 180; pos1 += 1) {
      // in steps of 1 degree
      myservo1.write(pos1);
      delay(2);
    }
    delay(500);
    for (pos1 = 180; pos1 >= 0; pos1 -= 1) {
      myservo1.write(pos1);
      delay(2);
    }
    delay(500);
  }
  PT_END(pt);
}

////////////////////////     T H R E A D    2     /////////////////////////
pt ptServo2;
int servoThread2(struct pt* pt) {
  PT_BEGIN(pt);
  for(;;) {
    for (pos2 = 0; pos2 <= 180; pos2 += 1) {
      // in steps of 1 degree
      myservo2.write(pos2);
      delay(2);
    }
    delay(500);
    for (pos2 = 180; pos2 >= 0; pos2 -= 1) {
      myservo2.write(pos2);
      delay(2);
    }
    delay(500);
  }
  PT_END(pt);
}

void setup() {
  myservo1.attach(9);
  myservo2.attach(6);
}

void loop() {
  PT_SCHEDULE(servoThread2(&ptServo2));
  PT_SCHEDULE(servoThread1(&ptServo1));
}

In the loop() function, whichever thread is called first, that's the servo that sweeps. The second servo does not do anything at all.
Any help would be greatly appreciated!
Thank you so much,
H

You must use PT_SLEEP not delay to allow your threads to co-exist. That's what the examples use, so why did you decide not to?

@Majenko Thank you, yes that has indeed solved my first problem....I have another problem which I will post in another question. Thank you so much, please have a look at that also if you can! Thank you so much :)


text:
How do I modify the value of a variable when I press a switch
I am new to arduino and I want to make a project where I have a motor spinning clockwise then when a button is pressed it spins anti-clockwise and if it is pressed again it goes back to clockwise etc... Unfortunately I am having trouble getting this to work. How I was aiming to make it work was to have a variable and whenever a button is pressed the value of that variable changes from HIGH to LOW to HIGH and so on and based on that variable the motor spins in either direction. I have got this code so far:
const int buttonPin = 8;     // the number of the pushbutton pin

// variables will change:
int buttonState = 0;         //variable to change status

void setup() {

 Serial.begin(9600);
 pinMode(buttonPin, INPUT);
}

void loop() {
 // read the state of the pushbutton value:
 buttonState = digitalRead(buttonPin);
 Serial.print("Digital value: ");
 Serial.println(buttonState);
 delay(150);
}

so, what is your question? ... you are doing good so far

use the Bounce2 library to read the button

You've made a good start by first working with the button by itself (no motor) to keep your experiments simple. You've probably noticed that buttonState changes when you press or release the button, where your description says you want it to change each time you press the button. That means you have to ignore the releases, and invert the buttonState only on the presses.
Make that change next.
When you test that, you may discover that the buttonState changes several times when you press it once. Mechanical switches may make/break... several times at each change. (It's called bouncing even though it isn't "bouncing" but the two contacts grating across one another. The result is the same.) There are several ways to deal with that, but the simplest is to wait 20-30 milli-seconds after you first see a change; read it again, and if it is still in the new state, accept that, otherwise ignore it. That time delay is approximate; you might need to adjust it for a particular button.
Once you've decided that the button really has been pressed, then change the direction of the motor.

Thank you that is a good explanation

I would recommend that you "debounce" the button input first. Instead of re-inventing the wheel, you could use an existing library: Bounce2.
Using the conditioned input, you could simply manipulate a counter to determine state.
// Connect one end of a N.O. push button switch to
// GND and the other end to pin 2 of the Arduino.
#include <Bounce2.h>
byte buttonState = 0;
const byte modeButtonPin = 2;
const unsigned long debouncerInterval = 50;  // Time in ms.

Bounce modeButton = Bounce();

void setup(){
  Serial.begin(9600);
  pinMode(modeButtonPin, INPUT_PULLUP);
  modeButton.attach(modeButtonPin);
  modeButton.interval(debouncerInterval);
}

void loop(){
  if(modeButton.update()){
    if(modeButton.read() == 0){
      buttonState++;
      if(buttonState > 1){buttonState = 0;}
      Serial.println(buttonState);
    }
  }
}

First I would make create an enumeration type and motor direction variable (instead of the button state):
enum EMotorDirection
{
    CLOCK_WISE,
    COUNTER_CLOCK_WISE
}

EMotorDirection _motorDirection = CLOCK_WISE;

Then read the button and when it has changed (make a variable `_previousButtonState), adjust the motor direction.
int _previousButtonState = LOW;

In the loop function:
int buttonState = digitalRead(buttonPin);
// Debounce buttonState;
if (buttonState != _previousButtonState)
{
   if (_motorDirection == CLOCK_WISE)
   {
       _motorDirection = COUNTER_CLOCK_WISE;
   }
   else
   {
       _motorDirection = CLOCK_WISE;
   }
   SwitchMotorDirection();

   _previousButtonState = buttonState;
}

And create the function SwitchMotorDirection
void SwitchMotorDirection()
{
   if (_motorDirection == CLOCK_WISE)
   {
       // Control motor clock wise
   }
   else
   {
       // Control motor counter clock wise
   }
}

The above example is not compiled, and also it could be smaller, but serves as a explanatory example, with the advantage to separate the UI (button), state machine (state variable), and hardware (motor).
Below is the complete code, which compiles. The bouncing has to be implemented (check the link for that above), and the actual motor driving.
// Types

enum EMotorDirection
{
    CLOCK_WISE,
    COUNTER_CLOCK_WISE
};

// Constants
const int _buttonPin = 8;     // the number of the pushbutton pin

// Global variables
int             _previousButtonState = LOW;
EMotorDirection _motorDirection      = CLOCK_WISE;

// Function prototypes
void SwitchMotorDirection();

// Functions

void setup()
{
  Serial.begin(9600);
  pinMode(_buttonPin, INPUT);
}

void loop()
{
  int buttonState = digitalRead(_buttonPin);
  // Debounce buttonState;
  if (buttonState != _previousButtonState)
  {
     if (_motorDirection == CLOCK_WISE)
     {
         _motorDirection = COUNTER_CLOCK_WISE;
     }
     else
     {
         _motorDirection = CLOCK_WISE;
     }
     SwitchMotorDirection();

     _previousButtonState = buttonState;
  }
}

void SwitchMotorDirection()
{
   if (_motorDirection == CLOCK_WISE)
   {
       // Control motor clock wise
   }
   else
   {
       // Control motor counter clock wise
   }
}

I am very new and I have no idea how to compile this could you maybe tell me?

I added the code which compiles.


text:
Simulating a button press using the Serial Monitor to run a Servo
I'm kind of new to Arduino and C, and I was having trouble with this sketch. I'm working on a project to control 6 servos using virtual buttons. When I hold down the button, the servo moves forward smoothly to a certain fixed point, and when I release it, it comes back to a fixed point. I initially tested this with a single servo and an actual button on my breadboard using the following sketch.
#include<Servo.h>
int switch1;
float switch1Smoothed;
float switch1Prev;
Servo myservo1;
float a=1200.0; //lower angle limit

void setup() {

  Serial.begin(115200);
  pinMode(A1,INPUT_PULLUP);
  myservo1.attach(9);
  myservo1.writeMicroseconds(a);
  switch1Prev=a;
}

void loop() {
//Motor 1
  switch1 = digitalRead(A1);// read switch | will return 1 or 0 continuously
  //Serial.println(switch1);
  switch1 = switch1 * 2400;        // multiply by angle limit

  // *** smoothing ***

  switch1Smoothed = (switch1 * 0.05) + (switch1Prev * 0.95);
  if(switch1Smoothed>=a){
  switch1Prev = switch1Smoothed;
  }
  else{
    switch1Prev = a;
  }
  // *** end of smoothing ***

//  Serial.print(switch1);                  // print to serial terminal/plotter
//  Serial.print(" , ");
//  Serial.println(switch1Smoothed);
    myservo1.writeMicroseconds(switch1Smoothed) ;
    delay(10);                               // repeat loop 100 times per second
}

This works out just fine. Now, I'm working with NodeRed, a low code JavaScript flow creator, which is where my virtual button is, and I've set it up to send 0s or 1s as strings based on whether the button is pressed or not via serial communication. This is the config of the Serial Node on NodeRed:

And I wrote a short function on Arduino to parse the incoming string from the serial connection, convert it back to an integer, and then use that as my "button" input. However, it seems that either my logic is flawed, or my code is because my servo does not behave the same way it does with the physical button.
Here's the modified sketch:
#include <Servo.h>
int switch1;
float switch1Smoothed;
float switch1Prev;
Servo myservo1;
float a=1200.0;
String readString, mot1, mot2;

void setup() {
  Serial.begin(9600);
  myservo1.attach(9);
  myservo1.writeMicroseconds(a);
  switch1Prev=a;
}

void captureChar(int& n1){ //using reference to pass the value

  while (Serial.available()) {
    delay(3);  //delay to allow buffer to fill
    if (Serial.available() >0) {
      char c = Serial.read();  //gets one byte from serial buffer
      readString += c; //makes the string readString
    }
  }

  if (readString.length() >0) {

      mot1 = readString.substring(0,1);
      mot2 = readString.substring(1,2);
      n1 = mot1.toInt();
      //n2 = mot2.toInt();
    readString="";

  }
}

void loop(){
  captureChar(switch1);
  switch1 = switch1 * 2400;        // multiply by maximum angle limit

  // *** smoothing ***

  switch1Smoothed = (switch1 * 0.05) + (switch1Prev * 0.95);
  if(switch1Smoothed>=a){
  switch1Prev = switch1Smoothed;
  }
  else{
    switch1Prev = a;
  }
  // *** end of smoothing ***

//  Serial.print(switch1);                  // print to serial terminal/plotter
//  Serial.print(" , ");
//  Serial.println(switch1Smoothed);
  myservo1.writeMicroseconds(switch1Smoothed);
  delay(15);
}

When I load this sketch and hold down the virtual button, i.e., send a continuous stream of string "1", the motor simply goes back and forth really fast, rather than slowly moving to the set maximum position and stopping there while the button is held.

first thing, insert a layer of separation between the button press and the servo activation ... a button press sets a buttonPressed flag and releasing a button sets a buttonReleased flag ... no other action is done ... the servo motion part of the program moves the servo only in response to the two flags ... it does not respond to anything else ... when that works correctly  then add code that sets the flags in response to the data received from serial

I will try this and get back to you ASAP. If I'm being completely honest, I'm way out of my depth here, and I appreciate any feedback. It took me a week just to come up with what I have now.

There may be a problem with your smoothing logic, which is quite
convoluted. However, if the first code works fine, you can keep it
almost as-is, and only replace digitalRead() with a version that
reads the virtual button. It looks like that is what captureChar()
attempts to achieve. This function, however, has a couple of problems:

it has a loop and a delay, thus breaking the timing of the original
code
its interface is very different from the one of digitalRead(), and
thus cannot be used as a drop-in replacement.

Here is what I would propose as a digitalRead() replacement. It has
the same signature as the original digitalRead(), and can be used as a
drop-in replacement:
int virtual_switch_reading = LOW;

int virtualDigitalRead(uint8_t /* pin number ignored */) {
    int c = Serial.read();
    if (c == '0')
        virtual_switch_reading = LOW;
    else if (c == '1')
        virtual_switch_reading = HIGH;
    return virtual_switch_reading;
}

Note that calling Serial.available() is not useful: if no data is
available, Serial.read() returns -1, which is neither equal to '0'
nor equal to '1'.

Edit: addressing the requirement to have six virtual switches.
As stated in a comment, I suggest you encode the states of all the
switches, within NodeRed, as a single byte, with one bit per switch. You
would then send this byte to the Arduino, either periodically or
whenever any switch changes state.
On the Arduino, in order to simulate digitalRead() on a virtual
switch, you first have to map the pin numbers to the virtual switches:
// Map a pin number to a virtual switch.
const uint8_t virtual_switch_masks[NUM_DIGITAL_PINS] = {
    0,     // pin 0: not virtual
    0,     // pin 1: not virtual
    1<<0,  // pin 2: virtual switch 0
    1<<1,  // pin 3: virtual switch 1
    // etc...
};

Note that this table doesn't store switch numbers. It instead stores
bit masks. For example, virtual switch 1 is stored as 1<<1 =
0b00000010, i.e. all bits are clear except for bit number 1 (rightmost
being zero), which is set.
You can then simulate digitalRead() by extracting the relevant bit
from the byte you last received from NodeRed, which is done by a
bitwise and with the relevant mask:
// States of all virtual switches, one bit per switch.
uint8_t virtual_switch_states = 0;

int virtualDigitalRead(uint8_t pin) {
    uint8_t mask = virtual_switch_masks[pin];

    // If this is not a virtual switch, do a regular digitalRead().
    if (!mask)
        return digitalRead(pin);

    // For a virtual switch, extract the relevant bit
    // from virtual_switch_states.
    if (virtual_switch_states & mask)
        return HIGH;
    else
        return LOW;
}

In order to update the states of the virtual switches from the data
received, you just have to add this somewhere within loop():
if (Serial.available())
    virtual_switch_states = Serial.read();

This would work if I were using a single motor only though, right? I plan to use 6 motors, and I was considering sending a string of the form "000000" with each character representing the state of 1 of 6 motors (I would basically have 6 virtual switches on NodeRed)

Also, regarding the smoothing, I do agree it's not very refined, but it's the easiest bit of code I could come up with and felt that would be sufficient for the purposes of my project. However, I'm definitely open to suggestions or ideas on improving it, and more importantly, help with maybe improving the virtual button part.

@rayank97: A string like "000000" wouldn't work very well, as you cannot know where one string ends and the next one begins. You would have to add some sort of delimiter. It would be simpler to send a single byte, where the six switch positions are encoded as individual bits.

@rayank97: Regarding the smoothing: you can simplify it by removing switch1Prev and using switch1Smoothed instead. Also, if you set switch1 = 1200 + 1200*digitalRead(A1);, then switch1Smoothed will always be between 1200 and 2400: no need to explicitly clamp it.

Thanks for the idea for the smoothing. Regarding the virtual buttons, I just realized that even if I were to send a single byte as you suggested, wouldn't the issue of having 2 separate loops still have the effect of breaking the timing of my original code? Or am I mistaken? If I'm not, could you tell me if you think there's another way I could go about doing this?

@rayank97: There are no separate loops. virtualDigitalRead() would be O(1) even with six switches. See amended answer.


text:
How to pass non-static class member to callback on avr platforms?
I am using the PubSubClient library in my own Arduino library. I'm having trouble with trying to assign a class member as the client library setCallback callback function.
MyClass.cpp:
#include <PubSubClient.h>
#include <Wifi.h>
#include "Arduino.h"
#include "MyClass.h"

WiFiClient wifiClient;
PubSubClient mqttClient(wifiClient);

void MyClass::connect(String host, int port) {
  mqttClient.begin(host, port, "/");
  mqttClient.setCallback(incomingEventHandler);
}

void MyClass::loop() {
  mqttClient.loop();
}

void MyClass::incomingEventHandler(char* type, byte *payload, unsigned int length) {
  // do stuff with incoming data
  // need to access other member functions and class variables
}

MyClass.h:
#ifndef MyClass_h
#define MyClass_h

#include <PubSubClient.h>
#include <Wifi.h>
#include "Arduino.h"

class MyClass {
  public:
    void connect(String host, int port);
    void loop();
    void incomingEventHandler(WStype_t type, uint8_t *payload, size_t length);
};

#endif

Error I see is:
sketch/MyClass.cpp: In member function 'void MyClass::connect(String, int)': MyClass.cpp:14:47: error: no matching function for call to 'PubSubClient::setCallback()'
mqttClient.setCallback(incomingEventHandler);

If I move the incomingEventHandler function outside the class definition, it works as expected, however then I can't call other class members or access class properties in the same scope.
In arduino c++ how can I pass non-static class member properties as a callback? Is there a better way to approach this?
P.S. This code is only to show the intent. It might not be compile too.
There was a similar question like this at: How to pass non-static class member to callback?
but this is for esp-8266 and this is for avrmega4809 based board.

Personally I usually write a small wrapper that calls a function on a global object. Either as a normal function or as a static function if I only ever need one instance. Crude, but effective.

You can't. On the AVR platform, PubSubClient::setCallback() expects a
raw function pointer as a callback, and that is what you have to
provide. A static method is equivalent to a raw function, a non-static
method is not, and neither are a functor or an std::function.
If you need more that one MyClass object, one solution might be to
modify the pubsubclient library in order for it to store a pointer to
your MyClass instance, and pass this pointer to your callback. If you
never have to instances of MyClass subscribe to the same topic, a
better solution might be to statically store a map from topics to
MyClass instances and, within the callback, use this map to find the
appropriate instance.

Technically you can do it, but not without changing the library. Easiest way would be pure virtual interface class definition and inherit from it and override callback method. Another way would be https://www.tutorialspoint.com/function-pointer-to-member-function-in-cplusplus (similar changes as the first way)


text:
Audio range with custom waveshape
I am planning to use several Arduino to produce audio range analog signals. I need to use custom waveshapes generated on the fly. As far as I understand, there are two paths:

Aquiring a DAC, but can I send instructions fast enough (the Arduino needs to process the waveshape table) for audio rate signals? On a DAC like this one, I see that it supports a 100kb/s standard I2C and a 12 bit precision, so my guess is I will have 100kb/s / 12b / 10kHz = 0.8 input/period at 10kHz... Will this suffice? Or will it creates compression artefacts?
Using the Mozzi library, but it seems to me it outputs through a PWM digital IO pin. As I have a lot of Arduino to process, I would like to limit the number of RC circuitry I have to solder. Moreover, can Mozzi use custom waveshapes?

If you see any other solution, you are very welcome !
Thanks in advance

and I2S DAC ? .

Keep in mind the nyquist rate: You need at very least 2 samples per period to make sure the resulting wave has anything to do with the real target wave. And when you want to represent the shape of the wave correctly, then you will need significantly more samples. What is the highest frequency signal part, that you need to represent?

I need to go up to 20 kHz. I will investigate the I2S path. Thanks !


text:
Some code only works when USB serial port connected
I'm using Arduino Uno as my microcontroller, but I got a strange behavior. I need to run several function at the same time. One to get GPS and temperature value then send every value to user's phone number when a request received by SIM800L GSM module, and another to display those value on I2C LCD. Everything works fine when my USB port connected to my computer. But when I tried to unplug the USB and using external power source from Li-Po battery I can't get a response from SIM800L module whenever I send a request message.
When I tried to create a separate program (just received a request message and then sent a response by SIM800L) it works fine even though using external power supply (Li-Po battery) without USB port plugged in. Another strange behavior is when I was using both of Li-Po battery and USB port connected then unplugged the USB port it works fine again. But when I unplugged my battery and then plugged it again without USB port connected, SIM800L couldn't send a response. What is wrong ?
This is my full code:

#include <TinyGPS++.h>
#include <SoftwareSerial.h>
#include <LiquidCrystal_I2C.h>
#include <SoftwareSerial.h>
#include "DHT.h"

//sms
char ReceivedSms;
short DHT_OK=-1, GPS_OK=-1;
String DataSms;
int _timeout;
String _buffer;
String number = "+62811XXXXXX";

//dht
#define DHTPIN 5
#define DHTTYPE DHT11

LiquidCrystal_I2C lcd(0x27,20,4);
SoftwareSerial sim800l(2,3);
DHT dht(DHTPIN, DHTTYPE);

// The TinyGPS++ object
TinyGPSPlus gps;

void setup()
{
  Serial.begin(9600);
  sim800l.begin(9600);
  dht.begin();
  lcd.init();                      // initialize the lcd
  // Print a message to the LCD.
  lcd.backlight();
  _buffer.reserve(50);
  ReceiveMode();
}

void loop()
{
   displayInfo();

}

void displayInfo()
{
  String RSMS;

  while(sim800l.available() > 0) {
      ReceivedSms = sim800l.read();
      RSMS.concat(ReceivedSms);
      GPS_OK = RSMS.indexOf("All");
   }

  if (gps.location.isValid())
  {
    lcd.clear();
    lcd.setCursor(0,0);
    lcd.print("Latitude  : ");
    lcd.println(gps.location.lat(), 6);
    lcd.setCursor(0,1);
    lcd.print("Longitude : ");
    lcd.println(gps.location.lng(), 6);
    delay(5000);
    lcd.clear();
    lcd.setCursor(0,0);
    lcd.print("Suhu       : ");
    lcd.println(dht.readTemperature());
    lcd.setCursor(0,1);
    lcd.print("Kelembaban : ");
    lcd.println(dht.readHumidity());
    delay(2000);

    if(GPS_OK!=-1)
        {
        String link = "http://www.google.com/maps/place/" + String(gps.location.lat(),6) + "," + String(gps.location.lng(),6);
        DataSms = "ALL\nSuhu = "+String(dht.readTemperature(),1)+" C"+" \nKelembaban ="+String(dht.readHumidity(),1)+" %"+" \nMaps = "+link;
        SendMessage();
        ReceiveMode();
        GPS_OK = -1;
        }
  }
  else
  {

    lcd.clear();
    lcd.setCursor(0,0);
    lcd.print("GPS not found");
    delay(2000);
    lcd.clear();
    lcd.setCursor(0,0);
    lcd.print("Suhu      :");
    lcd.println(dht.readTemperature());
    lcd.setCursor(0,1);
    lcd.print("Kelembaban:");
    lcd.println(dht.readHumidity());
    delay(2000);

    if(GPS_OK!=-1)
       {
        DataSms = "ALL\nSuhu = "+String(dht.readTemperature(),1)+" C"+" \nKelembaban ="+String(dht.readHumidity(),1)+" %"+" \nMaps = Lokasi Tidak Ditemukan";
        SendMessage();
        ReceiveMode();
        GPS_OK = -1;
       }
  }

}

String _readSerial() {
  _timeout = 0;
  while  (!sim800l.available() && _timeout < 12000  )
  {
    delay(13);
    _timeout++;
  }
  if (sim800l.available()) {
    return sim800l.readString();
  }
}

void ReceiveMode() {
  sim800l.println("AT");
  delay(100);
  sim800l.println("AT+CMGF=1");
  delay(100);
  sim800l.println("AT+CNMI=2,2,0,0,0");
  delay(100);
}

void SendMessage()
{
  //Serial.println ("Sending Message");
  sim800l.println("AT+CMGF=1");    //Sets the GSM Module in Text Mode
  delay(1000);
  //Serial.println ("Set SMS Number");
  sim800l.println("AT+CMGS=\"" + number + "\"\r"); //Mobile phone number to send message
  delay(1000);
  String SMS = "Hello from 800L...";
  sim800l.println(DataSms);
  delay(100);
  sim800l.println((char)26);// ASCII code of CTRL+Z
  delay(1000);
  _buffer = _readSerial();
}

Just for your information I'm using Li-Po battery 7.4V 2200mAh

I suspect that you have power supply issues when you are not connected to the USB.  Using your voltmeter, please measure the Uno's supply voltage when not connected to USB.  Also check the supply voltage for the SIM800 when disconnected.

You never call gps.encode(...) - and anyway, where is your GPS connected? I see no SoftwareSerial for it (which by the way can only listen on ONE interface at a time).

It sounds like but I am only guessing you have a grounding problem. Be sure all the grounds are connected together.  I assume you are connecting the lipo battery to Vin and not the 5V pin. The battery voltage swings to much for stable operation. Be sure to follow jwh20's suggestions and you should be operational.

@Majenko I'm using digital pin 0 and 1 for my GPS.. that's work fine although I have to disconnected GPS VCC pin first during uploading my program

@Gil I'm connecting the Li-Po battery to my 5v stepdown then I'm connecting the output of this stepdown to 5v Arduino pin, is this okay to directly connecting 7.4V Li-Po battery to 5v Arduino pin?

Here I attach my simple schematic wiring of how do I power up my Arduino and another part: https://github.com/Proxcentaur/track-gps-sim/blob/main/wiring.PNG

@Majenko I have tried using 2 software serial in Arduino Uno but it doesn't work. Then I have decided to use digital pin 0 and 1

@jwh20 I have measured it, Uno supply voltage when not connected to USB and just connected to battery is 8.04V

Pins 0 and 1 conflict with the usb serial. You can't j use both.

I have solved my problem by click on Arduino reset button pin after all of my components got a power supply. Somehow I can't explain why does it work after doing that simple thing

Good to hear! It always helps to feed them good electrons:-)


text:
PZEM-004T can't read current
I'm trying to measure the current, voltage, and power of AC load using Peacefair PZEM-004Tv3.0 module. For the serial communication of this module, I'm using SoftwareSerial Pins 2 and 3 on Arduino Uno.
But this module seems doesn't work well, it just read the voltage and the rest is zero. The datasheet said:

current test value is from the beginning of 0.02A
power test value is from the beginning of 0.4W

I have assumed the load that I'm trying to measure hasn't enough minimum current or power. But I have tried to measure a bigger load also, and the result of current and power measurement is still zero.
I don't think it is caused by the program because I just run the example of the library. I'm using this library.
Here I attached how do I wire my pieces stuff:

Any suggestions?

SoftwareSerial doesn't work well at 115200 baud on the 8 bit Arduinos. They can't keep up with the flow of data.

Have you tried placing the sensor over the other AC load wire?

Uhh, are you running the line and return through the same CT and going in opposite directions?

I created an answer thinking that it was.  For anyone that doesn't see it, if you zoom in your can just barely tell that the black wire is in fact outside the CT.

It should always be on one lead, not both, and I could see the black is outside. What I suggested is placing the sensor on the "other" lead, meaning remove the red and try the black. Also, have you tried reducing the speed to 9600 as Majenko suggested?

@Nino, to be clear, none of what I wrote was addressing your suggestion.

I have tried all of your suggestions but it still doesn't work guys :(

just changed the CT with the new one and now everything works fine, thank you :D

It would probably be best to delete the question.