# Question
Title: Frequency problems with DIY arduino and resonator
I made a simple music program using an arduino Uno and the `tone()` function. It works fine.

I decided to build my own circuit using a barebones AVR and upload that program. I did not know exactly what frequency was being used by the arduino, so I used a Murata resonator, with a frequency of 8 MHz.

When I put my circuit to the test, the music that I had generated was played an octave lower, and its duration was doubled (taking twice the time to finish played a note).

I figured out that I used the wrong resonator frequency. Indeed, I found out that the Arduino Uno used a 16 MHz resonator. Since I had half that frequency in my clock, the tone would be lower frequency, and it would take twice the time to finish a note. This made sense.

So I went ahead and rebuilt the circuit with a 16 MHz resonator frequency. However, now I have the opposite effect!

All the notes are one octave higher compared to my original Arduino Uno design, and the note duration finished in hald the time compared to the original Arduino Uno design... This suggests that I now have doubled the frequency compared to the original design (and four times the frequency compared to my first custum circuit attempt).

I cannot seem to understand why this is happening, because right now I have the frequency that the original Arduino uses....

# Answer
If the code runs at twice at the expected speed when clocked at 16 MHz, this can only be because either:

* you fixed the program to run correctly when clocked at 8 MHz
* you told the IDE that you are using a 8 MHz clock.

The IDE comes with a few configurations that are suitable for an 8 MHz clock. If you select as a board “Arduino Pro or Pro Mini”, you have something equivalent to an Arduino Uno, except that you can choose between an 8 MHz clock and a 16 MHz clock (and also between an ATmega168 and a 328P).
> 2 votes

---
Tags: audio, frequency, oscillator-clock
---


# Question
Title: Pressure transducer returns 2.4v at 0 psi when working with a 0.5v to 4.5v pressure transducer
I have this pressure transducer: https://www.amazon.co.uk/dp/B07YZL6TYD?psc=1&ref=ppx\_yo2ov\_dt\_b\_product\_details

The transducer has a range of 0.5v to 4.5v which translates to 0 psi to 100 psi.

When I hook the transducer up to a Arduino boards analog pin, whose range is between 0 to 1024, it returns about 520 at 0 psi.

When I measure with a meter, it reads 2.4v which i think should not measure that much.

What am I doing wrong?

# Answer
Is the pressure sensor measuring relative pressure or absolute pressure?

Assuming the pressure sensor is measuring absolute pressure:

* 1 atmosphere is about 14 pounds per square inch (PSI).
* Altitude and weather change that so it is unreliable / not-constant. But for many uses it is close enough.
* (14/100 PSI * (4.5V - 0.4V)) + 0.4V = 0.546V + 0.4V = 0.946V

The expected voltage given the parameters in the question, assuming this is an absolute pressure sensor and that it has a linear response, should be near 1 Volt. But it is over double that. Consider checking the supply voltage to the sensor. Also consider disconnecting the output of the sensor from the Arduino board and repeating the voltage measurement. Finally, make sure the above assumptions are accurate.
> 1 votes

# Answer
I would expect your pressure transducer has an initial offset voltage, typically 0.5V, it states Output: 0.5 - 4.5 V / 0 - 5 V. I would also expect the output to be about 4.5V at full pressure but this is only a SWAG as there is no data sheet available. It might have been a good price but was it worth all of the time it is taking you to determine if it is OK? Are the meter readings correct, I cannot determine that unless I know what type of output the transducer has. Is it actually analog, does it need a pull up resistor, output loading requirement, ???

If you cannot get the information from the vendor I think the only way you will really know is to connect several up and test them. There are several types of pressure transducers in this package, they are absolute (atmospheric pressure) and Gauge (PSIG) (Pounds Per Square Inch). The nice looking advertisement on your link does not give this or much other needed information such as what media is it compatible with other then a few.
> 0 votes

---
Tags: arduino-mega, pressure
---


# Question
Title: Problem with Bing generated code for automated chicken coop door
Glenn from Sweden here. I was wondering if some kind soul could help me out here.

My partner bought a cheap chinese knock-off automatic chicken coop door that operates based on sunlight. Link to the actual chicken coop door In the morning the door opens and at the evening the door closes. It does this (from my humble understanding) with a LDR, a 5v dc motor and a small circuit board. The main problem is that the door opens way to early (about 07:00 am) with the risk that predators may snatch the chickens and there is no way to regulate the opening/closing times.

What I would like is the following: I would like the door to open at 10:00am and close at 21:00pm every day of the week using the existing 5v motor. I do have some 28BYJ-48 step motors and A3967 driver boards I bought 10+ years ago, but then I would have to start modify physical things to get it to fit. I rather not do that if it’s possible to use the original parts.

Now, coding is way over my head. Some people can draw beautiful things with paints and brushes, others can not. I can get some LED's to flash but I just can’t wrap my head around ”advanced” coding like this project. That is why I, out of desperation, tried to get Bing A.I. to write the code for me. **I can compile the code without any errors, but it doesn’t work IRL. The motor does not start at the specified time, and sometimes the motor starts to spin out of the blue but doesn’t stop spinning.** I have installed ”Time (1.6.1) by Michael Margolis” in the Arduino Library Manager to get the timer function to work. Is that the problem?

I must mention here that the three leads from the SN754410 originally was routed to pins 7,8,9 on the Arduino, but since it didn't work I tried switching them to 3,5,6 in case it had something to do with the analog output?

With the original electronics the door opens and closes mechanical fine, but I don’t understand how the ”brain” knows when to stop the motor so it doesn’t start to crunch the gear on the motor. There are no microswitches at the end points or anything…

I added the red and green LED's (got Bing to include them in the code) just to be able to see when the door opens/closes if dark outside).

I understand a Fritzing layout is preferable so I did my best to create one. Its my first time so please bear that in mind.

```

    // Include the Time library
#include <TimeLib.h>

// Define the pins for the motor controller
#define ENA 6
#define IN1 5
#define IN2 3

// Define the pins for the LEDs
#define GREEN_LED 10
#define RED_LED 11

// Define the times for the motor actions
#define START_TIME 1825 // 10:25 AM in 24-hour format
#define END_TIME 1925 // 21:25 PM in 24-hour format
#define DURATION 20 // 20 seconds

// Define a variable to store the current time
int currentTime;

// Define a variable to store the motor state
int motorState;

// Define the motor states
#define STOPPED 0
#define CLOCKWISE 1
#define COUNTERCLOCKWISE 2

void setup() {

  setSyncProvider(getTime);

  // Set the motor pins as outputs
  pinMode(ENA, OUTPUT);
  pinMode(IN1, OUTPUT);
  pinMode(IN2, OUTPUT);

  // Set the LED pins as outputs
  pinMode(GREEN_LED, OUTPUT);
  pinMode(RED_LED, OUTPUT);

  // Stop the motor and turn off the LEDs initially
  stopMotor();
  turnOffLEDs();

  // Set the time to sync with the computer's time
  setTime(17,27,10,7,10,2023); // hour,minute,second,day,month,year
}

void loop() {
  // Get the current time in HHMM format
  currentTime = hour() * 100 + minute();

  // Check if the current time matches the start time or the end time
  if (currentTime == START_TIME || currentTime == END_TIME) {
    // Check the motor state and switch it accordingly
    switch (motorState) {
      case STOPPED:
        // Start the motor clockwise and turn on the green LED
        startMotor(CLOCKWISE);
        turnOnLED(GREEN_LED);
        break;
      case CLOCKWISE:
        // Stop the motor and start it counterclockwise after DURATION seconds and switch the LEDs accordingly
        stopMotor();
        turnOffLED(GREEN_LED);
        delay(DURATION * 1000);
        startMotor(COUNTERCLOCKWISE);
        turnOnLED(RED_LED);
        break;
      case COUNTERCLOCKWISE:
        // Stop the motor and start it clockwise after DURATION seconds and switch the LEDs accordingly
        stopMotor();
        turnOffLED(RED_LED);
        delay(DURATION * 1000);
        startMotor(CLOCKWISE);
        turnOnLED(GREEN_LED);
        break;
    }
  }
}

// A function to stop the motor
void stopMotor() {
  // Set the enable pin to low
  digitalWrite(ENA, LOW);

  // Set the motor state to stopped
  motorState = STOPPED;
}

// A function to start the motor in a given direction
void startMotor(int direction) {
  // Set the enable pin to high
  digitalWrite(ENA, HIGH);

  // Set the input pins according to the direction
  if (direction == CLOCKWISE) {
    digitalWrite(IN1, HIGH);
    digitalWrite(IN2, LOW);
    motorState = CLOCKWISE;
  }
  else if (direction == COUNTERCLOCKWISE) {
    digitalWrite(IN1, LOW);
    digitalWrite(IN2, HIGH);
    motorState = COUNTERCLOCKWISE;
  }
}

// A function to turn on a given LED pin
void turnOnLED(int ledPin) {
  // Set the LED pin to high
  digitalWrite(ledPin, HIGH);
}

// A function to turn off a given LED pin
void turnOffLED(int ledPin) {
  // Set the LED pin to low
  digitalWrite(ledPin, LOW);
}

// A function to turn off both LEDs
void turnOffLEDs() {
  // Turn off both LED pins
  turnOffLED(GREEN_LED);
  turnOffLED(RED_LED);
}
  // A function that gets the time from the computer
time_t getTime() {
  // Check if there is serial data available
  if (Serial.available()) {
    // Read the serial data and convert it to a time_t value
    time_t t = Serial.parseInt();
    // Return the time value if it is valid
    if (t >= 946684800) { // Check if the value is after 1 Jan 2000
      return t;
    }
  }
  // Return a zero value if there is no valid time
  return 0;
}

```

# Answer
> 1 votes
Using generative AI is only really helpful, if you have enough knowledge to work further with the generated code. Current LLMs are not as plug and play as many believe them to be.

Timemages idea of covering the LDR with an LED in your control seems very reasonable. Then you don't need to hassle with the motors. Try taping one if your LEDs to the sensor and use a blink code to test that. You might need a brighter LED, depending on the LDR. Just make sure to use a transistor in low side switch configuration, if the needed current for the LED is greater than 20mA, which is the maximum continous current for a digital output pin (small bipolar transistors are very cheap; you will find much information online when searching for something like arduino transistor low side switch).

Then about the time keeping: The Arduino itself is not good at keeping time accurately over a longer span. Due to manufacturing differences and temperature clock drift your time will be very much off after some days. For this you need a RTC (Real Time Clock). It has a very precise internal clock, so it can keep time accurately over long timestamps. You can buy ready to use RTC modules which also include a battery backup, so that the clock doesn't loose time on powerloss. Often these modules are build with the DS3231. There are also libraries for this RTC, for example this one. Look at the provided alarm example, because that is what you want (code triggering on specific times of the day). Use that example as starting point and make the LED turn on and off at these alarms. That are only small changes to the existing example code.

---
Tags: programming, motor, timers
---


title: Rising and falling edge on GPIO_STM32G4

text:
# Question
Title: Rising and falling edge on GPIO_STM32G4
I am working with STM32G491RE.I am giving pulse to GPIO pin from function generator. That pulse will be 2 msec on time and 8msec off time.I need to make flag high if the signal from function generator lost. Can anyone suggest me how to do this?

```
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
if(GPIO_Pin==detect_Pin){
if(HAL_GPIO_ReadPin(detect_GPIO_Port,detect_Pin)==GPIO_PIN_SET){
 HAL_UART_Transmit(&huart2, (uint8_t *)"rising:",7, HAL_MAX_DELAY);
 }
else if(HAL_GPIO_ReadPin(detect_GPIO_Port,detect_Pin)==GPIO_PIN_RESET){
 HAL_UART_Transmit(&huart2, (uint8_t *)"falling:",8, HAL_MAX_DELAY);
 }
else
{
 HAL_GPIO_WritePin(led_GPIO_Port,led_Pin,GPIO_PIN_SET);
}

```

I tried with EXTI interrupt but If input is there from generator its detecting both rising and falling edge and if there is no signal from generator I am not getting in to else condition.

1.If I want to make flag high for no signal from function generator,above image offtime also it considering as no signal.

can anyone suggest how to do?

Thanks

# Answer
I do not know how to use the HAL API you are using. I will instead suggest an approach based on the Arduino API, which is more suitable for this site.

Take note of the current time on every transition you detect. When the time since the last detected transition is longer than a predefined timeout, you know the pulse train has stopped:

```
const uint8_t pulse_pin = 2;
const uint32_t pulse_timeout = 10;  // milliseconds

volatile uint32_t last_input_change;  // last time we detected a change

void on_input_change()
{
    last_input_change = millis();
}

void setup() {
    Serial.begin(9600);
    attachInterrupt(digitalPinToInterrupt(pulse_pin),
            on_input_change, CHANGE);
}

void loop() {
    // Avoid a data race while reading last_input_change.
    noInterrupts();
    uint32_t last_input_change_copy = last_input_change;
    interrupts();

    if (millis() - last_input_change_copy >= pulse_timeout)
        Serial.println("The pulse train stopped.");
}

```

Note that, for this to work, your whole code should be non-blocking, which is a good practice in any case.
> 2 votes

---
Tags: interrupt, stm32
---


# Question
Title: How can I get servos to not brownout my Arduinos and power supply?
I have a problem with a project where one servo is resetting (browning out) two Arduino Pro Minis running 3.3v/8mHz. The two Arduinos are connected by SoftwareSerial on pins 9 and 10 and the slave sends yaw data to the master Arduino obtained from an MPU9250 breakout board. The power supply can supply 1 A of current. The servo is a small 2g servo that takes 3.3v at 50mA when moving (measured, not from the datasheet). Everything is hooked up on a breadboard. In case you're wondering, I am using an adaptation of the ServoTimer2 library to control the servos so as to not interfere with SoftwareSerial. I am baffled as to why one small servo is resetting two Arduinos. The Arduinos, along with the MPU9250, are only drawing 10mA. Could back EMF be causing the brownout?

In the past, I have done a similar circuit but with only one Arduino obtaining sensor data and not sending it over SoftwareSerial. This works completely fine with two servos, a Pro Mini, and an MPU9250 breakout board. This leads me to think it is some sort of software issue.

I have already received some guidance on the Arduino Discord stating to connect ceramic capacitors close to the servos, and this seems to sort of work, but I'm wondering if there might be a software way to do it with the least number of components possible.

Any help would be greatly appreciated!

# Answer
*Note: Commonly you cannot use software to circumvent physics.*

Your symptoms show that the initial current of the servo is too high for your power concept to maintain the voltage. Therefore your Nanos brown out.

An electric motor can easily take a multiple of its average current on acceleration. If blocked, and in the first moment it *is* blocked by the inertia, you can observe factors in low tens. From 50 mA to 1 A it's just a factor of 20...

Please note that servos often control their motors with PWM, and you measure only the average. During the "active" state the current is higher, and depending on the motor's inductive properties can have "strange" wave forms.

Additionally, each wire adds an inductive and resistive component in series with your Nanos and the servo. The shorter and thicker the wires, the better.

So your case looks quite simple, and you have options:

* Decouple your power supply with appropriate capacitors. Ceramics with some tens of nF and an electrolyte or tantalum capacitor with some µF are common to provide the necessary current "reservoir" for the initial moment in different frequency ranges. Put them near the servo(s).
* Use a separate power supply for the servo(s). Do not forget to connect the grounds. But also here you might need capacitor(s) to avoid browning out the servo.
> 0 votes

# Answer
You are seeing classic signs of power supply overload. Those motors can draw upto 10x there operating current when starting. Transients etc that are occuring are to fast for your meter to see but the electronics does. To view that you need a scope and a current probe. My recommendation is to get a larger power supply probably in the 3A range.
> -1 votes

---
Tags: power, servo, softwareserial, arduino-pro-mini, reset
---


# Question
Title: Serial to USD (HID keyboard device) converter
I am working on a project to collect data from a barcode scanner using an Arduino, which in turn is connected to a POS/laptop. So far I am able to collect the data from the barcode scanner by using the Arduino as a host, and in order to send the scanner data from the Arduino to the laptop, I am using a basic FTDI board that converts serial data from the arduino to USB.

However, it shows up as a COM port in my computer and I need an additional serial monitor to see the data transferred from the Arduino.

Is there a device that converts serial data from the arduino to "HID keyboard Device" similar to the FTDI board?

Please let me know if I have not made myself clear or if you need more information.

Edit: I forgot to add that I am using an Arduino MKR NB 1500. I am using the board's native USB port to connect to the barcode scanner. The USBHost library gives the board the ability to act as a USB host and connect to the barcode scanner and get the scanned data from the barcode scanner.

I am using the FTDI board (serial to USB converter) and arduino's serial1 to send the scanned data to my laptop.

We are trying to build a portable device that connects to the barcode scanner and the POS. We are using the Arduino to update our database (I can use the MKR board to send a POST request with the barcode data to update our database) and in addition to this the Arduino should be able to send the scanned data to POS. As of now I am connecting the Arduino's RX and TX pins to the FTDI board, which converts UART to USB. I would like to replace this FTDI board with an interface that converts UART to "USB HID keyboard". Please let me know if more information is needed.

# Answer
> 1 votes
> **I would like to replace this FTDI board with an interface that converts UART to "USB HID keyboard".**

On the left is an "FTDI Friend" that converts serial to USB. It is similar to the Sparkfun product you are using.

On the right is a similar sized, similar priced, board that can read serial and can act as a USB keyboard (Implementing the appropriate HID). It's a Pololu A\*Star micro but it's just one example of many similar devices. I used this one to implement a physical keyboard using mechanical switches but the input could have as easily come from it's serial interface.

Any ATmega32u4 or SAMD based board can act as a USB HID keyboard using the standard Arduino keyboard library

Admittedly you'll have to write and upload a sketch but that ought to be relatively straightforward.

There are also smaller, potentially cheaper, boards such as the Digispark and clones that have a separate software library to implement USB HID Keyboard functionality on a very simple microcontroller like the ATtiny85.

---

> **We are trying to build a portable device that connects to the barcode scanner and the POS.**

As Juraj's comment suggests, many barcode readers started out as serial devices and only later had USB-serial capability added. If you use a Barcode scanner with serial output, you probably don't need any extra hardware and can use the MKR NB 1500's USB interface to act as a keyboard device instead of as a host for the scanner.

# Answer
> 0 votes
use CH9329 chip it's cheap and could act as Keyboard and mouse at the same time. interface is a little bit hard as it's Chinese but it's cost 1 USD only.

---
Tags: serial, usb, hid
---


# Question
Title: When it comes to UART to RS485 communication, what is the difference between the 'MAX485' and the 'HW-0519' module?
I recently found this model with the ID 'HW-0519' on it. It can be found online (HW-0519 in Aliexpress) and is sold for the purpose of converting UART to RS485 communication using Arduino devices. The MAX485 module (MAX485 in Banggood) is the more commonly used module for this purpose and has been used in many projects. The MAX485 has the following pins DI (data in), RO (receiver out), DE (Data Enable), RE (Receiver Enable), VCC, GND and the 'A' and 'B' pins for the RS485 device (Shown below).

The HW-0519 module, has a slightly different pin configuration, and I can't seem to wrap my head around it. It has Tx and Rx pins, which I am guessing match up with RO and DI respectively, but don't have enable pins. They have the VCC and GND pins along with the 'A' and 'B' pins, but also come with this pin marked in Chinese. I translated it using Google translate and it translates to something similar to 'Ground'. Which is not connected to the GND pin though (Shown below).

Does anyone know whether I can use the HW-0519 module in the same manner as the MAX485? If so, are there any libraries written for this module? I want to use the module for communication with a pH sensor like the one in this link.

# Answer
> 3 votes
I did a bit of research and found others who use this particular component for their RS485 communication purposes. It is difficult to get clear info because the device goes by different names and the most commonly used name is MAX485 (name of the IC), which is used interchangeably for both the components shown in the question.

It seems the more I search for the 'HW-0519', the more names I find for it. So far, it goes by the name 'MAX485', 'XY-017', and 'XY-K485'. A clear advantage for this 'HW-0519' is that it does not require D or R enabling, just straightforward Tx and Rx. It also has LEDs to show the data transfers. I found a project that used this module here. I am unsure about their pin connections from the ESP-32 though. It looks like they've connected the ESP-32's TX2 to the HW-0519's Tx, and the RX2 to the Rx. I thought it should be the other way around.

# Answer
> 0 votes
I have the HW-0519 (bought as https://www.amazon.co.uk/gp/product/B0BCFLTLGJ/ at £9.98 for 8x in 2023-09) and it matches the picture above quite closely enough. It is a variant, and the first difference I see is the (?) polyfuses JK075 above are T010 on mine.

I picked this because it has protection components on the board which others don't have - including the MAX485 board from Banggood linked above.

Both boards lack mounting holes but the MAX485 board has pins which (if they align?) might assist breadboard usage. For me, the prototyping phase will start with epoxying HW-0519 to a Lego brick.

I found a circuit diagram at https://easyeda.com/modules/HW-0519-TTL-to-RS485-converter\_c4836920e8ec45b3924add8ac2acbe57 for something similar which helped me work out what's what. I'm not going to steal a copy and upload here but it looks like https://web.archive.org/web/\*/https://image.easyeda.com/components/c4836920e8ec45b3924add8ac2acbe57.png .

My board is a cousin of the circuit diagram I found.

* chips are named U2 (unmarked SOIC14, maybe 74HC04) and anon unmarked SOIC8,
* its TVS protection is done as three chunky 2-pin diodes marked WK as in the HW-0519 above,
* bus termination resistor is R9 and **you have to short R0 to terminate the bus**, so one at each end but not in the middle, in the usual way.
* TVS protection comes to that third bus pin 球大(??) which I think is "earth big (something)"

Note that the bus ground is *not* connected to the logic ground GND on the 4-pin connector. You need to **provide bus ground separately** and maybe from a different source after considering fault currents.

---
Tags: serial, sensors, uart, rs485, modbus
---


# Question
Title: How do I write efficient callback functions on a Teensy 4.0?
I am looking at refactoring my code by implementing callback functions in order to be able to reuse the abstract logic of other functions/classes.

However, I feel I need to learn more about the limits of callback functions on embedded systems like the teensy 4.0 I'm using. The reason I ask is because - if I'm correctly informed - std::function is adviced against on embedded systems due to memory overhead. Another reason for asking is that the functions I want to use for callback might run the risk of violating the principle of keeping callback functions short.

I've consulted the chapter devoted to embedded programming principles in Stroustrup's Programming: Principles and Practice Using C++. Unfortunately, he doesn't give advice on callback functions for embedded systems, specifically.

I understand I can simply rely on a trial and error methodology using function pointers, but figured I'd ask for your experience and advice before I rewrite a lot of code. In other words, I'm asking for good principles and guidelines.

# Answer
I have been using callbacks quite intensively on an Arduino Mega 2560, for managing RS-485 messages. This board has roughly 8 times less flash and 128 times less RAM than your Teensy. However, as the AVR core does not support `std::function`, I used the good old C idiom for defining callbacks:

```
void MyClass::register_callback(
        void (*callback)(some_type some_data, void *callback_data),
        void *callback_data);

```

It is up to the caller to nicely pack all the state needed by the callback into a `struct`, and pass a pointer to this `struct` as the last argument of `register_callback()`. The class will record both the function pointer and the `void*` pointer. When the expected event happens, the class calls the callback, giving it the saved `void*` as its last argument. The callback then casts this pointer to a pointer to the expected `struct`, and now it can access the state it needs.

Yes, this is a bit clumsy, but it is a tried and true way of handling callback state in plain C. And the cost is marginal, especially for your board that has orders of magnitude more resources than my Mega.

If you are afraid of the cost of `std::function`, I suggest you implement a simple callback example using this method, then using `std::function`, and you compare the memory usage. If the cost of `std::function` turns out to be significant, you can always go the C way. I suspect `std::function` will be just fine, and it really is more convenient than handling the function pointer and the state as separate arguments.
> 2 votes

---
Tags: c++, teensy, callbacks
---


# Question
Title: Understanding ESP8266 OTA Updates: A Question on Limitations
I am currently researching OTA updates for ESP8266 firmware, and I have a question that I couldn't find an answer to:

Question: Is the number of OTA updates limited? According to the documentation, it states: "The flash chip size should be large enough to hold the old sketch (currently running) and the new sketch (OTA) at the same time." Does this mean that the old sketch always remains, and with each new update, the previous versions continue to exist? If so, does this imply that after multiple updates, the flash memory will eventually be full, preventing any further updates?

Thank you for your assistance.

# Answer
No each update overrites the oldest one (if present) so there are only ever a maximum of 2 versions in flash
> 2 votes

# Answer
This statement takes mainly two reasons into account:

1. The OTA update needs a complete sketch that executes the update. Overwriting a running sketch with an update crashes in almost all cases.
2. An OTA update can be disrupted or fail, as a wireless connection is notoriously unreliable. The device needs a working sketch after such events.

That's why the device stores the new sketch in a space separated from the old sketch.

But as soon as the "download" is complete and hopefully checked (by a hash or other means of checksum) to be error-free and valid, the old sketch is not needed any more. The system "switches" from the old sketch to the new sketch, in your case the bootloader overwrites the old sketch with the new sketch, see the last part of the documentation you link to.

The space after the now running new sketch is again free for the next OTA update.

However, there is a physical limit caused by flash memory wear. Commonly this is far away from the number of OTA updates a device will have in its lifetime.
> 0 votes

---
Tags: esp8266, ota
---


# Question
Title: Square wave generator generates a shorter pulse from time to time
I am using an arduino Micro to generate 8 square waves on 8 pins. The idea is as follows: on pin 13 is the main square wave. It represents a certain BPM (beats per minute). The other 7 pins should give multiplications or divisions of that BPM.

It uses timer1 to trigger an interrupt at BPM/192 (this number is choosen to enable easy multiplications). It counts those interrupts and changes the states of the outputs when needed.

The codes seems to run fine for most divisions and most multiplications. However in certain cases like /2, there seem to be shorter pulses from time to time that throw the whole timing off.

Adding a short delay at the end of the loop seems to make the system more stable but still the short pulses appear from time to time.

Does anyone have an idea what the problem might be.

```
int counter[8] = {0,0,0,0,0,0,0,0}; //storing number of interrupts since last pulse
int trip[8] = {191,383,767,1535,3071,6143,12287,24575}; //number of interrupts needed for div/mult
int outputPin[8] = {13,12,11,10,9,8,7,6};

void setup() {

  for (int x = 0; x < 8; x++){

    pinMode(outputPin[x], OUTPUT);
    digitalWrite(outputPin[x], HIGH);

  }

  cli();
  TCCR1A = 0;
  TCCR1B = 0;
  TCNT1 = 0;
  OCR1A =2602; // 16000000 / (x * 8) -1
  TCCR1B |= (1 << WGM12);
  TCCR1B |= (0 << CS12) | (1 << CS11) | (0 << CS10);//prescaler of 8
  TIMSK1 |= (1 << OCIE1A);
  sei();

}

void pulse(){

  for (int count = 0; count < 8; count++){

    counter[count]++;

  }

}

ISR(TIMER1_COMPA_vect){

  pulse();
}

void loop() {

  for (int y = 0; y < 8; y++){

    if(counter[y] > trip[y]){

      digitalWrite(outputPin[y],!digitalRead(outputPin[y]));
      counter[y] = 0;

    }

  }

  delayMicroseconds(100);

}

```

# Answer
> 4 votes
There are two issues here:

1. There is a data race on `counter[]`: it can be modified in interrupt context while it is being read (or even modified) by the main program.
2. Clearing `counter[y]` will make you loose ticks if for some reason (say some interrupt) you do it a little bit late. You should instead decrement it by `trip[channel]`.

Here is a safe way of managing the counters:

```
volatile int counter[8] = {...};  // don't forget `volatile`

// Return whether this channel has tripped, and update the count.
bool tripped(int channel) {
    noInterrupts();
    bool did_trip = counter[channel] >= trip[channel];
    if (did_trip) counter[channel] -= trip[channel];
    interrupts();
    return did_trip;
}

void loop() {
    for (int y = 0; y < 8; y++)
        if (tripped(y))
            digitalWrite(outputPin[y], !digitalRead(outputPin[y]));
}

```

Notice that the critical section (the section with interrupts disabled) lives within the `for` loop, rather than around it. It is better to have multiple small critical sections rather than one large one.

**Edit 1**: You don't need the delay. It makes the system “more stable” because it reduces the likelihood that, on any given TIMER1\_COMPA interrupt, the main program is accessing the counters (as it will spend most of its time delaying). Adding this delay is in a way treating the symptoms rather than the root cause of the data race.

**Edit 2**: Answering a comment. If you want the squares waves to stay in sync, their frequency ratios should be integers. In your program, this is almost, but not quite the case. For example, if you look at the ratio between the first two channels:

channel 0: 191 interrupts per signal toggle
channel 1: 383 interrupts per signal toggle
ratio: 383 ÷ 191 ≈ 2.0052

The easy fix is to add 1 to every element of the `trip` array (384 ÷ 192 is *exactly* 2).

---
Tags: timers, arduino-micro, wave
---


# Question
Title: Not registering complete rotary encoder input
I am working on a project using a Rotary Encoder and I am trying to recieve the output from the encoder. As it stands I am able to get a count for degrees of change and direction of rotation, however depending on the speed the encoder spins I get a varying rotational output. For example if I rotate it slowly I can get 100's of counts for 180 degrees of rotation, but if I do so fast, then I could get 10 or so counts.

I believe my Arduino is running too slow to count each of the signals from the encoder, I measured the wavelength of a signal to be ~25 us when spun quickly but using the following code I found that my arduino is running at a loop rate of 200 loops per second.

```
void loop() {
  if(counter <= 1000){
    counter++;
    Serial.println(counter);
  }
}

```

The code for the Rotary Encoder: Dt and Clk pin representing the 2 signal wires, both being pulled up

```
void loop(){

  //take clk pin state
  clkState = digitalRead(clkPin);

  //if clk state changed then wheel is rotating, react to rising edge to avoid double count
  if(clkState != preClkState && clkState == HIGH){
    Serial.write(digitalRead(dtPin));
    //check direction of spin based on dtpin
    if(digitalRead(dtPin)== HIGH){
      counter++;

      clockwiseDirection = true;
    }else{
      counter--;

      clockwiseDirection = false;
    }

    //output values
    Serial.write("Direction: ");
    if(clockwiseDirection){
      Serial.write("Clockwise | Counter: ");
    }else{
      Serial.write("Counter Clockwise | Counter: ");
    }

    Serial.print((int)counter);
    Serial.print("\n");

  }

  //update pre pos
  preClkState = clkState;

}

```

Thanks in advance.

# Answer
> 0 votes
Serial transmission takes time. Let's assume that you have set up the `Serial` with 9600 baud. This means 9600 bits per second. A single byte transmission commonly consists of a start bit, the data bits, and a single stop bit. This gives a total of 10 bits per byte. Therefore, your transfer rate is 9600 bits/s / 10 bits/byte = 960 bytes/s.

Estimating with a quick look at your source, each loop of your sketch sends about 40 characters, commonly encoded as a byte per character. And you claim that it achieves 200 loops per second, so the transfer rate is 40 bytes/loop * 200 loops/s = 8000 bytes/s.

Calculating back to bits/s results in a baudrate of roughly 80000 bits/s. So presumably you set up your `Serial` with 57600 or 115200 baud.

---

How to solve the issue?

Separate the acquisition of the encoder data from the transmission of the counter value. You can use interrupts, for example on the clock signal. However, this is not for the faint heart.

The `Serial` uses a transmission buffer of unspecified size. See the last paragraph of its documentation:

> As of Arduino IDE 1.0, serial transmission is asynchronous. If there is enough empty space in the transmit buffer, `Serial.write()` will return before any characters are transmitted over serial. If the transmit buffer is full then `Serial.write()` will block until there is enough space in the buffer. To avoid blocking calls to `Serial.write()`, you can first check the amount of free space in the transmit buffer using `availableForWrite()`.

You can check that the transmit buffer has room for your message. Send only, if there is enough room.

---
Tags: rotary-encoder, signal-processing
---


# Question
Title: We have Arduino IDE code that needs to stop after a set number of "revolutions"
We have Arduino IDE code that oscillates a plate on a lead screw powered by stepper motor to move back and forth.

We have the lead screw move 8 mm in one direction, then 8 mm in the opposite direction, for a total displacement of 16 mm. After this movement we have a counter that will then count as 1 "revolution" essentially. After reaching a specified count that program will stop.

Currently the program continues to run indefinitely. Any help/suggestions would be appreciated.

```
// Include the AccelStepper library:
#include <AccelStepper.h>

// Define stepper motor connections and motor interface type.
// Motor interface type must be set to 1 when using a driver:
#define dirPin 2
#define stepPin 3
#define motorInterfaceType 1

// Create a new instance of the AccelStepper class:
AccelStepper stepper = AccelStepper(motorInterfaceType, stepPin, dirPin);

void setup() {
  // Set the maximum speed and acceleration:
  stepper.setMaxSpeed(40000);
  stepper.setAcceleration(20000);
}

void loop() {
  static int counter = 0; // Initialize a counter variable and start at 0

  // Set the target position:
  stepper.moveTo(400); // is in steps. setting to default

  // Run to target position with set speed and acceleration/deceleration:
  stepper.runToPosition();

  delay(0);

  // Move back to zero:
  stepper.moveTo(0);
  stepper.runToPosition();

  delay(0); //microseconds
  counter++; //adds 1 to the counter

  if (counter >= 2) {
    return; //exit the loop
  }
}

```

# Answer
> 4 votes
```
if (counter >= 2) {
    return; //exit the loop
  }

```

The return statement will end the loop, but the loop function is called over and over repeatedly. So it will just start over again.

There are a few possibilities here. You can replace the `return` statement with `while(1);` which will lock up execution there until the board is reset.

If you don't need the loop function to repeat ever then you can simply move all of your code into the setup function as it will only run once. Then the loop function can just be empty.

And lastly, you could add a boolean variable and put the code you want to run only sometimes under an if statement that checks that variable. At the end of the process you set the variable to false to stop the other code from running. This would allow you to add code later to set it back at the press of a button or something in case you wanted the option to start the process again.

```
bool running = true;
void loop(){
  if(running){
      // do things
  }
  if (counter >= 2){
    running = false;
  }
}

```

---
Tags: arduino-ide
---


# Question
Title: Impossible to install the esp_camera library
I cannot install the esp\_camera library. When I try to add the .zip, I get "does not contain a valid library.

Everything about this ESP-32 Cam seems to rely on that library, and I can't find a way to install from https://github.com/espressif/esp32-camera or any other way.

Thanks.

# Answer
> 0 votes
It's not a "library" in the way that the Arduino system uses the term. That is, it's not designed to be placed under `<sketchbook>/libraries` directory way typical Arduino libraries are.

The good news is that you don't need to install it, because you already have it. It comes as part of the SDK files packaged into the ESP32 Arduino core as it is installed through the boards manager.

You'll find the header various places under the `<arduino15>/packages/esp32/hardware/esp32/<version-number>/tools/sdk/esp32<architecture>/include/esp32-camera/driver/include/esp_camera.h` where arduino15 refers to this, `version` refers to whatever version of the board package you have installed, and `architecture` is nothing, or `c2`, `s3`, or various other related esp32 suffixes.

The bulk of the code being in `<arduino15>/packages/esp32/hardware/esp32/<version>/tools/sdk/esp32<architecture>/lib/libesp32-camera.a`

---
Tags: esp32, library, ide, camera, esp32-cam
---


# Question
Title: Incorrect reading from DHT22 (on a Nano board)
I have rigged two different DHT22 sensors to an Arduino Nano board. Both temperature readings are more or less comparable but they produce very different humidity readings.

The sensors are:

The simple code is build on one of the basic examples as followed:

```
#include "DHT.h"
#define DHTPIN_2 2     // Digital pin connected to the DHT sensor_1
#define DHTPIN_3 3     // Digital pin connected to the DHT sensor_2
#define DHTTYPE DHT22   // DHT 22  (AM2302), AM2321
#define DHTTYPE_11 DHT11   // DHT 11  (AM2302), AM2321

DHT dht_1(DHTPIN_2, DHTTYPE);
DHT dht_2(DHTPIN_3, DHTTYPE);

void setup() {
  Serial.begin(9600);   //consider baud in serial monitor!
  Serial.println(F("DHT22 test!"));
  dht_1.begin();
  dht_2.begin();
}

void loop() {
  delay(5000);
  float h_1 = dht_1.readHumidity();
  float t_1 = dht_1.readTemperature();
  float h_2 = dht_2.readHumidity();
  float t_2 = dht_2.readTemperature();

  //Check if any reads failed and exit early (to try again).
  if (isnan(h_1) || isnan(t_1)) {
    Serial.println(F("Failed to read from DHT sensor_1!"));
    return;
  }

  // Check if any reads failed and exit early (to try again).
  if (isnan(h_2) || isnan(t_2)) {
    Serial.println(F("Failed to read from DHT sensor_2!"));
    return;
  }
  Serial.print(F("Humidities: "));
  Serial.print('\n');
  Serial.print(F("s_1: "));
  Serial.print(h_1);
  Serial.print(F(" s_2: "));
  Serial.print(h_2);
  Serial.print('\n');
  Serial.print(F("Temperatures: "));
  Serial.print('\n');
  Serial.print(F("s_1: "));
  Serial.print(t_1);
  Serial.print(F(" s_2: "));
  Serial.print(t_2);
  Serial.print('\n');
}

```

The resulting output on the Serial Monitor is:

```
Temperatures:
s_1: 25.30 s_2: 23.40
Humidities:
s_1: 6.20 s_2: 66.40
Temperatures:
s_1: 25.20 s_2: 23.40
Humidities:
s_1: 6.00 s_2: 66.10
Temperatures:
s_1: 25.10 s_2: 23.40
.
.
.

```

The humidity reading from sensor\_1 seems defective, just having the 10th of the value of sensor\_2. Is there a fix for that? Is it possible to re calibrate sensor\_1 or is it broken?

Thank you!

## Edit: swapping the sensors (suggested by jsotola)

The output results in:

```
Temperatures:
s_1: 22.60 s_2: 24.70
Humidities:
s_1: 67.80 s_2: 7.30

```

Its the sensor it seems.

# Answer
The difference in humidity readings may be traced to any number of reasons including faulty parts, incorrect programming or low voltages (*please post at what voltage you are running the sensors at*) to name a few.

Let us speculate that one of the sensors is reporting relative humidity and the other absolute. Absolute humidity does not consider temperature where as relative does. From this web site we get the following conversion equation:

This equation converts relative humidity to absolute. Finding the saturation vapor pressure measured in pascal is not trivial. So we will use this web site to calculate this value.

Let us use the sample:

* Temperature 1: 22.60 C
* Temperature 2: 24.70 C
* (assumed) Relative Humidity: 67.80 %
* (assumed) Absolute Humidity: 7.30

So, average temperature is 23.65 C. Using this temperature and the above web page, the vapor pressure is 2923 PA.

AH = (67.80 x 2923) / (462.5 x (273.15 + 23.65) x 100) AH = 0.014437 Kg/(meter cubed)

As absolute humidity is normally written as grams per cubic meter:

AH g/(meter cubed) = 0.014437 * 1000 = 14.43 g/(meter cubed)

14.43 is not 7.30. Consider your options. Check your circuit, voltages and software (*does varying the amount of time between samples result in different values*). Also consider running more tests in better conditions (*placing both sensors inside the same sealed container over a long period of time to mitigate exposure to different conditions*).

---

Added later...

Evidently problems with the DHT11 humidity sensor is a known problem:
> 0 votes

---
Tags: arduino-nano, sensors, dht22
---


# Question
Title: How to use an external 32kHz crystal for ESP32 S3 with Arduino IDE?
I want to use an external 32kHz crystal for RTC with ESP32 S3, but I didn't see any example or tutorial for Arduino IDE, Even when I asked ChatGPT, it gave me some example but the code gave library errors. I don't understand why there is no RTC example in the Arduino IDE.

I have designed a PCB with this SCH for RTC. But I don't know how I can activate an external 32 KHz crystal with Arduino IDE. Please tell me how.

# Answer
From the ESP32-S3 documentation in section 2.4.2:

> ESP32-S3 supports an external 32.768 kHz crystal or an external signal (e.g., an oscillator) to act as the RTC sleep clock. The external RTC clock source is used to improve the timing accuracy and thus reduce the average power consumption, but will not affect the functionality.

This document also contains a schematic:

... it is assumed that the schematic in the question is that of the ESP32-S3-WROOM module accounting for the differences between the two schematics.

The wording in the document infers there is only a counter to track / control the processor's sleep state.

This is further enforced by this question / answer found in electronics.stackexchange.com:

> The ESP32 RTC module only has a timer that runs even in hibernation mode as well as some RAM that it can retain in deep sleep mode...
>
> ... There's no "wall clock" or "calendar" in the ESP32 RTC module.

If still interested in implementing a "wall clock" using the ESP32-S3, the same stackexchange question / answer offers the following:

> The ESP32 does not have a real time clock - you cannot tell it to wake up at a particular time. It does have a timer that can wake it from deep sleep after a given time.
>
> You can use the deep sleep wake up timer like this:
>
> > esp\_sleep\_enable\_timer\_wakeup((uint64\_t)sleepTimeSeconds * 1000000); esp\_deep\_sleep\_start();
>
> You set the sleep timer with esp\_sleep\_enable\_timer\_wakeup. The time period is in microseconds. With the timer set, the ESP32 will automatically wake up after the set time period.

Code will then have to be written to pull the last time from the ESP32-S3's nonvolatile memory, increment it by 1 second, store it back into nonvolatile memory and put the processor back to sleep for 1 second.
> 0 votes

# Answer
This is not a simple task: you have to recompile the Arduino core with the external RTC enabled.

Basically, you have to properly set the CONFIG\_RTC\_CLK\_SRC option in kconfig file. You should start to read from here, and practising with ESP-IDF configurator.

I successfully completed this operation for the ESP32-S2 few years ago, but the procedure is very similar. Good luck.
> 0 votes

---
Tags: esp32, rtc, oscillator-clock, esp32-s3
---


# Question
Title: Having an issue conveying array values properly
this is my first time asking a question here, sorry in advance if this is a poor way to ask this question.

I'm at an intermediary point in coding a program, and at this stage I'd like my byte information which I'm inputting into my serial monitor to take the places of my array elements. I'm able to do so, but when I try to use a 5 digit input, I only get a 4 digit input in return.

It seems like my Serial.available() == 4 loop is preventing my Serial.available() == 5 loop from operating. Would there be a simple modification I could make to allow a 5 digit result from a 5 digit input, and a 4 digit result from a 4 digit input? I've tried many things and Chat GPT seems to think the current code should work, but it doesn't. Here's the code:

```
int fiveArray[5];
int fourArray[4];
const char* colors[] = {"black ", "brown ", "red ", "blue ", "yellow ", "orange ", "white ", "gold ", "green ", "purple "};

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

  Serial.print("Input a number value: ");
  Serial.println();
}

void loop() {
  if (Serial.available() ==5 ) {
    char tempArrayFive[6];
    Serial.readBytes(tempArrayFive, 6);
    tempArrayFive[5] = '\0';

    for (int i = 0; i < 5; i++) {
      fiveArray[i] = tempArrayFive[i] - '0';
    }

    Serial.print("Color Value: ");
    for (int i = 0; i < 5; i++) {
      Serial.print(colors[fiveArray[i]]);
    }
    Serial.println();

  }
  if (Serial.available() == 4 ) {
    char tempArrayfour[5];
    Serial.readBytes(tempArrayfour, 5);
    tempArrayfour[4] = '\0';

    for (int i = 0; i < 4; i++) {
      fourArray[i] = tempArrayfour[i] - '0';
    }

    Serial.print("Color Value: ");
    for (int i = 0; i < 4; i++) {
      Serial.print(colors[fourArray[i]]);
    }
    Serial.println();
  }
}

```

# Answer
Yes, if you send 5 bytes to the Arduino then they will arrive one at a time. When the 4th byte arrives then the `if (Serial.available() == 4 )` statement is true and it runs that code. That code reads from the buffer which means that the part that checks for 5 bytes will never be able to run. There will always be 4 before there is 5.

A better idea would be to send your bytes with a start and end marker. The program on the Arduino will read bytes and collect them in an array until it sees the end marker. Then you can count how many bytes you have received if you want to take different actions depending on that number.

Here's a nice thread on handling Serial data: https://forum.arduino.cc/t/serial-input-basics-updated/382007
> 2 votes

# Answer
I have a post here which discusses handling incoming serial data. Also here on Stack Exchange.

For handling serial input like you are trying to do I suggest using an "end of line marker" like newline (which the Terminal Monitor in the IDE will do for you automatically).

Then it's just a case of seeing whatever-it-was you got before the newline. Example code:

```
/*
Example of processing incoming serial data without blocking.

Author:   Nick Gammon
Date:     13 November 2011.
Modified: 31 August 2013.

Released for public use.
*/

// how much serial data we expect before a newline
const unsigned int MAX_INPUT = 50;

void setup ()
  {
  Serial.begin (115200);
  } // end of setup

// here to process incoming serial data after a terminator received
void process_data (const char * data)
  {
  // for now just display it
  // (but you could compare it to some value, convert to an integer, etc.)
  Serial.println (data);
  }  // end of process_data

void processIncomingByte (const byte inByte)
  {
  static char input_line [MAX_INPUT];
  static unsigned int input_pos = 0;

  switch (inByte)
    {

    case '\n':   // end of text
      input_line [input_pos] = 0;  // terminating null byte

      // terminator reached! process input_line here ...
      process_data (input_line);

      // reset buffer for next time
      input_pos = 0;
      break;

    case '\r':   // discard carriage return
      break;

    default:
      // keep adding if not full ... allow for terminating null byte
      if (input_pos < (MAX_INPUT - 1))
        input_line [input_pos++] = inByte;
      break;

    }  // end of switch

  } // end of processIncomingByte

void loop()
  {
  // if serial data available, process it
  while (Serial.available () > 0)
    processIncomingByte (Serial.read ());

  // do other stuff here like testing digital input (button presses) ...

  }  // end of loop

```

In your case, you would put code in the `process_data` function to turn the input text into a number and then do something with that number.

I'm surprised ChatGPT didn't point out my code \<grin\> but maybe you asked it a too-specific question.

---

I'd just point out that without a line-terminator character (like newline) then your code will be permanently out of step with incoming data if it starts in the wrong place. For example:

```
123456789

```

Depending on the speed at which that arrives, are we seeing `123` followed by `456`? Or `12` followed by `34`? Or `1234` followed by `5678`? The end-of-line delimiter is really essential to avoid those ambiguities.

Or if the code happens to start running after you have sent the `1` but before the `2` it would think you sent `234` rather than `123` and then every other number would be out by one position.
> 2 votes

---
Tags: arduino-ide
---


title: WS2811 lights only turn red

text:
# Question
Title: WS2811 lights only turn red
I've connected a strand of WS2811 to a 5V power supply and an Arduino Uno and no matter what I do the lights are always red. I'm using the fast led library and for some reason, the WS2811 lights are only red.

# Answer
I had this same issue, turns out I had 12v WS2811's. Changing power supply fixed it for me!
> 1 votes

---
Tags: arduino-uno
---


# Question
Title: Has anyone modified a 16x2 LCD shield to work with Arduino DUE?
Since the DUE works on 3.3 volts has anyone successfully modified a 5V 16x2 LCD shield to work with Arduino DUE? I'm thinking 3.3V will be seen as a logic "1" by the 5V LCD shield and there are no 5V outputs that feed back to the 3.3V due if the R/~W line on the LCD is simply grounded.

Would love to hear anyone's opinion on this.

Thanks, Charlie

# Answer
> 3 votes
I understand this is an 8yo thread, however my answer might still help someone. I connected an unmodified no-brand LCD Shield to an Arduino DUE and it works perfectly - the only thing I had to change was the analog thresholds to identify the buttons. Just upload the sketch and read out the real values on the display then enter the averages between adjacent buttons in read\_LCD\_buttons function.

```
//Sample using LiquidCrystal library
#include <LiquidCrystal.h>

/*******************************************************

This program will test the LCD panel and the buttons
Mark Bramwell, July 2010

********************************************************/

// select the pins used on the LCD panel
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);

// define some values used by the panel and buttons
int lcd_key = 0;
int adc_key_in = 0;
#define btnRIGHT 0
#define btnUP 1
#define btnDOWN 2
#define btnLEFT 3
#define btnSELECT 4
#define btnNONE 5

// read the buttons
int read_LCD_buttons()
{
adc_key_in = analogRead(0); // read the value from the sensor

if (adc_key_in < 90) return btnRIGHT;
if (adc_key_in < 297) return btnUP;
if (adc_key_in < 533) return btnDOWN;
if (adc_key_in < 814) return btnLEFT;
if (adc_key_in < 1000) return btnSELECT;

return btnNONE; // when all others fail, return this...
}

int button_count=1;

// Pin 13 has an LED connected on most Arduino boards.
// give it a name:
int led = 13;

int i;

void setup()
{
lcd.begin(16, 2); // start the library
lcd.setCursor(0,0);
lcd.print("Push the buttons"); // print a simple message

// initialize the digital pin as an output.
pinMode(led, OUTPUT);

}

void loop()
{
  delay(100);
  lcd.setCursor(9,1); // move cursor to second line "1" and 9 spaces over
  lcd.print("        ");
  lcd.setCursor(9,1); // move cursor to second line "1" and 9 spaces over
  lcd.print(analogRead(0)); // display A0 analog input to calibrate values

  lcd.setCursor(0,1); // move to the begining of the second line
  lcd_key = read_LCD_buttons(); // read the buttons

  switch (lcd_key) // depending on which button was pushed, we perform an action
  {
    case btnRIGHT:
        lcd.print("RIGHT ");
        button_count = 2;
        break;

    case btnLEFT:
        lcd.print("LEFT ");
        button_count = 3;
        break;

    case btnUP:
        lcd.print("UP ");
        button_count = 4;
        break;

    case btnDOWN:
        lcd.print("DOWN ");
        button_count = 5;
        break;

    case btnSELECT:
        lcd.print("SELECT");
        button_count = 6;
        break;

    case btnNONE:
        lcd.print("NONE ");
        button_count = 1;
        break;
  }

}

```

---
Tags: arduino-due
---


title: DS2436 Arduino UNO programming

text:
# Question
Title: DS2436 Arduino UNO programming
I am struggling with programming my DS2436 chip using an Arduino UNO. To be honest, I am trying to modify DS18B20 code (the one that is anywhere on the internet) to work with DS2436. It's just harder for me to understand how whole memory and adressing thing work, since DS2436 has those pages of memory blocks, unlike DS18B20, which has only 1. Also the language factor is stopping me, I am not a native speaker.

I keep getting wrong data/temperature/CRC. Can someone assist me, please? I need this thing to show me voltage/temperature and cycles.

```
#include <OneWire.h>
OneWire  ds(10);

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

void loop(void) {
  byte i;
  byte addr[8];
  byte data[32];
  byte type_s;
  byte present = 0;
  float celsius, fahrenheit;

  if (!ds.search(addr)) {
    ds.reset_search();
    delay(1000);
    return;
  }

  Serial.print("ROM =");
  for( i = 0; i < 8; i++) {
    Serial.write(' ');
    Serial.print(addr[i], HEX);
  }
  Serial.print("\n");
  if (OneWire::crc8(addr, 7) != addr[7]) {
    Serial.println("CRC is not valid!");
    return;
    Serial.print("\n");
  }
  if (addr[0] != 0x1B) {
    Serial.print("Device is not a DS2436 family device!");
    Serial.print("\n");
  }
  {
    Serial.print("CRC= ");
    Serial.print(OneWire::crc8(data, 8), HEX);
  }
  Serial.print("\n");
  ds.reset();
  ds.select(addr);
  ds.write(0xD2, 1);
  delay(1000);
  present = ds.reset();
  ds.select(addr);
  ds.write(0xB2);
  Serial.print("  Data = ");
  for (int i = 0; i < 13; i++) {
    data[i] = ds.read();
    Serial.print(data[i], HEX);
    Serial.print(" ");
  }
  Serial.print(" CRC=");
  Serial.print(OneWire::crc8(data, 8), HEX);
  Serial.println();
  unsigned int raw = (data[1] << 8) | data[0];
  int sig = raw & 0x8000;
  if (sig) {
    raw = (raw ^ 0xffff) + 1;
  }
  celsius = (float)raw * 0.03125;
  Serial.print("Temperature = ");
  Serial.print(celsius);
  Serial.print(" Celsius ");
  Serial.print("\n");
  Serial.print("_______________________________________________");
  Serial.print("\n");
}

```

# Answer
Yes necro, but having my own example of a DS2436 to try this out on, and having to write code for it with little else to go on, seems like the IC doesn't really know what to send you when reading the bus after sending the read register command.

As per the datasheet, 0xFF is data the IC sends when the bus master reaches the end of a page or an address that's reserved. Adding in `ds.write(0x60);` before performing the read cycles fixes most of this.

Haven't gotten into much past that, but it seems like there's also something not quite right going on with your arithmetic to turn your binary into temperature. Even with my fix getting something serviceable as output, I get 1024.00 Celsius.
> 0 votes

---
Tags: arduino-uno
---


# Question
Title: Where to find interrupt flag for 3rd-party Arduino board cores?
This question might be a bit broad, but I'm running into an apparently classic problem with Arduino interrupts, where the rising or falling edge flag is triggered prior to a rising or falling edge technically occurring before a pin is pulled high/low and the microcontroller "remembering" that event occurred, running the interrupt the moment it gets attached to a pin. In this case, I'm working with Sparkfun's Artemis module (using the Apollo3 microcontroller). The code in question can be seen below:

```
#define SLEEP_INTERRUPT   4

void setup
{
    pinMode(SLEEP_INTERRUPT, INPUT);
#ifdef DEBUG
  Serial.print("About to attach interrupt");
#endif
  attachInterrupt(digitalPinToInterrupt(SLEEP_INTERRUPT), sleepModeSwitch, FALLING);
#ifdef DEBUG
  Serial.print("Interrupt attached");
#endif
}

void sleepModeSwitch()
{
#ifdef DEBUG
  Serial.print("Interrupt triggered! button status: "); Serial.println(digitalRead(SLEEP_INTERRUPT));
#endif
  if(sleep_mode_status == false)
  {
    goToSleep();
  }
  else
  {
    wakeUp();
  }
}

void goToSleep()
{
  sleep_mode_status = true;
#ifdef DEBUG
  Serial.println("Going to sleep");
  delay(50);  //Wait for serial to finish
  Serial.end(); //Power down UART(s)
#endif
  // turn off the led.
  digitalWrite(LED_BUILTIN, LOW);

  // Stop the BLE advertising.
  BLE.stopAdvertise() ;

  powerControlADC(false);

  for(int x = 0; x < 50; x++)
  {
    if(x != 4)
    {
      am_hal_gpio_pinconfig(x, g_AM_HAL_GPIO_DISABLE);
    }
  }
  //Power down Flash, SRAM, cache
  am_hal_pwrctrl_memory_deepsleep_powerdown(AM_HAL_PWRCTRL_MEM_CACHE); //Turn off CACHE
  am_hal_pwrctrl_memory_deepsleep_powerdown(AM_HAL_PWRCTRL_MEM_FLASH_512K); //Turn off everything but lower 512k
  am_hal_pwrctrl_memory_deepsleep_powerdown(AM_HAL_PWRCTRL_MEM_SRAM_64K_DTCM); //Turn off everything but lower 64k
  //am_hal_pwrctrl_memory_deepsleep_powerdown(AM_HAL_PWRCTRL_MEM_ALL); //Turn off all memory (doesn't recover)

  // // Enable interrupts to the core.
  am_hal_interrupt_master_enable();

  // //Enable the timer interrupt in the NVIC.
  // NVIC_EnableIRQ(STIMER_CMPR6_IRQn);

  //Go to Deep Sleep.
  am_hal_sysctrl_sleep(AM_HAL_SYSCTRL_SLEEP_DEEP);
}

void wakeUp()
{
  am_hal_pwrctrl_memory_deepsleep_powerdown(AM_HAL_PWRCTRL_MEM_MAX);

  // Re-enable UART0 pins
  am_hal_gpio_pinconfig(48, g_AM_BSP_GPIO_COM_UART_TX);
  am_hal_gpio_pinconfig(49, g_AM_BSP_GPIO_COM_UART_RX);

  am_hal_pwrctrl_periph_enable(AM_HAL_PWRCTRL_PERIPH_UART0);

  initializeADC();

#ifdef DEBUG
  Serial.begin(115200);
  Serial.println("Waking up! Hello world!");
#endif
  deepSleepTimer = millis() ;
  sleep_mode_status = false;
}

```

Based on my research, the solution for this is to just clear the interrupt flag manually before attaching the interrupt to your desired pin. Unfortunately, so far the methods for doing so that I've found only work for AVR boards, and I'm not certain where to look to find more information about how to access an interrupt flag in a sketch for a 3rd-party Arduino core. Does anyone have a suggestion or two on where to start?

# Answer
> the rising or falling edge flag is triggered prior to a rising or falling edge technically occurring before a pin is pulled high/low and the microcontroller "remembering" that event occurred, running the interrupt the moment it gets attached to a pin

There is no "technically" about it. This is what is supposed to happen. Once you configure the interrupt to happen (as you do in `setup`) then the processor will remember that the condition has happened, whether or not interrupts are enabled.

If you want the interrupt only to be processed *after* a certain point, then yes, you should clear the "interrupt has happened" flag in the MCU, before enabling interrupts.

Your question is pretty non-specific about exactly which processors you are talking about, but I would certainly clear any appropriate flags before attaching the interrupt.

> I'm not certain where to look to find more information about how to access an interrupt flag in a sketch for a 3rd-party Arduino core

The datasheet of the device on this particular core?

---

Judging by the datasheet for the Apollo3 Blue SoC:

> 6.3.2.15 INTCLR Register
>
> IO Master Interrupts: Clear
>
> OFFSET: 0x00000228
>
> INSTANCE 0 ADDRESS: 0x5000C228
>
> Write a 1 to a bit in this register to clear the interrupt status associated with that bit.

However I don't have one of those processors around to test it.
> 1 votes

---
Tags: interrupt, core-libraries
---


title: Large arrays crash the arduino

text:
# Question
Title: Large arrays crash the arduino
I have three large `PROGMEM` arrays, in order to store musical notes for a song. One array is the notes, one is the note durations, and one is the pause after the note.

The first array is an `int` one and the other two are `floats.` The program works, but after a specific number of elements, the arduino crashes. Meaning, I upload the program without problems, but the device does nothing.

When I have 227 elements (in all three arrays) obviously, the program works. If I increase the number of elements to 228, nothing happens when I upload...

When the IDE says `avrdude: 10606 bytes of flash verified` then everything works. When the size gets increased to `10616`, everything crashes. Is this normal behaviour?

**EDIT:** The code is trivial, the only important part of the code is this:

```
int number_of_stored_values_in_MelodyArray = sizeof(Crash_Melody) / sizeof(int);
int Melody_Array[number_of_stored_values_in_MelodyArray];
memcpy_P(Melody_Array, Crash_Melody, sizeof Melody_Array);

```

I am using `memcpy_P()` in order to copy the arrays from `PROGMEM` to RAM. I do this for the int and the two float arrays. With 221 elements in each array, I guess I am out of RAM.

The reason I have an array for the pause as well, is because I am using an online midi to tone() converter and that is the format that it uses. So I have to stick to that format.

I think if I did the assignment incrementally - like for example copy only 20 elements from the array, play the song, then repeat until the end, I would have no problem.

Is there a way for `memcpy_P()` to specify not the whole array to copy, but index them? Does it take a starting index value?

**EDIT 2:** This is a snippet of code after trying Edgar Bonnet's approach.

```
int number_of_stored_values_in_MelodyArray = sizeof(My_Melody) / sizeof(int);
for (int i = 0; i < number_of_stored_values_in_MelodyArray; i++)
{
  int note = pgm_read_word(&My_Melody[i]);
  float duration = pgm_read_word(&My_noteDurations[i]);
  float pause_duration = pgm_read_word(&My_Delay[i]);
  playMelodyExtended2(note, duration, pause_duration, number_of_stored_values_in_MelodyArray, 10, 400);
}

int playMelodyExtended2(int melody, float noteDuration, float pauseDuration, int number_of_notes, int music_pin, int delay_var)
{
  for (int thisNote = 0; thisNote < number_of_notes; thisNote++)
  {
    tone( music_pin, melody, noteDuration );
    delay( pauseDuration );
    noTone(music_pin);
  }

  delay(delay_var);
}

```

**EDIT 3:** This is the newest iteration of the code:

```
 int number_of_stored_values_in_MelodyArray = sizeof(My_Melody) / sizeof(int);
 for (int i = 0; i < number_of_stored_values_in_MelodyArray; i++)
 {
    int note = pgm_read_byte_near(&My_Melody[i]);
    note << 8;
    note += pgm_read_byte_near(&My_Melody[i+1]);
    float duration = pgm_read_float_near(&My_noteDurations[i]);
    uint16_t pause_duration = pgm_read_byte_near(&My_Delay[i]);
    pause_duration << 8;
    pause_duration += pgm_read_byte_near(&My_Delay[i+1]);
    playMelodyExtended2(note, duration, pause_duration, number_of_stored_values_in_MelodyArray, 10, 400);
  }

int playMelodyExtended2(int melody, float noteDuration, uint16_t pauseDuration, int number_of_notes, int music_pin, int delay_var)
{
  for (int thisNote = 0; thisNote < number_of_notes; thisNote++)
  {
    tone( music_pin, melody, noteDuration );
    delay( pauseDuration );
    // stop the tone playing:
    noTone(music_pin);
  }

  delay(delay_var);
}

```

# Answer
In the edited version of your question, you wrote:

> I am using `memcpy_P()` in order to copy the arrays from `PROGMEM` to RAM.

The whole purpose of `PROGMEM` is to **avoid having to store the data in RAM**. If you copy the arrays to RAM, you are defeating `PROGMEM`. Your Arduino has much more Flash than RAM, and it will crash if you eat up all the RAM. This is why the `PROGMEM` optimization is valuable whenever you have large arrays of constant data.

The proper way to use those arrays is to copy to RAM one element at a time: get the data for the next note you have to play, then play it, then move to the next one. E.g.:

```
for (int i = 0; i < melody_length; i++) {
    int note = pgm_read_word(&Crash_Melody[i]);
    // etc...
}

```

Copying small chunks to RAM, as you suggest in your question, would make the code more complex and add absolutely no value.

---

**Edit**: In the second edit of your question, you have this:

```
float duration = pgm_read_word(&My_noteDurations[i]);

```

What this does is:

* read the first two bytes of `My_noteDurations[i]` (which is a four-byte quantity, thus you are truncating it)
* interpret that as an integer (which it is not)
* convert that to `float`

The result will have little to do with the original number. The correct way to read a float from `PROGMEM` is to use `pgm_read_float()`.

That being said, I see now that you use this number as a parameter for `delay()`. Given that this function takes an integer, there is no point in storing the delay as a float. This will only add a (somewhat costly) float-to-integer conversion to your program, with no added benefit. Also, since the delays are likely to be less than 65 seconds, a 16-bit unsigned integer should be enough.

Further down, you have this:

```
for (int thisNote = 0; thisNote < number_of_notes; thisNote++)
{
  tone(music_pin, melody, noteDuration);
  delay(pauseDuration);
  noTone(music_pin);
}

```

I fail to see the purpose of this loop. You are repeating **each note** a number of times that is equal to the total number of notes in the song. Why?

---

**Answer to edit 3**: there are a few issues I can see in this version of the code.

1. Consistency of the data types: in the previous version, it looked like the pause durations were floats. Now they are integers. You have to make sure you use the `pgm_read_*()` function suitable for the actual data type of the array.
2. Reading by bytes: there is no point in reading a 16-bit integer one byte at a time: use `pgm_read_word()` to read it all at once. Reading byte by byte only makes the code more complex and increases the chances of bugs. In fact, your way of reconstructing the numbers is buggy.
3. The loop in `playMelodyExtended2()` makes no sense to me. Please, try removing it.

Here is what I suggest at this point:

```
for (int i = 0; i < number_of_stored_values_in_MelodyArray; i++)
{
    int note = pgm_read_word(&My_Melody[i]);
    float duration = pgm_read_float(&My_noteDurations[i]);
    uint16_t pause_duration = pgm_read_word(&My_Delay[i]);
    tone(10, note, duration);
    delay(pause_duration);
}

```

This snippet makes some assumptions about the rest of your code, and specifically about the way your arrays are defined. If these assumptions are incorrect, this will not work. Thus, I second @orithena's comment and urge you to post a full, testable version of you sketch (three notes would be enough).
> 4 votes

---
Tags: array, debugging, progmem, sketch-size
---


title: Serial data plotting programs

text:
# Question
Title: Serial data plotting programs
I need to plot serial data from Arduino.

I require support for:

1. Various data formats (e.g. signed, unsigned, 8 bits, 16 bits);
2. Plots several data on the same axes;
3. Exports / Imports file data.

As plotting serial data from Arduino is a common need, my question is: What programs/utilities are available for plotting serial data from Arduino that meet the needs above?

What are the advantages / disadvantages of the method you have suggested?

# Answer
There are some good applications for visualizing the serial data, including:

* MegunoLink ($39.95; Lite free) - plotting, logging, programming, reporting and more.
* Electric UI ($80; free for students) - cross platform, fully featured code based GUI framework for hardware.
* MakerPlot ($59) - digital & analog plotting, monitoring, custom interfaces and more.
* ArduinoPlot (free) - simple plotting.
* arduino-plotter (free) - easy, light-weight plotting with support for all primitive types
* Bridge Control Panel (free) - logging, plotting, and more.
* RealtimePlotter (free) - 6 channels data plotting.
* SimPlot (free) - 4 channel plotting.
* Arduino Serial Plotter (free) - built in Arduino Editor under *Tools \> Serial Plotter*.

(This is a community wiki, you can expand the list.)
> 25 votes

# Answer
GnuPlot

Advantages: It's very flexible, scriptable, and freely available.

Disadvantages: A bit complex to learn (but I figured out how to get started in a few minutes, and quite functional in an hour or two), runs in a terminal window (if you consider that a disadvantage).

Something I found very useful was to script it to reload my terminal program's logfile periodically so i got a dynamic graph as my experiment progressed.

Edit: Here is the GnuPlot script that plots it:

```
#!/usr/local/bin/gnuplot -rv
# Note reverse video here ^^^   til I find a way to put it in the script

# gpFanCtl - Plots DiffThermo fan controller data (aloft, alow, Tdiff, fan-state).
# $Id: gpFanCtl,v 1.8 2014-04-28 09:40:51-04 jrobert Exp jrobert $

set terminal x11 1 noraise
set xtics 3600
set mxtics 4
set xdata time

set ytics 1 nomirror
set mytics 2

set y2range [0:3]
set y2tics 1
set my2tics 4

set grid
set ylabel 'Temperature, degC'
set y2label 'Tdiff, degC' textcolor rgb '#00CD63'

cd '/Users/jrobert/Desktop'
plot "Logfile.txt" using ($0*4):1 title "Aloft" with lines lc rgb "red",\
     "Logfile.txt" using ($0*4):2 title "Alow" with lines lc rgb "#3982FF",\
     "Logfile.txt" using ($0*4):3 title "Tdiff" with lines lc rgb "#00CD63" axis x1y2,\
     "Logfile.txt" using ($0*4):4 title "Fan" with lines lc rgb "orange" axis x1y2;
pause 4
refresh
reread

```
> 10 votes

# Answer
I use Matplotlib for any plotting I need to do.

It's not arduino specific in any way, but it is a very excellent *Python* plotting toolkit.

I've built a number of applications that plot data from a variety of microcontrollers in real-time to a graph, but that was really more of a two-step process: 1. Get data from device into computer, 2. plot realtime data.

Really, I think you should break your question into two parts:

* How do you get data from an Arduino/Any serial device into a computer easily.
* What is a good plotting library that is easy to use.
> 8 votes

# Answer
SerialPlot (free). It does everything you require and much more.

Other features:

* Zoom in on data
* Click on datapoints to see values
* Send commands back to Arduino
* Adjust total number of points plotted
* Ability to show each channel in its own autoscaled plot
* Interprets binary, ASCII and custom packets
* Demo mode lets you play with features
> 8 votes

# Answer
Responding to my own question here.. I use Bridge Control Panel as mentioned.

Advantages: Lots of Features.

Disadvantages: Tricky to setup and very poor syntax/error reporting.

To use: You need to write the Arduino Data over the Serial Port one byte at a time. For an int data type that would look as follows:

```
// RX8 [h=43] @1Key1 @0Key1
Serial.print("C");
Serial.write(data>>8);
Serial.write(data&0xff);

```

In Bridge the command to Read Data is:

```
RX8 [h=43] @1Key1 @0Key1

```

RX8 is the read command \[h=43\] means the next valid byte is "C" in ASCII then the High Byte of Key1 then the Low Byte of Key1

It looks like this in Bridge:
> 6 votes

# Answer
You can try **serialchart**. It's pretty strait forward program. It does exactly what you asked. The only disadvantage is that it requires data in CSV format (does not meet first point).

Screenshot from project page:
> 6 votes

# Answer
Nobody had mentioned Processing which is super versatile. You can do a lot more than just plotting but if that's all you want to do you can use the gwoptics library; hook up Arduino and Processing as directed here.
> 6 votes

# Answer
You might be interested in `Telemetry` See on Github . It is a communication protocol, highly simple to use, with a clean interface, that enables bidirectionnal communication with Arduino/Mbed devices.

If you don't want to read this long post, see *A walkthrough of all the awesome features in it*

The power of this library comes from the desktop command line interface (that requires **no** programming skills in python).

It is able to open high-performance plots (much higher that what can be done with matplotlib) **just by typing a command**.

The protocol supports **complexes data structures**. For now **arrays** and sparse arrays can be send from the embedded board.

The plots opened from the command line interface understand the type of data, and for arrays, rather than plotting each sample versus time, sample will be plotted against its own index.

In a near future, it is planned to add **support for spatial coordinates** (xyz data), that will allow you to plot immediately spatial data. Once, again the plots will figure everything out, plot your data in 2D or 3D space and you can focus on developping your app.

I believe those features are simply **unique** for such a project.

## Pytelemetry CLI

Once installed with `pip`, the command line can be started with

```
pytlm

```

Then you can `connect`, `ls`(list) received topics, `print` data received on a topic, `pub`(publish) on a topic, or open a `plot` on a topic to display received data in real-time

# Get started

Wiki

*PS : I am the author.*

I developed it because I could not find a solution that would allow me to:

* write quickly PC scripts to control an Arduino
* debug quickly
* plot complex data (not just a time varying value)

all of the above without using proprietary solutions or bloated GUIs.

Using this library, the time to setup a communication between Arduino and PC went from usually half a day to 5 minutes.
> 6 votes

# Answer
You can use MATLAB Student Edition, this can save your time for further analysis, too. You can just open the COM port in MATLAB and plot the received signal and/or save the signal in the workspace or whatever. MATLAB makes everything easy!
> 2 votes

# Answer
I made an equivalent tool in python that print real time data from ADXL345 accelerometer. https://github.com/mba7/SerialPort-RealTime-Data-Plotter

may be it will be helpful for someone

Just choose the serial com and speed and sent a serial data on the following format:

* 3 inputs, every input is a 2 bytes (Two's complement )
* 6 bytes seperated by a space
* the packet is a string terminated by '\n'

Could be easily adapted to change this format
> 2 votes

# Answer
While I haven't used it myself, "rqt\_plot" running on the PC seems to be a popular way to plot data on a PC that comes over a serial port from an Arduino running a sketch that includes the rosserial\_arduino library or the ros\_arduino\_bridge library.
> 2 votes

# Answer
CSV format is most versatile for any data (signed/unsigned, various size and precision).

Cross-platform (written in Java/Scala) tool Scsvlog can receive/parse CSV strings from serial port / socket, show values and draw charts (up to 8).
> 2 votes

# Answer
You can try out the software I developed for that propose. It's aimed to be easy to use. See SerialGraphicator \- Open Source Free Serial Port Client capable of graph values that are received in JSON format.
> 2 votes

# Answer
I know this is a very old question, but I recently created a mac application that solves this problem very well. You can find more information about it on www.bloonapp.com. There are some demo videos on the website that you can check out.
> 1 votes

# Answer
I know you were probably after more advanced GUI output, but I managed to replicate a task that one would normally do with an oscilloscope:

using the serial plotter in the Arduino IDE and an ADC module you can get for $3 on eBay. I admit it's a bit crude, but it might be worth playing with the tool for a while, before you invest in Python/Matlab/ect level solutions. It was exceedingly easy to use. It would not take much to add SD card recording to the process.

See: https://edwardmallon.wordpress.com/2016/08/15/using-the-arduino-uno-as-a-basic-data-acquisition-system/
> 1 votes

# Answer
Serial Plotter is a simple program that I've made with Electron that receives data in the following format: `data1,data2,timestamp;` and converts it into a realtime chart.
> 1 votes

# Answer
Almost useful. It needs:

1. logging serial data to a file OR
2. graphing from a file and updating every xxx milliseconds.

Live Graph is a better option and I use it in conjunction with Tera Term which gets the data via the USB/serial link (and saves it to a log file which then Live Graph polls).

Live Graph is slightly buggy when caching data and I haven't found a way to set a moving window to display results. Also, showing multiple graphs requires manual scaling, but in spite of all this, it's still very useful. It's written in java so you'll need the JRE. I prefer this over having to install python like some of the other graphing programs do. another downside is that it opens 4 different windows, which is a pain when I want to flip between it and Tera Term.

I've yet to find software that's

1. An executable (.EXE) so it has no external reliance
2. Includes a terminal emulator or serial data logger
3. Logs serial data
4. Graphs multiple items from a CSV
5. Allows for CSV AND tab-delimited data (which is way easier to read as it scrolls along while *simultaneously* monitoring the graph.
6. Allows setting of different scales for each overlaid graph without having to scale everything to \[0..1\] or setting a multiplier, i.e. allowing setting an \[y0..y1\] range for each item graphed.
> 0 votes

# Answer
Telemetry Viewer

Advantages:

1. Easy to use
2. Intuitive and flexible UI
3. Open Source and free
4. Different types of Graphs
5. Very fast graph update rate

Disadvantages:

1. Stopped development
2. Binary data format is not complete yet.
3. Primitive graph controls like zoom, screenshot and ...
> 0 votes

# Answer
SVisual Monitoring and recording of signals for Arduino and not only.

Video example

Download (free)
> 0 votes

# Answer
I am using processing.org for serial plotting from Arduino. It was the only app I could find that allowed me to make real histograms ( e.g. a million events in a hundred bins) and display various info numbers in addition to mean sigma for each channel. Two major problems: A) it turned out to be based on Java with no unsigned bytes B) synch ig with input required circular buffer and markers in the data. ( high speed, no handshake)
> 0 votes

# Answer
HITIPanel Serial data plotting and recording. You can zoom in/out, pan, export data to text or excel file, or import external data from text files. Come with a user interface to control and monitor the hardware.
> 0 votes

---
Tags: serial
---


# Question
Title: Why won't my servo and ultrasonic sensor work together?
I have a school project due tomorrow, and I'm planning to connect a servo motor with an ultrasonic sensor. If the distance is under 10cm, the servo motor should turn 180 degrees and will return to 0 degrees when there's no object in front of the sensor. I've tried them separately, the sensor by itself works and could read distance as usual and the servo works too. However, when I put the two code together, it just seems to cancel each other out. I don't know much about coding but pretty sure the sensor is supposed to print the distance on the serial monitor, but it just stops working, I also put some code to try and get the servo to turn, but it also doesn't work... So now I'm stuck pls help me, it's due tomorrow :(

Could it be my power source? I'm using my laptop to power it... but my friend did the same project, and it worked well using laptop as a power source, but i saw some post like this that encourages me to change power source, but isn't a laptop a huge power source? (genuinely asking)

```
#include <Servo.h>
#define servopin 9
#define echoPin 4
#define trigPin 5

Servo Myservo;
int long duration;
int distance;

void setup() {
    Myservo.attach(servopin);
    pinMode(echoPin, INPUT);
    pinMode(trigPin, OUTPUT);
}

void loop() {
    digitalWrite(trigPin, LOW);
    delayMicroseconds(2);
    digitalWrite(trigPin, HIGH);
    delayMicroseconds(10);
    digitalWrite(trigPin, LOW);

    duration = pulseIn(echoPin, HIGH);
    distance = (duration * 0.034 / 2);

    if (distance < 10)
    {
        Myservo.write(180);
    }
    else
    {
        Myservo.write(0);
    }
    delay(500);
}

```

# Answer
> 0 votes
I tried your code on online simulator, and it works perfect!
Maybe just try another distance check like `if(distance<30)` (at least) and let's know what will happen.
*I don't think using the laptop as a power source is your problem*

---
Tags: sensors, servo
---


# Question
Title: Sounds are being played at the same time
I'm making a school project that allows plants to 'talk'. As in when the plant is in an un-ideal environment (low or high soil moisture, not ideal temperature or humidity and not enough light). I have currently made some demo code for my presentation as the real code has real thresholds and is hard to trigger instantly during the presentation. The problem im facing is that the sound is almost always cut off by another one, how can i stop this, also the recordings are all 7 seconds or less.

```
#include <DHT.h>
#include <SoftwareSerial.h>
#include <DFRobotDFPlayerMini.h>
#include <LiquidCrystal_I2C.h>
//-----------------DEMO---CODE-------
#define DHTPIN 3
#define DHTTYPE DHT22
#define SOIL_MOISTURE_PIN A0
#define LIGHT_SENSOR_PIN 2
#define TEMP_THRESHOLD 25.0
#define HUMIDITY_THRESHOLD 60
#define LIGHT_THRESHOLD 1  // 1 for dark, adjust as needed
#define LOWER_SM_THRESHOLD 20 // Adjust as needed
#define UPPER_SM_THRESHOLD 50 // Adjust as needed
#define LCD_ADDR 0x27  // I2C address of the LCD
#define LCD_COLUMNS 16
#define LCD_ROWS 2
#define MESSAGE_INTERVAL 20000  // 20 seconds in milliseconds

DHT dht(DHTPIN, DHTTYPE);
SoftwareSerial mySoftwareSerial(10, 11);  // RX, TX for DFPlayer
DFRobotDFPlayerMini myDFPlayer;
LiquidCrystal_I2C lcd(LCD_ADDR, LCD_COLUMNS, LCD_ROWS);

unsigned long lastTempTrigger = 0;
unsigned long lastHumidityTrigger = 0;
unsigned long lastSoilMoistureTrigger = 0;
unsigned long lastLightTrigger = 0;

void setup() {
  dht.begin();
  Serial.begin(9600);
  mySoftwareSerial.begin(9600);
  myDFPlayer.begin(mySoftwareSerial);

  myDFPlayer.volume(30);

  // Initialize the LCD
  lcd.init();
  lcd.backlight();
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("Initializing...");
  delay(2000);
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("Plantastic!");
  lcd.setCursor(0, 1);
  lcd.print("System Ready");
  delay(2000);
  lcd.clear();
}

void loop() {
  float temperature = dht.readTemperature();
  float humidity = dht.readHumidity();
  int lightValue = digitalRead(LIGHT_SENSOR_PIN);
  int soilMoistureValue = analogRead(SOIL_MOISTURE_PIN);
  int soilMoisturePercentage = 100 - (map(soilMoistureValue, 0, 1023, 0, 100));

  if (temperature > TEMP_THRESHOLD && millis() - lastTempTrigger >= MESSAGE_INTERVAL) {
    myDFPlayer.play(3);  // Play "Too Hot" message
    lastTempTrigger = millis();
  } else if (temperature < TEMP_THRESHOLD && millis() - lastTempTrigger >= MESSAGE_INTERVAL) {
    myDFPlayer.play(1);  // Play "Too Cold" message
    lastTempTrigger = millis();
  }

  if (round(humidity) < HUMIDITY_THRESHOLD && millis() - lastHumidityTrigger >= MESSAGE_INTERVAL) {
    myDFPlayer.play(2);  // Play "Low Humidity" message
    lastHumidityTrigger = millis();
  }

  if (soilMoisturePercentage < LOWER_SM_THRESHOLD && millis() - lastSoilMoistureTrigger >= MESSAGE_INTERVAL) {
    myDFPlayer.play(6);  // Play "Thirsty" message
    lastSoilMoistureTrigger = millis();
  } else if (soilMoisturePercentage > UPPER_SM_THRESHOLD && millis() - lastSoilMoistureTrigger >= MESSAGE_INTERVAL) {
    myDFPlayer.play(5);  // Play "Enough Water" message
    lastSoilMoistureTrigger = millis();
  }

  if (lightValue == 1 && millis() - lastLightTrigger >= MESSAGE_INTERVAL) {
    myDFPlayer.play(4);  // Play "It's dark in here" message
    lastLightTrigger = millis();
  }

  // Update the LCD display
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("T: ");
  lcd.print(temperature, 2);
  lcd.print(" H: ");
  lcd.print(humidity, 2);
  lcd.setCursor(0, 1);
  lcd.print("SM: ");
  lcd.print(soilMoisturePercentage);
  lcd.print("% L: ");
  lcd.print(lightValue == LIGHT_THRESHOLD ? "Dark" : "Light");

  delay(1000);
}

```

# Answer
There are 2 approaches which address the problem of not playing a sound to completion.

1. Place a delay loop after each call to myDFPlayer.play() designed to last as long as the played sound. This is likely the most straight forward solution. However, adding delays where no other code is able to run is considered bad programming form. It also creates problem when adding new features to the program.
2. Create a finite state machine where the loop() function has no delays. Instead use a variable to track the state the state machine is in and only change that variable when the conditions to go to the next state have been satisfied. For instance, do nothing until a threshold (dryness, light, ect) has been crossed. At which point switch to the state where you play back the associated sound & clear that threshold flag. Do not exit that state until millis() has increased past the duration of the played sound. Finally, repeat these state transitions for any other thresholds that have been crossed. Complex behaviors dealing with how long before repeating a sound can then be added with additional states.
> 1 votes

---
Tags: arduino-uno, code-review
---


# Question
Title: Arduino Pro Mini doesn't automatically reset
I have an issue with my Arduino pro mini. Yesterday, I uploaded a sketch a few times on the pro mini, with an FTDI adapter, and everything worked fine. Today I'm trying to re-upload a sketch, but now, for some obscure reasons, my Arduino pro mini doesn't want to reset itself. I need to manually reset it. Since it is embedded in s case, I can't do that if I want to upload a sketch.

**EDIT**: I managed to make some tests, and it would seem that the DTR pin on the mini doesn't work anymore. When I short the DTR PIN to GND, the mini doesn't reset itself. I believe that could be a reason. But why? And how? It was working a day ago.

I soldered the FTDI like that, and it didn't work several times. (At the moment I left it unsoldered because I don't want to solder it yet):

Can anyone complete my intuition?

Thanks in advance.

# Answer
Is this is an actual photo of your FTDI and mini? I can't tell whether the FTDI pins are soldered to the mini. If not, I would guess that the problem is an unreliable electrical connection at one of the pins, and look there for the problem.

If it helps, this is what I use for my embedded devices. The FTDI is in the USB-A connector. The embedded end is just a female connector that pushes onto the 6 pins on the board. This cable supplies +5v; there are also ones that supply 3.3v.

> Thanks for your answer, the connection is soldered.

In that case, I'd check the resistance of the solder joints including trying to wiggle them; then trying to narrow it down by swapping FTDI boards if you have another; and likewise, swapping the mini board.
> 0 votes

# Answer
The reset pulse issued by the USB-Serial adapter via the DTR line may be of low amplitude (3.3V). This is occasionally too low for the Pro Mini reset function. Sometimes, it helps to solder a 47k resistor across the reset button contacts, lowering the initial DC level of the reset input. This applies to 5V/16MHz and 3.3V/8MHz versions of the Pro Mini.
> 0 votes

---
Tags: arduino-pro-mini, ftdi
---


title: D1 mini ESP8266 no sound on speaker

text:
# Question
Title: D1 mini ESP8266 no sound on speaker
I am new to Arduino and microcontrollers, I want to make a tone with my D1 mini and a LSM-50F speaker. But I don't get any output. Any idea what I am doing wrong? Tested it with two D1 mini boards.

This is how I wired everything:

Specifications:

```
Impedance   45 Ohm
Power (Nominal)   0,2 W
Power (Maximum)   0,5 W
Resonance frequency   450 Hz

```

The D1 mini's GPIO pins have a maximum of 10 mA, so I am using a 330 Ohm resistor in series to the 45 Ohm speaker to avoid overloading.

```
I = U/R
I = 3.3 V / 330 Ohm + 45 Ohm
I = 3.3 V / 375 Ohm
I = 8.8 mA

```

My code:

```
int Speaker = 5;

void setup()
{
}

void loop()
{
tone(Speaker, 450);
delay(1000);
noTone(Speaker);
}

```

I also tried a piezo from an old computer in the same setup. Not sure if the piezo is active or passive, so I tried using:

```
digitalWrite(Speaker, HIGH); // Play a tone on an active piezo.

```

And

```
tone(Speaker, 450); // Play a tone on a passive piezo.

```

# Answer
> 1 votes
You are plugged into D5 and have `int Speaker = 5;` However, D5 and 5 are actually different things.

```
static const uint8_t D5   = 14;

```

The plain number refers to the GPIO number of the esp8266 chip. The "D5" type numbers that are silk screened are mapped onto those. So you need `int Speaker = D5;` or alternately `int Speaker = 14; /*D5 is GPIO14*/` or you need to move the wire to the actual GPIO5 which is labeled `D1`.

You may find your speaker is very quiet, maybe inaudible. If you're going to try driving a speaker from a GPIO pin the piezo is a better choice. But really it would be better to have some kind of amplification. This is the sort of thing I've used with piezos before. You can test that you're affecting the pin at all with a meter. You may get a weird reading, but you should at least be able to tell the difference between that and a pin you aren't trying to use.

---
Tags: esp8266, pwm, speaker
---