text:
Problem with using PubSubClient, the "callback" function doesn't seem to work correctly
I have a program that communicate between a esp8266 and a atmega328 using Serial, the esp8266 will connect to a MQTT server running on local network, and publish/subscribe to some topics. In the callback function for the subscribing, it will send an instruction to atmega chip to toggle the LED (pin 13). I am using XC4411 board which is an integrated 2-in-1 board with both esp and atmega.
The code looks like this:
On esp side:
#include <ESP8266WiFi.h>
#include <PubSubClient.h>
#include "credentials.h" // this is where I define the wifi ssid, psw, mqtt username/psw etc.
#include <Arduino.h>

#define SERIAL_BAUD 115200 //make sure this is the same in atmega code, serial communication with atmega chip
#define ESP8266_LED 1

WiFiClient espWifiClient;
PubSubClient espMQTTClient(espWifiClient);
const char* test_topic = "/test/msg01";
void reconnect();
void callback(char *topic, uint8_t *payload, unsigned int length);

void setup_wifi() {
    delay(10);
    WiFi.begin(MY_SSID, MY_WIFIPSW);
    while (WiFi.status() != WL_CONNECTED) delay(500);
}

void setup_mqtt() {
    espMQTTClient.setServer(MY_MQTT_SERVER_ADDRESS, MY_MQTT_SERVER_PORT);
    reconnect();
    espMQTTClient.subscribe(test_topic);
    espMQTTClient.setCallback(callback);

}

void reconnect() {
    while(! espMQTTClient.connected()) {
        if (espMQTTClient.connect(MY_MQTT_CLIENT_ID, MY_MQTT_USER, MY_MQTT_PSW)) {
            espMQTTClient.subscribe(test_topic);
        }
        else delay(500);
    }
}

void callback(char *topic, uint8_t *payload, unsigned int length) {

    digitalWrite(ESP8266_LED, !digitalRead(ESP8266_LED));
    Serial.println("[toggle]");

    // espMQTTClient.publish("/test/esp8266", topic, length);
    espMQTTClient.publish("/test/esp8266", payload, length);

    if (strcmp(topic, test_topic) == 0) {
        if (length >= 0 && (char) payload[0] == '1') {
            espMQTTClient.publish("/test/esp8266", "get payload 1");
        } else if (length >= 0 && (char) payload[0] == '0') {
            espMQTTClient.publish("/test/esp8266", "get payload 0");
        } else {
            espMQTTClient.publish("/test/esp8266", "unknown payload for topic /test/msg01");
        }

    }
}

void setup() {
    Serial.begin(SERIAL_BAUD);
    setup_wifi();
    setup_mqtt();
    pinMode(ESP8266_LED, OUTPUT);
}

String data_from_arduino = "";

void loop() {
    if (! espMQTTClient.connected()) reconnect();
    espMQTTClient.loop();
    while (Serial.available()) {
        char x = Serial.read();
        if (x == '\r')
            continue;
        data_from_arduino += x;
    }
    if (data_from_arduino != "") {
        espMQTTClient.publish("/test/arduino", data_from_arduino.c_str());
        data_from_arduino = "";
    }
    // espMQTTClient.publish("/test/esp8266", "hello from esp"); // this line works fine, so there is no connection problem
}

On atmega side:
#include <Arduino.h>

#define SERIAL_BAUD 115200

#define LED_PIN 13

String receivedCommand = "";
bool dataIn = false;

void setup()
{

    Serial.begin(SERIAL_BAUD); //same as ESP baud
    pinMode(LED_PIN, OUTPUT);
}

String msg_from_esp8266 = "";
bool start_receiving_msg = false;

void loop()
{
    while (Serial.available())
    {
        char c = Serial.read();

        if (c == '[')
        {
            start_receiving_msg = true;
            msg_from_esp8266 = "";
        } else if (start_receiving_msg && c != ']') {
            msg_from_esp8266 += c;
        } else if (start_receiving_msg && c == ']') {
            start_receiving_msg = false;
            if (msg_from_esp8266 == "toggle") {
                digitalWrite(LED_PIN, !digitalRead(LED_PIN));
                Serial.println("arduino toggle led");
            }
        }

    }
    delay(10);
}

Basically when you publish anything to topic /test/msg01 manually, it will try to toggle the esp8266's built in led. then esp8266 will publish a message to /test/esp8266 with the exact payload you publish to /test/msg01. Also, esp8266 will also send a serial message "[toggle]" to atmega. On the atmega side, it will check if it receives the "[toggle]" and toggle its built in LED, then it will send a message through serial. on the esp side, in the loop, it will receive that message from atmega and publish it to topic /test/arduino. This program is to test the communication between other mqtt client devices and the esp8266, as well as (communication between other mqtt client devices) and the atmega through esp8266 via serial.
The code in if (strcmp(topic, test_topic) == 0) is just some other additional test code.
Generally, you should expect the behaviour like this: once you publish any message to topic /test/msg01, you will see the same message being relayed to topic /test/esp8266. both esp8266 and atmega will toggle their LED on and off. And the message "arduino toggle led" will be published to topic /test/arduino.
However, neither LED toggles. And there is no message from /test/arduino. in topic /test/esp8266 I saw some garbage text instead of my original message.
I have already troubleshooted the connection, the board configuration and checked if the lED is broken. They are all good, and I am pretty sure that the problem is to do within the "callback" function.
Here are some screenshot with the mqtt message:
What I have published to /test/msg01:

What I get from /test/esp8266

And, there is no problem with the message in /test/msg01 as I was also subscribing to the topic and get the same message as I published.

I didn't receive any message from topic "/test/arduino", so seems like the Serial message didn't get to atmega.
And again no problem with XC4411 board configuration as I turn the button 1, 2 on after I done flashing the two chips, and the code compiled and was uploaded to both chip successfully.
Looks like the callback function just corrupted my message, and also just somehow skipped and ignored the line that sends the toggle message to arduino and the line that toggle esp8266's LED.
I am very new to these topic discussed in the question in general, so maybe there are some mechanism that I am not aware of. Thank you the answers in advance.

From the PubSubClient library documentation:

Internally, the client uses the same buffer for both inbound and outbound messages. After the callback function returns, or if a call to either publish or subscribe is made from within the callback function, the topic and payload values passed to the function will be overwritten

Hi, that make sense. Thanks. Any ideas on why the LED isn't turn on and off?

I'm not familiar with the XC4411 board but suspect the ESP8266 LED isn't on GPIO 1 and anyway it may not be possible to use serial and the built in LED at the same time


text:
A4988 Jitter on stepper motor, some of the time
Hardware:

Arduino Uno Rev3
A4988 Driver
Nema 8 Stepper

Setup:
I've adjusted the VRef of the driver based on the formula VRef = Imot * 8 * Rsen. With the values of Imot = .5 (max = .6), Rsen = .068.
A 12-Volt power supply is being used to supply power to the breadboard hat for the Arduino.
The Arduino code is being activated by a Python GUI, that is sending commands to the Arduino to make adjustments to the code in order to manipulate delay between steps, step size, and enable/disable. here is a simplified version of the Arduino code.
#include "src/Laser_Welder_8124.h"

void setup() {
    //
    Serial.begin(115200);

    pinMode(STEPPER_DIR, OUTPUT);
    pinMode(STEPPER_STEP, OUTPUT);

    pinMode(STEPPER_ENABLE, OUTPUT);
    pinMode(STEPPER_MS1, OUTPUT);
    pinMode(STEPPER_MS2, OUTPUT);
    pinMode(STEPPER_MS3, OUTPUT);

    digitalWrite(STEPPER_MS1, HIGH);
    digitalWrite(STEPPER_MS2, HIGH);
    digitalWrite(STEPPER_MS3, HIGH);

    digitalWrite(STEPPER_DIR, HIGH);
    digitalWrite(STEPPER_ENABLE, HIGH);
}

void loop() {

    curMillis = millis();
    commsCheck();
    singleStep();
}

void commsCheck(){

    if(Serial.available() > 0){

        int rlen = Serial.readBytes(incomingMsg, MSGSIZE);
        byte cmd = incomingMsg[CMD_POS];

        int val = incomingMsg[VAL_POS];

        switch(cmd){
            case 0xC0:{
                enableStepperMotor(val);
                break;
            }
            case 0xC1:{

                toggleStepperDirection(cmdLookup[2].pin, val);
                break;
            }
            case 0xC2:{

                cmdLookup[0].state = val;
                millisBetweenSteps = val;

                break;
            }
            case 0xC7:{

                setStepSize(val);
                break;
            }
        }
    }
}

void setStepSize(int val){

    switch(val){
        case 0xD0:{
            stepSize(HIGH, HIGH, HIGH);
            break;
        }
        case 0xD1:{
            stepSize(HIGH, HIGH, LOW);
            break;
        }
        case 0xD2:{
            stepSize(LOW, HIGH, LOW);
            break;
        }
        case 0xD3:{
            stepSize(HIGH, LOW, LOW);
            break;
        }
        case 0xD4:{
            stepSize(LOW, LOW, LOW);
            break;
        }
    }
}

void stepSize(int MS1, int MS2, int MS3){
    digitalWrite(STEPPER_MS1, MS1);
    digitalWrite(STEPPER_MS2, MS2);
    digitalWrite(STEPPER_MS3, MS3);
}

void toggleStepperDirection(int pin, int val)
{

    if (val == 0){
        cmdLookup[1].state = CW;
        digitalWrite(STEPPER_DIR, LOW);
    }
    else{
        cmdLookup[1].state = CCW;
        digitalWrite(STEPPER_DIR, HIGH);
    }
}

void singleStep() {

    if (curMillis - prevStepMillis >= millisBetweenSteps) {

        prevStepMillis = curMillis;
        digitalWrite(STEPPER_STEP, HIGH);
        digitalWrite(STEPPER_STEP, LOW);
    }
}

This works, for the most part.
I'm using the GUI to pass a value from 1-255 to represent a delay between steps in milliseconds.
If I set the time between steps to 1 ms, then it runs smoothly on all step sizes. However, when I start to play with the time delay, I get all sorts of jitter, at different time delays with different step sizes. How do I go about smoothing out the motor so I can use a range of delays across different step sizes?
I've attached a video link to show you what I'm seeing.
Video Link of motor behavior

source: Stack Exchange

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

sort: votes


text:
Atmega 328pu on breadboard. What to choose in order to upload code with ftdi converter
When I program atmega328 PU on breadboard,vwhat programmer do I have to use and what arduino board type I have to choose? I am trying this with ftdi converter I have already done the connections and it's okay but there's an error when I'm trying to upload the code either with instant upload either with the programmer. Everything can help is acceptable and thanks in advance for your support.

Does your ATmega have the Arduino bootloader?

There are quite a few questions here about breadboard computers. Try searching this site for "breadboard". I also have a page about making a breadboard Arduino which might help.
Normally I would set the Arduino type to Uno if the breadboard computer has a 16 MHz oscillator or crystal on it. If you are running at 8 MHz (possibly with the internal oscillator) I would set it to Lilypad.
If the chip doesn't have a bootloader on it then you need to install that first. I have a page about installing a bootloader which might help.
To install the bootloader you need to use an SPI interface as described on the above page. That requires running 6 wires from an existing (working) Arduino to your breadboard.

it's okay but there's an error when I'm trying to upload the code

It's OK? But there's an error? What error message?

I will try this next days. Although we have a different ftdi converter. I have a red one with the ft232rl chip. Thanks for help. If I can't achieve it after this i will come back again. Thank you

I have a number of atmega328-PU-on-breadboards. I build them with a 16MHz crystal and load the Uno Optiboot loader if they don't already have a bootloader installed. I program them with an FTDI USB to TTL Serial 5V Adapter Cable 6 Pin 0.1 inch Pitch Female Socket Header UART IC FT232RL Chip (or the 3.3v version of the same cable, if I built for 3.3v). By using a 16 MHz crystal and a standard bootloader, I can select 'Uno' as the board type in the IDE and everything works. On the board, I build a 6-pin header to accept the cable's 6-pin female header I use connect it for for uploading and/or viewing debug output on the board's serial port, but otherwise remove it and power the board through a more compact micro-USB connector. You could always make a more permanent connection between your board and the USB-FTDI cable if you find that more suitable.
Update:

what programmer do you choose ? Also can you share your pinout ?

My programmer is avrdude, run by the IDE. My boards program exactly like an Uno.
Pinout:
.
The CTS output (brown wire) is unused; the RTS output is wired connected to the reset pin through a 0.1uF capacitor, if you want the auto-reset feature. If you are using a different FTDI device, you will, of course, have to use it's particular pinout but it should provide the same signals and behavior.
This is the reset circuit I use on my board (crudely drawn but gets the point across):

Its ok ,but what programmer do you choose ? Also can you share your pinout ? Thanks in advance

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


text:
channels on logic level shifter outputs high
so I have a logic level shifter which is TXS0108E ,I use it to shift the eps32 ouput volatge to 5v to be used with motor driver ,when I test it with multimeter , all the channels on the B side outputs high (5v) without connecting anything on the A side, my connection is this :

it is normal...

So how can the driver know if it is high or low if it is all the time high

an unconnected pin of the converter when powered is HIGH. the input must pull it down to change the state and that state is reflected on output.

Oh I didn't know that , thanks.


text:
Arduino Nano not recieving MIDI Message
I'm building an MIDI to CV converter using an Arduino nano along with a MIDI input circuit, however, when uploading the code and connecting the MIDI to a laptop via USB, the Arduino doesn't recognize any input signals. Also, I'm confused on how to code for MIDI notes if anyone can offer guidance. I've followed building the circuit in the following link:
MIDI Input Circuit
Below is also the code I'm using:
/*

* Connections:

* (1) Midi Connector

* (2) DAC MCP4728:

* SDA pin to A4/SDA (Arduino Nano)

* SCL pin to A5/SCL (Arduino Nano)

* GND to GND

* VCC to +5V

* (3) Clock Rate Potentiometer

*

* Outputs:

* DAC OUT

*   Channel A-C to Drum Kit and Channel D to VCO

* Clock output with LED

* Gate 1 and 2 with LEDs

*/

#include <MIDI.h>

#include <Wire.h> // Include the Wire to talk I2C

#include <Adafruit_MCP4728.h>

// This is the I2C address of the MCP4728

#define MCP4728_ADDR 0x64

MIDI_CREATE_DEFAULT_INSTANCE();

Adafruit_MCP4728 dac;

#define GATE1 4   // pin D4 for Gate 1

#define GATE2 3   // pin D3 for Gate 2

#define G1LED 7   // pin D7 for signaling LED of Gate 1

#define G2LED 6   // pin D6 for signaling LED of Gate 2

#define CLOCK_OUT 5 // pin D5 (PWM) for Clock Out

#define CLED 8      // pin D8 for signaling LED of Clock out

float refVoltage = 5.04;  // Note cannot be higher than reference voltage

int previousNotePlayed1;

int previousNotePlayed2;

int previousNotePlayed3;

int previousNotePlayed4;

int clockRate = A0; // Potentiometer connected

int clockSpeed; // current clock speed, in milliseconds per beat

void setup() {

  // put your setup code here, to run once:

  pinMode(CLED, OUTPUT);

  pinMode(G1LED, OUTPUT);

  pinMode(G2LED, OUTPUT);

  pinMode(CLOCK_OUT, OUTPUT);

  pinMode(GATE1, OUTPUT);

  pinMode(GATE2, OUTPUT);

  MIDI.setHandleNoteOn(doThisNoteOn); // calls the function on note on

  MIDI.setHandleNoteOff(doThisNoteOff); // calls the function on note off

  MIDI.begin(MIDI_CHANNEL_OMNI);  // Listen to all midi channels

  Serial.begin(250000);

  Wire.begin();

  dac.begin(0x64);

} // end of setup

void loop() {

  // put your main code here, to run repeatedly:

  MIDI.read();  // Read incoming messages

  // Read the value of the tempo potentiometer and map it to a range of reasonable clock speeds

  int clockValue = analogRead(clockRate);

  clockSpeed = map(clockValue, 0, 1023, 1000, 250); // tempo range from 60 BPM to 240 BPM

  // send a clock pulse every clockSpeed milliseconds

  static unsigned long lastClockTime = 0;

  if (millis() - lastClockTime >= clockSpeed){

    digitalWrite(CLOCK_OUT, HIGH);

    digitalWrite(CLED, HIGH);

    delayMicroseconds(clockValue);    // initially had delayMicroseconds(10);

    digitalWrite(CLOCK_OUT, LOW);

    digitalWrite(CLED, LOW);

    lastClockTime = millis();

  }

} // end of loop

void doThisNoteOn(byte channel, byte note, byte velocity){

  if (channel == 1){  // Listen to channel 1 to set CV1

    previousNotePlayed1 = note;

    float voltPerOctave = (note - 24) * 0.0833;

    int dacInput = (voltPerOctave / refVoltage) * 4096;

    dac.setChannelValue(MCP4728_CHANNEL_A, dacInput);

    digitalWrite(GATE1, HIGH);

    digitalWrite(G1LED, HIGH);

  }

  if (channel == 2){  // Listen to channel 2 to set CV2

    previousNotePlayed2 = note;

    float voltPerOctave = (note - 24) * 0.0833;

    int dacInput = (voltPerOctave / refVoltage) * 4096;

    dac.setChannelValue(MCP4728_CHANNEL_B, dacInput);

    digitalWrite(GATE1, HIGH);

    digitalWrite(G1LED, HIGH);

  }

  if (channel == 3){  // Listen to channel 3 to set CV3

    previousNotePlayed3 = note;

    float voltPerOctave = (note - 24) * 0.0833;

    int dacInput = (voltPerOctave / refVoltage) * 4096;

    dac.setChannelValue(MCP4728_CHANNEL_C, dacInput);

    digitalWrite(GATE1, HIGH);

    digitalWrite(G1LED, HIGH);

  }

  if (channel == 4){  // Listen to channel 4 to set CV4... this CV will be used for the VCO

    previousNotePlayed4 = note;float voltPerOctave = (note - 24) * 0.0833;

    int dacInput = (voltPerOctave / refVoltage) * 4096;

    dac.setChannelValue(MCP4728_CHANNEL_D, dacInput);

   digitalWrite(GATE2, HIGH);

    digitalWrite(G2LED, HIGH);

  }

} // end of doThisNoteOn

void doThisNoteOff(byte channel, byte note, byte velocity){ //Handles note off correctly for previously played noted

  if (note == previousNotePlayed1){

    MIDI.sendNoteOff(1, note, 0);

    // velocity = 0;

    digitalWrite(GATE1, LOW);

    digitalWrite(G1LED, LOW);

  }

  if (note == previousNotePlayed2){

    MIDI.sendNoteOff(2, note, 0);

    // velocity = 0;

    digitalWrite(GATE1, LOW);

    digitalWrite(G1LED, LOW);

  }

  if (note == previousNotePlayed3){

    MIDI.sendNoteOff(3, note, 0);

    // velocity = 0;

    digitalWrite(GATE1, LOW);

    digitalWrite(G1LED, LOW);

  }

  if (note == previousNotePlayed4){

    MIDI.sendNoteOff(4, note, 0);

    // velocity = 0;

    digitalWrite(GATE2, LOW);

    digitalWrite(G2LED, LOW);

  }

} // end of doThisNoteOff

Also an image of the module:

What is the purpose of the Serial.begin call? Doesn't it use the same pins as the MIDI object?


text:
if statement does not work with fraction, but works with decimal equivalent
I'm trying to trouble shoot a problem with my code and narrowed it down to my if statement not working with a fraction.
The below code does not work and returns 0
for(float i=0; i <= 1; i += .0001){
 t += .0001;
 if(t >= 1/440){ //Fraction
   t = 0;
 }
 Serial.println(t*100);
 delay(100);
}

But when I replace the 1/440 with its decimal equivalent (.0022727) it works fine and counts from 0 to 2.2
for(float i=0; i <= 1; i += .0001){
 t += .0001;
 if(t >= 0.0022727){ //Decimal
   t = 0;
 }
 Serial.println(t*100);
 delay(100);
}

If there is a simple way to use a fractional value instead of a decimal value it would make my application much similar.
Thanks.

Always present float calculations like this 1.0/440.0 and not 1/440 to prevent  these being treated as integer calculations. Avoid using floats in comparisons especially '==' comparisons.

@6v6gt  Please read When shouldn't I comment?. If you aren't requesting clarification from the author (or the other couple of reasons to comment on the question) then you should be posting an answer instead.

@6v6gt You may want to look at this. I don't know if it will matter being as old as it is, but you could weigh in on it if you have the interest; I don't. But I would them to make up their minds about it.

@NickGammon One problem with giving a formal answer in such a borderline off topic case (this one could fail if the often applied test "non-Arduino specific" is applied and it does anyway have a general C/C++ look to it) is that the answerer risks losing a couple of Brownie points if someone decides to assert that it is off topic and starts down-voting both the question and the answer.  Some answers which I have put considerable effort into, and the OP could not have known that the solution to the problem was "Non-Arduino specific", have ended up with a -1 score.

@6v6gt Yeah, I agree. I try to ignore the occasional down-vote as there are people who like to nitpick that sort of stuff. It's true it's really a programming question, but we do have a programming tag after all, so I think programming questions are OK. Especially if beginners to Arduino maybe think that the Arduino has different rules to C++.

"The process of designing and writing source code as part of a program (or sketch) for Arduino." It is not clear that this applies to the question asked nor the answer given. Nor that it isn't in conflict with "If the solution would be the same with or without Arduino, then it's usually a general coding question". I don't disagree with your desire to answer it here. But your thinking is not evidently supported by the rules where it isn't evidently not supported by the rules.

1/440 will be treated as an integer expression, returning zero.
To make it work, make one or both operands a floating-point type. In your case:
 if(t >= (float)1 / 440){ //Fraction
   t = 0;
 }

Or:
 if(t >= 1.0/440){ //Fraction
   t = 0;
 }


text:
Arduino Bluepill STM32 spi doesn't work
Has anyone successfully use SPI1 of those pins?
SCLK -> PB3
SDIO -> PB5
SDO -> PB4
MISO CS -> PA15

I've tried to use another side of SPI1 pins on the other sides of the board (PA4, 5, 6, 7) and i can successfully communicate with

Arduino and STM32 Blue pill are not the same, they are different platforms. And you need to supply more details, like the complete code.

i used the stm32arduino core , so i will perform like arduino and the code is very simple just spi output to sensor its not responsing at all until i switch the pin it will work fine

It depends on how you use the SPI object. If you use the SPI object directly like what Arduino Uno without creating an instance object, the SPI construct will default to the PA4 - PA7, see the default pins definition and default Class construct of Blue Pill.
For STM32 Arduino Core (Stm32duino), there are four STM32 Arduino Core specific APIs for configure the alternative SPI pins.
void setMISO(uint32_t miso)
void setMOSI(uint32_t mosi)
void setSCLK(uint32_t sclk)
void setSSEL(uint32_t ssel)

These must be called before the SPI.begin().
Another alternative way of using the alternative SPI pins is to create an SPI object and pass-in the pin assignments like this:
#include <SPI.h>

SPIClass mySPI(PB5, PB4, PB3, PB15); //mosi, miso, sclk, ssel

See the alternative construct API, and further information on STM32duino wiki page.

Thank a lot , you had no idea how many hours i waste on this thing :)


text:
Arduino Mega Loopback Test with Several TX/RX Ports
I am trying to do a loopback test using an Arduino Mega. What I am looking to do is send a byte over TX and receive said byte back at RX and verify that the byte is unchanged. More or less I just have a jumper wire connecting the TX and RX ports (In reality I have a circuit hooked up to the TX RX ports that effectively acts like a wire, I'm just trying to verify that the circuit traces are sound).
I am also doing the exact same thing over TX2/RX2 and TX3/RX3.
The issue I have run into is that I can't seem to get the data to send out the TX ports. In my attempt I used Serial objects where I would do the following:
void setup() {
Serial.begin(9600); //0 and 1
Serial2.begin(9600); //16 and 17
Serial3.begin(9600); //14 and 15
}

void loop() {

//RX TX
int bytesSent = Serial.write(1);
delay(500);
if(Serial.read()!=bytesSent){

  //Do Something

}

delay(500);

//RX2 TX2
bytesSent = Serial2.write(2);
delay(500);
if(Serial2.read()!=bytesSent){

   //Do Something

}

delay(500);

//RX3 TX3
bytesSent = Serial3.write(3);
delay(500);
if(Serial3.read()!=bytesSent){

   //Do Something

}

delay(500);

}

I'm aware that the use of "delay(500)" is not optimal nor good coding practice but is left here for now while I'm still trying to understand what's wrong with my transmit and receive.
I believe my misunderstanding comes in with the Serial objects; Am I not using them correctly in this case? I've referenced the Arduino Serial reference guide, so this seems like it would work, but does not.
Further details: I am currently powering my Arduino via USB (which I'm aware can be an issue, but I currently do not have the battery power source). Would switching to the other power source resolve my issue? Just to reiterate I'm not trying to communicate with the PC, I'm just trying to verify that this external circuit (which acts like a wire) is able to carry the signal.

you have a logic error ... your code assumes that  bytesSent contains the data that was sent

How exactly do you know, that it doesn't work? In the code above you aren't doing anything. You only have the comments in there.

There seems to be a slight misunderstanding here:
bytesSent = Serial2.write(2);
// [...]
if (Serial2.read() != bytesSent) // [...]

On the serial ports:

the method write() returns the number of bytes that were written,
not the value of a written byte

the method read() returns the byte that was read (or −1 if nothing
was available), not the number of bytes read.

I suggest you modify your test like this:
uint8_t byte_sent = random(256);
Serial2.write(byte_sent);
delay(100);
if (Serial2.read() != byte_sent) // there was an error


text:
Arduino Nano not receiving MIDI messages
so I am currently creating a MIDI to CV module and am still having trouble with my MIDI input circuit. I am following this circuit as my guideline and am sending MIDI messages via MIDI interface with the use of this cable. I am also using this software called MIDIKeys as a virtual keyboard for the MIDI notes. Unfortunately, every time I play a note on the keyboard the Arduino doesn't respond with the blink of the LED. I could really use some guidance on fixing this problem.
Below is also the code that I'm using:
#include <MIDI.h>  // Add Midi Library

#define LED 13    // Arduino Board LED is on Pin 13

//Create an instance of the library with default name, serial port and settings
//MIDI_CREATE_DEFAULT_INSTANCE();
MIDI_CREATE_DEFAULT_INSTANCE();

void setup() {
  pinMode (LED, OUTPUT); // Set Arduino board pin 13 to output
  MIDI.begin(MIDI_CHANNEL_OMNI); // Initialize the Midi Library.
  MIDI.turnThruOff();
  MIDI.setHandleNoteOn(MyHandleNoteOn);
  MIDI.setHandleNoteOff(MyHandleNoteOff);
  Serial.begin(31250);
}

void loop() { // Main loop
  MIDI.read(); // Continuously check if Midi data has been received.
}

void MyHandleNoteOn(byte channel, byte pitch, byte velocity) {
  digitalWrite(LED,HIGH);  //Turn LED on
}

void MyHandleNoteOff(byte channel, byte pitch, byte velocity) {
  digitalWrite(LED,LOW);  //Turn LED off
}

Edit:
To verify that my laptop is sending a MIDI message I am using this MIDI Monitor

how do you know that the PC is sending NoteOn events? ... please edit your question with a description of what you already tried

I doubt that the virtual keyboard sends serial messages to the com port


text:
Unexpected Behaviour w/ Arduino Uno Calculation
I have a really simple snippet of code wherein the same calculation outputs different values depending on how I do the calculation. The platform that I am running this code on is an Arduino Uno - with an Atmel MEGA328P microcontroller chip. Here's the code:
void setup() {

  Serial.begin(9600);
  unsigned long num = 100927;
  Serial.println(1000*60);
  Serial.println(num/(1000*60));
  Serial.println(num/(60000));
}

void loop() {}

This code prints the following on the console:
-> -5536
-> 0
-> 1

I don't understand why num/(1000*60) and num/(60000) evaluate to different values? Also, 1000*60 evaluates to a garbage value which looks like it somehow set the data type to int and resulted in overflowing the "int" range.
My programming background is heavy in Python. I figure I'm used to python dynamically interpreting variable data types for me which is why the arduino language confuses me a bit here. Any help is appreciated!

This is a pure C++ programming issue, which I cover on my web site.
However, since link-only answers are not allowed here, I reproduce that post below:

On the Arduino (Uno) platform, what do you think will be printed here?
void setup ()
  {
  Serial.begin (115200);
  Serial.println ();

  Serial.println (30000 + 30000); // twice 30000
  Serial.println (60 * 60 * 24);  // seconds in a day
  Serial.println (50 / 100 * 1000); // half of 1000
  }  // end of setup

void loop () { }

Did you guess:
60000
86400
500

Nope!
It prints:
-5536
20864
0

This is because of integer arithmetic. If the compiler can, it treats an numeric literal (like 60) as an int type, which means it has the range -32768 to +32767. This may be unexpected for users of modern compilers because nowadays an int is usually 32 bits. However on the 8-bit Arduino processors such as the Atmega328P the compiler treats an int as 16 bits wide. The C++ standard permits an int size of at least 16 bits, but you are not guaranteed that it will be larger.
And, arithmetic is done using the type of the largest argument, which means the arithmetic in each case is done as 16-bit arithmetic, and thus it overflows once it reaches 32767.
For example, 30000 + 30000 = 60000 which is 0xEA60 in hex. Unfortunately, 0xEA60 is exactly how -5536 is stored in an int type, which is why it prints -5536.
Meanwhile, 60 * 60 * 24 = 86400 which is 0x15180 in hex. As that doesn't fit in 16 bits, it is truncated to 0x5180 which is 20864 in decimal (as printed).
Finally, in integer arithmetic 50/100 is zero, multiply zero by 1000 and you still get zero, which is why the final result is zero.

So, can we "help" the compiler by telling it the sort of result we want, like this?
void setup ()
  {
  Serial.begin (115200);
  Serial.println ();

  long a = 30000 + 30000;
  long b = 60 * 60 * 24;
  float c = 50 / 100 * 1000;

  Serial.println (a);
  Serial.println (b);
  Serial.println (c);
  }  // end of setup

void loop () { }

That prints:
-5536
20864
0.00

So no, that hasn't helped.

Solution
First, you can add a suffix to numeric literals (eg. L for long, or UL for unsigned long), and add a decimal place to floats, like this:
void setup ()
  {
  Serial.begin (115200);
  Serial.println ();

  Serial.println (30000L + 30000); // twice 30000
  Serial.println (60L * 60 * 24);  // seconds in a day
  Serial.println (50.0 / 100 * 1000); // half of 1000
  }  // end of setup

void loop () { }

Now we get:
60000
86400
500.00

You only need to help out with the first literal, once the compiler knows we are using longs (or floats) it sticks with them for the expression. *
Or we can "cast" them:
void setup ()
  {
  Serial.begin (115200);
  Serial.println ();

  long a =  (long) 30000 + 30000;
  long b =  (long) 60 * 60 * 24;
  float c = (float) 50 / 100 * 1000;

  Serial.println (a);
  Serial.println (b);
  Serial.println (c);
  }  // end of setup

void loop () { }

Results:
60000
86400
500.00

Casting is useful for variables, because you can't just add "L" to the end of a variable name.
An alternative syntax is to use a constructor like this:
void setup ()
  {
  Serial.begin (115200);
  Serial.println ();

  long a =  long (30000) + 30000;
  long b =  long (60) * 60 * 24;
  float c = float (50) / 100 * 1000;

  Serial.println (a);
  Serial.println (b);
  Serial.println (c);
  }  // end of setup

void loop () { }

(Same results).

* It's actually somewhat more complex than that as this link explains: Understand integer conversion rules
The compiler "promotes" a value in an expression to match another "higher-ranked" type, under certain circumstances. For example, adding an int and a long will result in the int being promoted to a long (regardless of whether it appears first in the expression or not). However if an int is being added to another int, it will not promote them to a long, even though the result may not fit into an int.

More explanations
I was asked in the comments why 1000 * 60 is not the same as 60000 from the compiler's point of view.
The answer is that a compiler will treat an integer literal as an int (if possible) and an int on this platform is 16 bits.
Thus 1000 (an int) * 60 (another int) are multiplied using 16-bit arithmetic, giving a result that overflows.
However the literal, 60000, cannot be stored as an int and thus the compiler promotes it to long (aka "long int"). Since it has been promoted to a long it is correctly stored, and further operations on 60000 will be done with long arithmetic.
I have seen people code 60000 as 60000L however that is unnecessary. The compiler is not silly enough to make 60000 be stored as -5536, as that is clearly not the intent of the programmer.

I think the most important point is that sizeof(int) is 2 on the AVR platform, which is different from about every other current platform I know

Good point. Modern compilers make an int as 32 bits or even 64 bits. However because of space considerations on a microprocessor they chose to make the int be 16 bits wide. See int - Arduino reference

@PMF You seem to be young. I was socialized with CP/M and DOS, even Atari's TOS, and ints had 16 bits for ages. :-D With the dawn of 32 bit system, I found it irritating that an int became as large as a long. Lesson learned by me: Never assume a size, use the types of "stdint.h" or "cstdint" if I need a certain size.

@thebusybee That was mostly before my time, yes. But I also have started to use int32_t and it's siblings just to avoid pitfalls. Luckily, for modern languages such as C# and Java, the size of int is fixed in the specification.

Though this doesn't explain why (1000*60) is different from 60000. Now, I'm guessing the latter is taken as unsigned, so actually 60000, while the former overflows the range of a signed int and gives, um, -5536? (Plus that signed overflow is actually undefined.) The solution of explicitly casting the values to long of course works, but the explanation could be more to the point asked about

@ilkkachu Yeah it does. 1000*60 is evaluated in the domain of int. However 60000 must necessarily be promoted to a long. It would be ridiculous of the compiler to assume that every numeric literal was an int. It assumes they are the least type that will hold the literal (starting at int, not char).

Unfortunately the link I gave has gone link-dead, I'll try to find another.

Here it is - I'll amend my post.

@NickGammon, yes, that's exactly the explanation that appears to be missing from the answer itself.

@ilkkachu You said  Now, I'm guessing the latter is taken as unsigned, so actually 60000 - I'm not sure about the "unsigned" part. See the link I gave above which says in point 4 of "Usual arithmetic conversions":  If the type of the operand with signed integer type can represent all of the values of the type of the operand with unsigned integer type, the operand with unsigned integer type is converted to the type of the operand with signed integer type.  -- So it may instead be considered (signed) long.

@NickGammon, yeah, I had a vague recollection that there might be an intermediate step of unsigned somewhere. The list here seems to say it's only so for non-decimal bases though: https://en.cppreference.com/w/c/language/integer_constant so indeed it seems to be long in the case here, as you say

@ilkkachu That page seems strangely silent about a leading minus sign (which doesn't apply in this case) however it seems that for decimal literals they are generally considered signed.

Maybe a leading sign is considered a unary operator after the literal has been evaluated. Pages like the above are lengthy enough and still don't completely specify this sort of situation.

@NickGammon, yes, it's a constant+unary minus. It looks to be mentioned there under "Notes": "There are no negative integer constants. Expressions such as -1 apply the unary minus operator to the value represented by the constant."

That makes sense. :)


text:
Transmitting voice via VLC
The project I'm working on: Short-Range Coded Visible Light Communication System.
Visible Light Communication (VLC) systems use light to transfer data between transmitter and receiver over short-range links. This project intends to build a wireless VLC system capable of transmitting voice between two microcontrollers such as an Arduino or a Raspberry Pi using visible light.
An LED or laser diode is deployed at the transmitter side, and a Light Dependent Resistor (LDR) or photodiode is deployed at the receiving side.
Digital data is transmitted using on-off keying where the LED functions as on-off light. Strings of ones (1) and zeros (0) are transmitted with high frequency such that the LED flicking is undetectable to the human eye.
I'm using an Arduino Uno and this is the code that I used. I'm hearing noise from the speaker, not my voice.
Transmitter code:
// Define microphone pin
const int micPin = A0;

// Define LED pin
const int ledPin = 9;

// Define sampling frequency (in Hz)
const int samplingFrequency = 8000;

void setup() {
  // Set microphone pin as input
  pinMode(micPin, INPUT);

  // Set LED pin as output
  pinMode(ledPin, OUTPUT);

  // Begin serial communication at 9600 baud rate
  Serial.begin(9600);
}

void loop() {
  // Read analog voltage from microphone
  int analogValue = analogRead(micPin);

  // Map analog voltage to PWM duty cycle (0-255)
  int dutyCycle = map(analogValue, 0, 1023, 0, 255);

  // Set LED brightness based on duty cycle
  analogWrite(ledPin, dutyCycle);

  // Print duty cycle value to serial monitor
  Serial.println(dutyCycle);

  // Delay to maintain sampling frequency
  delay(1000 / samplingFrequency);
}

Receiver code:
const int ldrPin = 9;
const int speakerPin = 11;
int voiceSample;

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

void loop() {
  analogWrite(ldrPin, voiceSample);
  delay(10);
  voiceSample++;
  if (voiceSample > 255) {
    voiceSample = 0;
  }
  int voiceInput = analogRead(A0);
  voiceInput = map(voiceInput, 0, 1023, 0, 255);
  analogWrite(speakerPin, voiceInput);
}

The Serial.println(dutyCycle) in your transmitter is going to seriously slow down communications. It takes 1.04 ms to send a single byte over serial at 9600 baud, and assuming you have 3 digits, plus carriage return and linefeed that will take over 5 ms for each serial print.
However you are trying to sample at 8000 times a second (once per 125 µs) so you simply won't keep up. I suggest removing the serial print.

delay(1000 / samplingFrequency);

The delay function takes a long argument, not a float. 1000 / 8000 will evaluate to zero so the sample rate will not in fact be 8000 times a second.
You may want to consider the delayMicroseconds function.

Did you write this code or ChatGPT? ChatGPT questions are currently banned on Stack Overflow.  I'm not sure about their policy in regards to Arduino Stack Exchange.


text:
Implementing very slow external drive using ESP32 and TinyUSB
I want to implement a simple external drive with ESP32-S3 that would act like a normal USB enabled flash drive when connected to a computer.
The actual storage of the data is done mechanically (for educational purposes) and controlled via the esp pins. (the exact setup is not important now)
I am using the esp32TinyUSB library to implement the communication between the ESP and the Computer. However the problem is, that when I actually try to store the data using the mechanical system (which is very slow ~1 bit/s), the USB disconnects from the computer.
Is there a way to fix this issue? I don't know how exactly the USB and MSC protocol works but I am thinking some keep-alive messages?
Here is the setup() which is typical for this library:
void setup() {
  USB.onEvent(usbEventCallback);
  MSC.vendorID("myUSB");
  MSC.productID("myUSB");
  MSC.productRevision("1.0");
  MSC.onStartStop(onStartStop);
  MSC.onRead(onRead);
  MSC.onWrite(onWrite);
  MSC.mediaPresent(true);
  MSC.begin(DISK_SECTOR_COUNT, DISK_SECTOR_SIZE);
  USBSerial.begin();
  USB.begin();
}

and here is where the problem lies:
static int32_t onWrite(uint32_t lba, uint32_t offset, uint8_t* buffer, uint32_t bufsize){
  // this check is there to only use the mechanical system of storage for
  //one of the segments
  if (lba == 8) {
    for(int i = 0; i < bufsize; i++) {
      writeAt(offset + i, buffer[i]); // this function is slow and probably causing problems
    }
  } else {
    memcpy(msc_disk[lba] + offset, buffer, bufsize); // otherwise store in memory
  }
  return bufsize;
}

thank you in advance!
UPDATE:
I later found, that the reason for the drive disconnecting is probably the fact, that the esp32 is not dealing with the interrupts (events) as fast as they are coming from the USB (which is unfortunately unavoidable). This probably causes the ESP32 to be overwelmed with the events to the point that it crashes.
I will have to come up with a queue in memory that will be holding the waiting events. It seems like there is nothing like keep-alive messages on this layer - the Windows OS just waits patiently and displays the loading bar...


text:
How can I program an Arduino Pro Mini with an ESP8266-01 connected to its TX and RX?
I am working on a project that uses an Arduino Pro Mini to gather information from various sensor. Once the readings are taken I turn on an ESP-01 from a separate dedicated 3.3v power supply. The ESP-01 then sends the info to Adafruit.
This works fine. My problem lies in programming the Arduino Pro Mini. If I program it separately (without the ESP attached) using FTDI connected to my Mac using Arduino IDE everything goes great and program is successful.
If however I have the whole thing connected up on the PCB board where the TX on the Pro Mini is connected to RX on ESP-01 and the RX on Pro Mini to TX on ESP I can't get the program to upload. It just keeps trying to connect but can't even though it recognizes the board via the USB port.
Is there anyway to work around this without unsoldering things. I just want to tweak a bit of the programming on the Arduino Pro Mini. Not a big deal but I would be nice. I soldered a female header onto the end of the Pro Mini for programming.
I am enclosing a visual of the connection set up when I am trying to program Arduino Pro Mini.

Thanks in advance.

(a) Can you get access to pins 11,12 ,13 and Reset on the PCB mounted Promini and (b) have you another Arduino (or ICSP programmer)  available?

Pretty sure you can use OTA uploads to the pro mini via the attached ESP01. A bit of googling should confirm.

Pins 11, 12, and 13 are connected to other things on PCB mounted Pro Mini.  I do have other FTDI programmers and have tried different ones in different USB ports with no difference.  I don't know if the small update to the Pro Mini is that important that I want to go through the hassles of setting up OTA but that is an interesting idea.  Thanks.  Since it works with another Pro Mini connected up the same wayI think it has to do with maybe the header on the Pro Mini.  I'm going to try to remove it and resolder another one on.  Or maybe just live with what is programmed already.

You could try connecting a temporary jumper between the esp01 pin CH_PD and GND. Find a pinout diagram. It is one of the pins broken out on the 8 pin header. This is the "enable" pin of the esp01. Grounding it will have the effect of disabling the esp01 and may prevent it interfering with the attempt to upload code to the pro-mini. This would be less hassle than attempting an ICSP type upload. If this works, I'll add a formal answer to the question.


text:
What do I need for a plug?
I've manage to build myself an RFID music player which I'm pretty chuffed with. It's definitely a bit home made but it woks and I'm proud of it. I don't know what plug type to buy to sort my problem below:
As you can see from the second photo, my wiring is a big mess. I've wired up all the components on the lid (the RFID reader, three buttons, and a speaker) with 21 single plug wire connections. As you can clearly see from the photo, it's a dogs breakfast of wires. Worse, the wiring is fragile and connections can break when I open and close the box.
The fix, I think, is fairly simple: to wire up a multi-wire plug connection between the lid and the box. That is have all the wires from the lid feed into one side of a plug, and all the wires on the bottom feed into the other side of the plug. That way, I can bundle all the wires up and attach them neatly out of the way, with the only moving part being the large multi-wire plugs.
I would really like one plug (male and female) with at least 21 pins, or few smaller pinned plugs to clean everything up. I don't know what to search for - when I google search for plugs, wiring harness, connections, etc, I get a variety of plugs and wires that just don't seem quite what I'm looking for.
Ideally, I'd like to be able to set up the plug by just screwing in each of the bare tinned wire ends. That way, alls I have to do is cut each single wire plug off, strip back the wire, tin it, then screw it into the plug in the right spot. Do that 21 times for each side and hey presto: 2 neat plugs.
Can someone please let me know what plug type I need? Or any other helpful suggestions?

The reason there is unshrunk heat shrink wrap on the wires is that I thought shrink wrap would make the single wire plug connections a bit more permanent. I only actually shrunk the two loose connections, and decided against shrinking the rest lest it prevent me removing the connections should I need to.

please do not add explanations into a comment ... use the edit button and add it to your question ... anyway, your question is not about arduino

I would also suggest just using pin headers and female dupont connectors. You can get them with  like 2 rows of multiple contacts (as you need it). Thats the easiest for the typical 0.1" pitch and they are durable enough to hold for the limited number of times, that you need to disconnect them.

gentleman, sorry, I reopen the question. I think it is on topic here. It is too basic for EE SE. simple circuits and wiring a project around Arduino is 'Arduinoing'

You could have use say 4 long stand-off spacers and mounted the circuit board on the underside of the lid (as you have done with the RFID reader), possibly inverting it for easier access to the arduino usb socket and SD card, so the lid could be removed without stressing the wiring.
If you had used a printed circuit board then edge connectors would have been a possibility.
I suppose you could use 0.1" header pins on the circuit board and use DuPont or similar connectors.


text:
MPU9250 and MPU6050 not working with SAMD21 board
I am trying to use an MPU6050 with my SAMD21-based board (a LightAPRS W-2), but it doesn't work.
The sensor definitely works, as I can get data from another 3.3 Vlogic-level board, and the sensor works with a level shifter with an Arduino Uno.
I do not know what is wrong. My SAMD21 board I2C works fine with other devices, but both the MPU6050 and the MPU9250 don't work. Here is the code I use:
/***************************************************************************
* Example sketch for the MPU9250_WE library
*
* This sketch shows how to measure pitch and roll angles from the MPU9250.
* I have also included the corrected angle method for comparison.
*
* For further information visit my blog:
*
* https://wolles-elektronikkiste.de/mpu9250-9-achsen-sensormodul-teil-1  (German)
* https://wolles-elektronikkiste.de/en/mpu9250-9-axis-sensor-module-part-1  (English)
*
***************************************************************************/

#include <MPU9250_WE.h>
#include <Wire.h>
#define MPU9250_ADDR 0x68

/* There are several ways to create your MPU9250 object:
 * MPU9250_WE myMPU9250 = MPU9250_WE()              -> uses Wire / I2C Address = 0x68
 * MPU9250_WE myMPU9250 = MPU9250_WE(MPU9250_ADDR)  -> uses Wire / MPU9250_ADDR
 * MPU9250_WE myMPU9250 = MPU9250_WE(&wire2)        -> uses the TwoWire object wire2 / MPU9250_ADDR
 * MPU9250_WE myMPU9250 = MPU9250_WE(&wire2, MPU9250_ADDR) -> all together
 * Successfully tested with two I2C busses on an ESP32
 */
MPU9250_WE myMPU9250 = MPU9250_WE(MPU9250_ADDR);

void setup() {
  Serial.begin(115200);
  Wire.begin();
  if (!myMPU9250.init()) {
    Serial.println("MPU9250 does not respond");
  } else {
    Serial.println("MPU9250 is connected");
  }

  /* The slope of the curve of acceleration vs measured values fits quite well to the theoretical
   * values, e.g. 16384 units/g in the +/- 2g range. But the starting point, if you position the
   * MPU9250 flat, is not necessarily 0g/0g/1g for x/y/z. The autoOffset function measures offset
   * values. It assumes your MPU9250 is positioned flat with its x,y-plane. The more you deviate
   * from this, the less accurate will be your results.
   * The function also measures the offset of the gyroscope data. The gyroscope offset does not
   * depend on the positioning.
   * This function needs to be called at the beginning since it can overwrite your settings!
   */
  Serial.println("Position you MPU9250 flat and don't move it - calibrating...");
  delay(1000);
  myMPU9250.autoOffsets();
  Serial.println("Done!");

  /*  This is a more accurate method for calibration. You have to determine the minimum and maximum
   *  raw acceleration values of the axes determined in the range +/- 2 g.
   *  You call the function as follows: setAccOffsets(xMin,xMax,yMin,yMax,zMin,zMax);
   *  Use either autoOffset or setAccOffsets, not both.
   */
  //myMPU9250.setAccOffsets(-14240.0, 18220.0, -17280.0, 15590.0, -20930.0, 12080.0);

  /*  Sample rate divider divides the output rate of the gyroscope and accelerometer.
   *  Sample rate = Internal sample rate / (1 + divider)
   *  It can only be applied if the corresponding DLPF is enabled and 0<DLPF<7!
   *  Divider is a number 0...255
   */
  myMPU9250.setSampleRateDivider(5);

  /*  MPU9250_ACC_RANGE_2G      2 g    (default)
   *  MPU9250_ACC_RANGE_4G      4 g
   *  MPU9250_ACC_RANGE_8G      8 g
   *  MPU9250_ACC_RANGE_16G    16 g
   */
  myMPU9250.setAccRange(MPU9250_ACC_RANGE_2G);

  /*  Enable/disable the digital low pass filter for the accelerometer
   *  If disabled the bandwidth is 1.13 kHz, delay is 0.75 ms, output rate is 4 kHz
   */
  myMPU9250.enableAccDLPF(true);

  /*  Digital low pass filter (DLPF) for the accelerometer, if enabled
   *  MPU9250_DPLF_0, MPU9250_DPLF_2, ...... MPU9250_DPLF_7
   *   DLPF     Bandwidth [Hz]      Delay [ms]    Output rate [kHz]
   *     0           460               1.94           1
   *     1           184               5.80           1
   *     2            92               7.80           1
   *     3            41              11.80           1
   *     4            20              19.80           1
   *     5            10              35.70           1
   *     6             5              66.96           1
   *     7           460               1.94           1
   */
  myMPU9250.setAccDLPF(MPU9250_DLPF_6);
}

void loop() {
  xyzFloat angles = myMPU9250.getAngles();

/* This method provides quite precise values for x/y
   angles up 60°. */
  Serial.print("Angle x = ");
  Serial.print(angles.x);
  Serial.print("  |  Angle y = ");
  Serial.print(angles.y);
  Serial.print("  |  Angle z = ");
  Serial.println(angles.z);

/* Pitch and roll consider all axes for calculation. According to my experience
   it provides more reliable results at higher angles (>60°) */
  float pitch = myMPU9250.getPitch();
  float roll  = myMPU9250.getRoll();

  Serial.print("Pitch   = ");
  Serial.print(pitch);
  Serial.print("  |  Roll    = ");
  Serial.println(roll);
  Serial.println();

  delay(1000);
}

are you saying that nothing prints in the serial monitor?

@jsotola The serial monitor works fine, and it prints "MPU9250 does not respond"


text:
STM32 "black pill" won't enter DFU mode reliably
I'm following the standard process to put an STM32 "black pill" (STM32F401CC) into DFU mode so that I can upload from the Arduino IDE over USB:

Hold down boot0.
Press and release rst.
Release boot0.

When the board is not in a circuit this works somewhat reliably but not 100%. While breadboarding with only a few connections it becomes very unreliable and sometimes won't work at all.
The USB serial device set up by my Arduino sketch works fine, it is only DFU mode that does not want to work.
When it fails to enter DFU mode I see the following error in the Arduino upload process:
      -------------------------------------------------------------------
                        STM32CubeProgrammer v2.13.0
      -------------------------------------------------------------------

An error occurred while uploading the sketch
Error: Target device not found
Establishing connection with the device failed

I'm using Arduino on Ubuntu 20.04 and when it fails I see in /var/log/syslog:
Apr 27 13:26:08 smurfenaar kernel: [79594.279257] usb 1-3: USB disconnect, device number 10
Apr 27 13:26:08 smurfenaar kernel: [79595.078232] usb 1-3: new full-speed USB device number 11 using xhci_hcd
Apr 27 13:26:09 smurfenaar kernel: [79595.192387] usb 1-3: device descriptor read/64, error -71
Apr 27 13:26:09 smurfenaar kernel: [79595.413389] usb 1-3: device descriptor read/64, error -71
Apr 27 13:26:09 smurfenaar kernel: [79595.636370] usb 1-3: new full-speed USB device number 12 using xhci_hcd
Apr 27 13:26:09 smurfenaar kernel: [79595.751435] usb 1-3: device descriptor read/64, error -71
Apr 27 13:26:09 smurfenaar kernel: [79595.973367] usb 1-3: device descriptor read/64, error -71
Apr 27 13:26:09 smurfenaar kernel: [79596.082540] usb usb1-port3: attempt power cycle
Apr 27 13:26:10 smurfenaar kernel: [79596.462407] usb 1-3: new full-speed USB device number 13 using xhci_hcd
Apr 27 13:26:10 smurfenaar kernel: [79596.462674] usb 1-3: Device not responding to setup address.
Apr 27 13:26:10 smurfenaar kernel: [79596.666550] usb 1-3: Device not responding to setup address.
Apr 27 13:26:10 smurfenaar kernel: [79596.874414] usb 1-3: device not accepting address 13, error -71

When it is successful I see:
pr 27 13:22:33 smurfenaar kernel: [79379.772197] usb 1-3: new full-speed USB device number 9 using xhci_hcd
Apr 27 13:22:33 smurfenaar kernel: [79379.899601] usb 1-3: New USB device found, idVendor=0483, idProduct=df11, bcdDe
vice=22.00
Apr 27 13:22:33 smurfenaar kernel: [79379.899605] usb 1-3: New USB device strings: Mfr=1, Product=2, SerialNumber=3
Apr 27 13:22:33 smurfenaar kernel: [79379.899607] usb 1-3: Product: STM32  BOOTLOADER
Apr 27 13:22:33 smurfenaar kernel: [79379.899609] usb 1-3: Manufacturer: STMicroelectronics
Apr 27 13:22:33 smurfenaar kernel: [79379.899611] usb 1-3: SerialNumber: 3466365E3135

and I can also see it with the lsusb command:
Bus 001 Device 052: ID 0483:df11 STMicroelectronics STM Device in DFU Mode

I found this solution in the stm32duino forums:

Tying A10 to GND successfully makes it enter DFU bootloader mode 100% of the time (though just not leaving PA10 floating is probably sufficient)
Hypothesized Explanation: In the last paragraph of Sec 4.3 of AN2606 (the STM bootloader manual), it states:

It is recommended to keep the RX pins of unused bootloader interfaces (USART_RX, SPI_MOSI, CAN_RX and USB D+/D- lines if present) at a known (low or high) level at the startup of the bootloader (detection phase). Leaving these pins floating during the detection phase might lead to activating unused interfaces.

PA10 is the RX pin for USART_1. I believe that since PA10 is floating, the bootloader senses traffic on USART_1, and believes that's the interface it should use, and thus turns off USB. By tying PA10 to GND, the bootloader doesn't sense UART traffic and correctly enables USB.

While I followed the advice of tying it to ground I assume tying it to ground via a high resistance value would work too and should allow you to keep using PA10 for something else. After tying PA10 to GND I find entering DFU mode is 100% reliable, even when the board is in a circuit.

I recently purchased two "WeAct V3.0 STM32F411" Black Pill boards on eBay. I've purchased many boards & other electronic items from this seller in the past without any issues. This eBay seller is very highly rated: 99.8% positive feedback with >1 million items sold. However, I cannot confirm whether these boards are "genuine" WeAct boards since I did not purchase them directly from WeAct.
Both of my Black Pill boards can be programmed with ST-LINK V2 using the standard 3 (or 4) wire SWD interface pins. No problems.
However, both boards initially failed to enter USB DFU programming mode after resetting boards with the BOOT0 button pressed. Then I tried grounding pin A10 as suggested above. This totally fixed DFU programming. Now both boards program perfectly every time via DFU mode.
The only downside is the requirement to press BOOT0 + NRST buttons on board to initiate DFU programming mode prior to uploading with Arduino IDE.


text:
IR Receiver Remote Controller for Windows
My dad watches netflix on his pc with his wireless mouse, hes gotten older and cannot hit the volume slide well enough.
I have an arduino kit (ard nano), an IR recevier and remote controller laying around (all from the arduino kit).
I want to use the remote control when you press volume down on it to make the windows volume go down.
I tried using chatgpt but have gotten nowhere, what would be the best simplest solution for this.
I was thinking it would be an easy read-in of the data from the receiver but how would you transfer this data on to windows? Is this possible, I havent found many examples online
Thank you all :)

Are there some keyboard commands that you can enter on the PC instead of manipulating a scroll bar with the mouse ? If so, state what they are here and/or check yourself if an Arduino Leonardo or Arduino Micro (both ATMega32U4 based) is capable of issuing such commands.

get a wireless keyboard that has volume buttons ... remove the electronics and place them in a small box ... discard the keyboard matrix ...  add a couple of buttons, and connect them in place of the keyboard matrix ... you can use a scrap keyboard for this, since the buttons are not needed

There are USB / HID keyboard codes for volume.  Here we see volume up is 0x80 and volume down is 0x81.
Consider obtaining an Arduino board which is capable of supporting a USB / HID port so that you can easily emulate a keyboard.  It would be best to choose a board with hardware USB / HID support.  But it may be possible to emulate (limited?) USB / HID support using software only.
There are plenty of Arduino USB / HID project (here and here are just 2 examples).  This should get you started designing an Arduino sketch which can transmit a keyboard's volume up and down control codes into one of the computer's USB ports.
And there are plenty of Arduino ASK / IR receiver projects (here and here are just 2 examples).  As there are many IR remote control codes, this part of the project might take a bit of research to uncover the codes used in the IR remote control you posses.


text:
Program to Multiply Numbers Won't Actually Multiply Them
I am trying to write a program which takes in a number of pairs to be multiplied, then prints out the result of each multiplication. Instead of doing this, the program just prints out the number of multiplications and the numbers, but it never does the multiplications or add the newline characters (despite me explicitly using println). In the example below I specify 2 number pairs to multiply, and then enter 3,4,7,8 (entering a NL character after each number, but spaces and commas cause the same problem).

I thought my approach would work, but I believe that there is something I am doing with the serial input that is causing the code not work (although there could be some other issue). I also wonder if maybe it's because I'm running this in Tinkercad and not the real Arduino IDE. Any help would be greatly appreciated.
void loop()
 {
  int numOfMults = 0;                             // number of pairs to multiply
  float *numArray;                                // pointer to beginning of array memory block
  numArray = (float *)malloc(sizeof(float)*50);   // dynamically allocate an array that can hold up to 50 floats

  numOfMults = Serial.parseInt(); // take in the number of multiplications from user

  Serial.println(numOfMults);

  // take in the specified amount of numbers (2 times the num of multiplications) in format: 1,2,3...
  // then convert that into an array of floats, where every 2 indices
  // is a pair of numbers to multiply
  for (int i = 0; i < (2*numOfMults) ;i++)
    {
      numArray[i] = Serial.parseFloat();
    }
      multNums(numOfMults,numArray);  // call function to get the product of all the numbers

      delay(5000);                    // wait 5 seconds before starting the loop again
 }

void multNums(int numofNums,float nums[])
{
  float *productArray;                                 // pointer to beginning of the product array memory block
  productArray = (float *)malloc(sizeof(float)*25);    // dynamically allocate an array that can hold up to 25 floats (for the products)

  // multiply all the number pairs in the array, store the product in another
  for(int i=0;i<(2*numofNums);i+2)
  {
      productArray[i/2] = nums[i]*nums[i+1];         // multiply current number pair, store in the product array one index at a time
  }
  // print the products
  for(int i=0; i < sizeof(productArray) ;i++)
  {
    Serial.println(productArray[i]);
  }
}

for(int i=0; i < sizeof(productArray) ;i++) are you expecting that the sizeof()  a float pointer to be equivalent to the number of elements in the referenced array ?

@6v6gt that was a good catch, but even after changing it to explicitly be the number of products my output is still not right. I also am printing out the values I'm reading into the float array and they all appear to be there before I call the multiply numbers function.

Ok I figured it out.
In the for loop I had to use i +=2, and not i+2.
What a dumb mistake..

There are quite a few issues in this code:

In C++, you are supposed to do dynamic allocation with new rather
than malloc().

If you allocate dynamic memory in a loop and forget to free it (with
free()/delete), you will quite quickly run out of memory.

Actually, you do not even need to do any dynamic allocation at all:
automatic allocation is the safest way to handle these arrays.

Since you know the exact size you need, allocate that rather than a
default size.

multNums receives as a parameter the number of multiplications, not
the length of the array.

i+2 does not change the value of i. You meant i+=2.

sizeof(productArray) does not give the length of the array, but its
size in bytes. Besides, your last loop is supposed to iterate only
through the initialized part of the array.

If you fix those issues, the program should work as expected.

fixing all those things made the program work, the biggest problem was using i+2 instead of +=. And I will go back and do dynamic memory allocation in a better way or just get rid of it. I actually thought arduino was C (not c++), which is why i used malloc. New is much better.


text:
Pool pump man-in-the-middle SDA/SCL with ESP32
Hey all I have found some code on GitHub that works with my pool pump but it seems my model is a little newer than the one they used on on their GitHub. Most things seem to work but what doesn't is that the buttons on the control board do not seem to call out correctly to the main board.
The code for the buttons look to be this:
#define BUTTON_BOOST        0x44
#define BUTTON_TIMER        0x46
#define BUTTON_POWER        0x4C
#define BUTTON_LOCK         0x4E
#define BUTTON_SELF_CLEAN   0x74

The bulk of the data seems to be coming from void IRAM_ATTR Core1( void* p) {...
And perhaps within that is the button code?
if (sendingKeyCode) {
   if (totalBitsSent < 8) {
       digitalWrite(dataPin, (buttonStatus << totalBitsSent) & 0x80 ? HIGH : LOW);
       totalBitsSent++;
   }
   // FALLING edge 8 while sending keycode
   else if (totalBitsSent == 8) {
       // Receive ACK
       pinMode(dataPin, GPIO_MODE_INPUT);
       digitalWrite(dataPin, HIGH);
       totalBitsSent++;
   }
   // FALLING edge 9 while sending keycode
   else {
       sendingKeyCode = false;
       totalBitsSent = 0;
   }
}

I did the rest api call (http://192.168.1.173:8080/api/v1/intex/swg/status) and got this:
{
    "data": {
        "display": {
            "status": "ON",
            "brightness": 3,
            "current_code": "."
        },
        "status": {
            "power": "STANDBY",
            "boost": "OFF",
            "sleep": "OFF",
            "o3_generation": "OFF",
            "pump_low_flow": "OFF",
            "low_salt": "OFF",
            "high_salt": "OFF",
            "service": "OFF"
        },
        "mode": {
            "working": false,
            "programming": false
        }
    }
}

So I know it can communicate with it just fine. And I also did this debug rest api call (http://192.168.1.173:8080/api/v1/intex/swg/debug) and got this back:
{
    "data": {
        "powerStatus": "0x01",
        "statusDigit1": "0x00",
        "statusDigit2": "0x02",
        "statusDigit3": "0x00",
        "displayingDigit1": "0x00",
        "displayingDigit2": "0x02",
        "current_code": ".",
        "readBuffer": "[0X68, 0X00], [0X49, 0XFF], [0X48, 0X01], [0X6C, 0X00], [0X49, 0XFF], [0X48, 0X01], [0X6A, 0X02], [0X49, 0XFF], [0X48, 0X01], [0X68, 0X00], [0X49, 0XFF], [0X48, 0X01], [0X6C, 0X00], [0X49, 0XFF], [0X48, 0X01], [0X6A, 0X02], [0X49, 0XFF], [0X48, 0X01], [0X68, 0X00], [0X49, 0XFF], [0X48, 0X01], [0X6C, 0X00], [0X49, 0XFF], [0X48, 0X01], [0X6A, 0X02], [0X49, 0XFF], [0X48, 0X01], [0X68, 0X00], [0X49, 0XFF], [0X49, 0XFF], [0X48, 0X01], [0X6C, 0X00], [0X48, 0X01], [0X6A, 0X02], [0X49, 0XFF], [0X48, 0X01], [0X68, 0X00], [0X49, 0XFF], [0X48, 0X01], [0X6C, 0X00], [0X49, 0XFF], [0X48, 0X01], [0X6A, 0X02], [0X49, 0XFF], [0X48, 0X01], [0X68, 0X00], [0X49, 0XFF], [0X48, 0X01], [0X6C, 0X00], [0X49, 0XFF], [0X48, 0X01], [0X6A, 0X02], [0X49, 0XFF], [0X48, 0X01], [0X68, 0X00], [0X49, 0XFF], [0X48, 0X01], [0X6C, 0X00], [0X49, 0XFF], [0X48, 0X01], [0X6A, 0X02], [0X49, 0XFF], [0X48, 0X01], [0X68, 0X00], [0X49, 0XFF], [0X48, 0X01], [0X6C, 0X00], [0X49, 0XFF], [0X49, 0XFF], [0X48, 0X01], [0X6A, 0X02], [0X49, 0XFF], [0X48, 0X01], [0X68, 0X00], [0X49, 0XFF], [0X48, 0X01], [0X6C, 0X00], [0X49, 0XFF], [0X48, 0X01], [0X6A, 0X02], [0X49, 0XFF], [0X48, 0X01], [0X68, 0X00], [0X49, 0XFF], [0X48, 0X01], [0X6C, 0X00], [0X49, 0XFF], [0X48, 0X01], [0X6A, 0X02], [0X49, 0XFF], [0X48, 0X01], [0X68, 0X00], [0X49, 0XFF], [0X48, 0X01], [0X6C, 0X00], [0X49, 0XFF], [0X48, 0X01], [0X6A, 0X02], [0X49, 0XFF], [0X48, 0X01], [0X68, 0X00], [0X49, 0XFF], [0X48, 0X01], [0X6C, 0X00], [0X49, 0XFF], [0X48, 0X01], [0X6A, 0X02], [0X49, 0XFF], [0X48, 0X01], [0X68, 0X00], [0X49, 0XFF], [0X48, 0X01], [0X6C, 0X00], [0X49, 0XFF], [0X49, 0XFF], [0X48, 0X01], [0X6A, 0X02], [0X48, 0X01], [0X68, 0X00], [0X49, 0XFF], [0X48, 0X01], [0X6C, 0X00], [0X49, 0XFF], [0X48, 0X01], [0X6A, 0X02], [0X49, 0XFF], [0X48, 0X01], [0X00, 0X00]",
        "compilation_date": "Apr 27 2023",
        "compilation_time": "16:20:36",
        "otaUpdating": false,
        "removeWifiConfig": false,
        "machineON": true,
        "wifiReconnecting": false,
        "readingMaster": true,
        "sendingKeyCode": false
    }
}

Would be great if someone more knowledgeable at binary and SDA/SCL would help me find my buttons binary code so that I can send that code to the pool pumps main controller.
The GitHub> https://github.com/jingsno/intex-swg-iot

do not seem to call out correctly ... they either do, or do not ... there is no seem to ... print the button code that is received and adjust your code to respond to the code that is received


text:
Why is my Arduino is getting power from the 5V pin?
I have an Arduino that is controlling two 6V DC motors through a L298N motor driver. The motor driver is being powered (from its Vin pin) by a 7.4V external source.
I then have the 5V pin from the motor driver connected to the 5V pin on an Arduino UNO to power the logic board.
Now, when I plugged in my Arduino to my computer to upload the sketch, everything was fine. However, when I unplugged the Arduino from the laptop, the Arduino was still being powered somehow from the 7.4V external source, though that source should only be powering the motors. I thought that unplugging the Arduino from the laptop would have cut power to the Arduino, but it was still somehow being powered by the external source.
What is going on here?

What is going on here? ... we can only guess ... you provided almost zero information ... please draw a clear diagram of all of the connections

@jsotola I added a diagram.

How about a schematic the frizzy picture does not help me much as I do not recognize the motor board.

It could be that this driver board is designes to supply (rather than consume) power through its 5V pin. Do you have a reference to this board?

What @EdgarBonet said is the most plausible scenario. It appears that at least some L298 modules have a jumper selectable 5 volt regulator which can be used to supply the 5 volt logic side of the L298 chip but only if the motor side voltage is less than 12 volts. If the motor voltage exceeds 12 volts, the jumper must be removed and the L298 module 5 volts must be supplied from the MCU board. See the example here: http://wiki.sunfounder.cc/index.php?title=Motor_Driver_Module-L298N . TL;DR ? understand and check the module jumpers.

@EdgarBonet its an Elegoo Uno R3

The Arduino Uno can be powered from the 5 volts present on the USB cable or from an external 5 volts connected to the Arduino's 5V and GND (ground) pins.
In general, power supply outputs should never be connected in parallel unless they are designed for such an unusual configuration. From the description in the Question, it appears the USB power and the L289N power supplies were connected in parallel. Fortunately, the Arduino design include a power cut off shich.  Look for part "T1" in this schmatic.  If power is applied from both the 5V pin and the USB port, the 5V pin is used and the USB power is cut off.
To answer your question specifically:

Assuming this is your board's schematic (note, this is a link to an RAR file which contains a JPG of what is likely the wb291111 board's schematic) and assuming you have J6 jumper installed.

If the Arduino 5V and GND (ground) pins were connected to the L289N board and the L289N board was supplying 5V power to the Arduino board, the Arduino board was never powered from the computer's USB port as transistor "T1" would have disconnected the USB power from the Arduino.

Is there another configuration to send 5V to the motor driver logic board? The plan was to have a separate 5V power supply for the Arduino, and have the Arduino send power to the logic board on the motor driver. The 7.4V external source is only to power the motors.

It looks like disconnecting J6 will remove the source of power of the motor driver board's 5V regulator.  Test this (the "disconnected" 5V pin of the motor driver board) with a volt meter ... as the schematic is a bit hard to read (doesn't look correctly labeled).  But why use 2 power supplies if you can get away with only 1 (the motor driver board power supply)?


text:
How to show repeated result on LCD while button is pressing
my results are here.
0 press--"a"
1st press--"b"
2nd press--"c"
3rd press-- still showing "c"
When button pressed 3rd time, It must be repeated to show "a" again. How can I repeat above 3 results to LCD?
#include <LiquidCrystal.h>
#include <ezButton.h>
ezButton button(7);
int count;
int count1;
const float rs = 1, en = 2, d4 = 3, d5 = 4, d6 = 5, d7 = 6;
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);
void setup() {
  button.setDebounceTime(50); // set debounce time to 50 milliseconds
  button.setCountMode(COUNT_FALLING);
  lcd.begin(16, 1);
}
void loop() {
  int count = button.getCount();
  button.loop();
  count1 = constrain(count, 0, 2);
  if(count1 == 0){
  lcd.print("a");
  }
  if(count1 == 1){
  lcd.print("b");
  }
  if(count1 == 2){
  lcd.print("c");
  }
  delay(500);
  lcd.clear();
}

investigate the remainder operator %

use button.resetCount();

The ezButton counter will keep counting up every time you release the button. count will be 3, then 4, 5, etc. But constrain will keep count1 stuck at 2. You could use button.resetCount(); when you print c to start over. Or use count1 = count % 3 like jsotola suggested.


text:
A9G GSM not connecting to teensy 4.0
Below is my current code for connecting to the A9G. As far as I can tell, it never actually opens a connection as HWSERIAL.println("AT"); does not return anything. Any ideas would be appreciated.
The TX and RX pins of the A9G connected to the 0 and 1 pins on the teensy
    #include <SoftwareSerial.h>

    #define HWSERIAL Serial1

    void setup()
    {
      //Begin serial communication with Arduino and Arduino IDE (Serial Monitor)
      Serial.begin(115200);

      //Begin serial communication with Arduino and A6
      HWSERIAL.begin(115200);

      Serial.println("Initializing...");
      delay(1000);

      HWSERIAL.println("AT"); //Once the handshake test is successful, it will back to OK
      updateSerial();
    }

    void loop()
    {
      updateSerial();
    }

    void updateSerial()
    {
      delay(500);
      while (Serial.available())
      {
        HWSERIAL.write(Serial.read());//Forward what Serial received to Software Serial Port
      }
      while(HWSERIAL.available())
      {
        Serial.write(HWSERIAL.read());//Forward what Software Serial received to Serial Port
      }
    }

you said nothing about the connections, so there may be none

I've got the TX and RX pins of the A9G connected to the 0 and 1 pins on the teensy

What voltage did you use to power the A9G module? Most GSM modules need something higher than 3.5V for their radio stage. Doublecheck the module datasheet.

@ChrisH its running on 5v


text:
My esp01 code keeps on erasing after reboot
I am uploading a simple Blynk cloud example code to control a led on GPIO2 of my esp01 board.
#define BLYNK_TEMPLATE_ID ""
#define BLYNK_DEVICE_NAME ""

#define BLYNK_FIRMWARE_VERSION        "0.1.0"

#define BLYNK_PRINT Serial
//#define BLYNK_DEBUG

#define APP_DEBUG

// Uncomment your board, or configure a custom board in Settings.h
//#define USE_SPARKFUN_BLYNK_BOARD
//#define USE_NODE_MCU_BOARD
//#define USE_WITTY_CLOUD_BOARD
//#define USE_WEMOS_D1_MINI

#include "BlynkEdgent.h"

BLYNK_WRITE(V0)
{
 int pinValue = param.asInt();
  Serial.println("Value Change");
  digitalWrite(2,pinValue);
}
void setup()
{
  pinMode(2,OUTPUT);
  Serial.begin(115200);
  delay(100);

  BlynkEdgent.begin();
}

void loop() {
  BlynkEdgent.run();
}

when I run it for the first time it works flawlessly, it gets configured easily with Blynk app and i am able to control the led.
but, when I reboot my esp01 it does not store the credentials and again starts the code from beginning!!
I think I am not able to get out of programming mode.
Please help me out !!
Thanks

try to add WiFi.persistent(); and WiFi.setAutoConnect();. it was the default until esp8266 Arduino version 3, but now both are off by default

@Juraj but it works fine for my nodemcu? So do you think it is the real prob?


text:
ESP32-CAM not sending base64 string as HTTP post request
in my recent project, I'm trying to detect motion and capture an image using the esp32 cam module and send it to the server via HTTP.
Once the image is captured it is converted to a base64 string and while trying to send the data at the server the body of the HTTP request is empty i.e., the base64 string is not sent.
Code that sends the image
void sendPic(String data, String len) {

    if(WiFi.status() == WL_CONNECTED) {

      HTTPClient http;

      http.begin("http://192.168.1.35:8000/capture");

      String d = data ;

      int res_c = http.POST(d);

      if(res_c > 0){
        Serial.println(res_c);
      }
      else{
        Serial.println("Not sent");
        Serial.print(res_c);
      }
      http.end();
    }
}

Entire code
// turn on debug messages
#define VERBOSE
#include "Arduino.h"
#include <base64.h>
#include <esp_wifi.h>
#include <HTTPClient.h>
#include "EloquentSurveillance.h"

const char* ssid = "****";
const char* password = "********";

void sendPic(String data, String len) {

    if(WiFi.status() == WL_CONNECTED)

      HTTPClient http;

      http.begin("http://192.168.1.35:8000/capture");

      String d = data ;

      int res_c = http.POST(d);

      if(res_c > 0){
        Serial.println(res_c);
      }
      else{
        Serial.println("Not sent");
        Serial.print(res_c);
      }
      http.end();

    }
}

/**
 * Instantiate motion detector
 */
EloquentSurveillance::Motion motion;

/**
 *
 */
void setup() {
    Serial.begin(115200);

    WiFi.begin(ssid, password);
    Serial.println("Connecting");
    while(WiFi.status() != WL_CONNECTED) {
      delay(500);
      Serial.print(".");
    }
    Serial.println("");
    Serial.print("Connected to WiFi network with IP Address: ");
    Serial.println(WiFi.localIP());

    if(WiFi.status() == WL_CONNECTED) {
      HTTPClient http;
      int res_c = -1;
      while(res_c < 0){
        http.begin("http://192.168.1.35:8080/capture");
        http.addHeader("Content-Type", "text/plain");
        String test = "hello from esp32";
        res_c = http.POST(test);

        if(res_c > 0){
          Serial.println(res_c);
        }
        else{
          Serial.println(res_c);
        }
        http.end();
      }

    }

    delay(3000);
    debug("INFO", "Init");

    /**
     * See CameraCaptureExample for more details
     */

    camera.aithinker();
    camera.vga();
    camera.bestQuality();

    /**
     * Configure motion detection
     *
     * > setMinChanges() accepts a number from 0 to 1 (percent) or an integer
     *   At least the given number of pixels must change from one frame to the next
     *   to trigger the motion.
     *   The following line translates to "Trigger motion if at least 10% of the pixels
     *   in the image changed value"
     */
    //motion.setMinChanges(0.015);
    motion.setMinChanges(0.02);

    /**
     * > setMinPixelDiff() accepts an integer
     *   Each pixel value must differ at least of the given amount from one frame to the next
     *   to be considered as different.
     *   The following line translates to "Consider a pixel as changed if its value increased
     *   or decreased by 10 (out of 255)"
     */
    motion.setMinPixelDiff(5);

    /**
     * > setMinSizeDiff() accepts a number from 0 to 1 (percent) or an integer
     *   To speed up the detection, you can exit early if the image size is almost the same.
     *   This is an heuristic that says: "If two consecutive frames have a similar size, they
     *   probably have the same contents". This is by no means guaranteed, but can dramatically
     *   reduce the computation cost.
     *   The following line translates to "Check for motion if the filesize of the current image
     *   differs by more than 5% from the previous".
     *
     *   If you don't feel like this heuristic works for you, delete this line.
     */
    //motion.setMinSizeDiff(0.015);
    motion.setMinSizeDiff(0.02);

    /**
     * Initialize the camera
     * If something goes wrong, print the error message
     */
    while (!camera.begin())
        debug("ERROR", camera.getErrorMessage());

    debug("SUCCESS", "Camera OK");
}

/**
 *
 */
void loop() {
    /**
     * Try to capture a frame
     * If something goes wrong, print the error message
     */
    if (!camera.capture()) {
        debug("ERROR", camera.getErrorMessage());
        return;
    }

    /**
     * Look for motion.
     * In the `true` branch, you can handle a motion event.
     * For the moment, just print the processing time for motion detection.
     */
    if (!motion.update())
        return;

    if (motion.detect()) {
        debug("INFO", String("Motion detected in ") + motion.getExecutionTimeInMicros() + " us");
        String encoded = base64::encode(camera.getBuffer(), camera.getFileSize());
        int size = camera.getFileSize() + 50;
        sendPic(encoded, (String)size);
        delay(4000);
    }
    else if (!motion.isOk()) {
        /**
         * Something went wrong.
         * This part requires proper handling if you want to integrate it in your project
         * because you can reach this point for a number of reason.
         * For the moment, just print the error message
         */
        debug("ERROR", motion.getErrorMessage());
    }
}

I'm a beginner in using esp32 cam any guidance on how to achieve the objective will be helpful. Thanks in advance!

ESP32-CAM not sending base64 string as HTTP post request  ... what is it sending? ... how is it sending it?

Hi @jsotola the request is received at the server when I print the request in the console it contains only the headers and the body is empty. I checked it with wireshark as well.

Have you checked it before it's sent? Try outputting the body in your code everywhere you pass it through the code - like right after the data is encoded and just before it's posted. Also there's absolutely no need to do  String d = data ;, all that's doing is making an extra unneeded copy of the data, which given the limited memory on the ESP32 is not great.

Hi @romkey I actually did print the encoded data before it was sent and the string was printed. And I just added the line because while debugging I tried adding a prefix to see whether it went through but no either way.


text:
Arduino Nano 33 BLE power consumption optimization
I am working on building a sensor using Arduino Nano 33 BLE that will measure temperature using two thermistors and angle changes. The measured values will be transmitted over Bluetooth to a smartphone every minute. I have written the code for temperature and angle measurements, as well as remote data transfer. However, I need this sensor to operate for 10 to 21 days on a 3.7v 250mAH battery. To achieve this, I planned to use the Arduino low-power library.
Unfortunately, I have not been able to find a library that is compatible with this Arduino board, nor have I found an example of how to put the board into sleep mode and then measure values every minute. I am aware of the option to power the board directly from a 3.3v source by cutting the 3.3V pads on the back of the board, disabling the power indication diode and turning off the sensors/the I2C pull-up resistors.
I would appreciate any suggestions or solutions to this problem. The full code of the sketch  is below:
#include <ArduinoBLE.h>
#include <Arduino_LSM9DS1.h>
//These  values are in the datasheet
#define RT0 100000   // Ω
#define B 4600      //  K
//--------------------------------------
#define VCC 3.3    //Supply  voltage
#define R 100000  //R=100KΩ

//Variables
float RT, VR, ln, TX0, TX1,  T0, VRT1, VRT0;
unsigned long last_time;
float x, y, z,angleX,angleY;

// Define the BLE service and characteristic
BLEService greetingService("180C");
BLEStringCharacteristic greetingCharacteristic("2A56", BLERead | BLENotify, 30);

void setup() {
  // Initialize BLE
  BLE.begin();

  // Set up the service and characteristic
  greetingCharacteristic.setValue("Hi");
  greetingService.addCharacteristic(greetingCharacteristic);
  BLE.addService(greetingService);

  // Start advertising the service
  BLE.advertise();
  Serial.begin(9600);
  T0 = 25 + 273.15;

  if (!IMU.begin()) {
    Serial.println("Failed to initialize IMU!");
    while (1);
  }

  Serial.print("Accelerometer sample rate = ");
  Serial.print(IMU.accelerationSampleRate());
  Serial.println("Hz");
   // Set the initial rotation angles to 0
  angleX = 0;
  angleY = 0;
}

void loop() {

  if (millis()-60000>last_time){
  last_time=millis();
  VRT0 = analogRead(A0);              //Acquisition analog value of VRT
  Serial.println(analogRead(A0));
  VRT0  = (3.30 / 1023.00) * VRT0;      //Conversion to voltage
  VR = VCC - VRT0;
  RT = VRT0 / (VR / R);               //Resistance of RT
  ln = log(RT / RT0);
  TX0 = (1 / ((ln / B) + (1 / T0))); //Temperature from thermistor
  TX0 =  TX0 - 273.15;                 //Conversion to Celsius
  Serial.print("Temperature1:");
  Serial.print("\   ");
  Serial.print(TX0);
  Serial.println("\ C");
  VRT1 = analogRead(A1);              //Acquisition analog value of VRT
  Serial.println(analogRead(A1));
  VRT1  = (3.30 / 1023.00) * VRT1;      //Conversion to voltage
  VR = VCC - VRT1;
  RT = VRT1 / (VR / R);               //Resistance of RT
  ln = log(RT / RT0);
  TX1 = (1 / ((ln / B) + (1 / T0))); //Temperature from thermistor
  TX1 =  TX1 - 273.15;                 //Conversion to Celsius
  Serial.print("Temperature2:");
  Serial.print("\   ");
  Serial.print(TX1);
  Serial.println("\ C");

  IMU.readAcceleration(x, y, z);
    Serial.print("x=");
    Serial.print(x);
    Serial.print("y=");
    Serial.print(y);
    Serial.print("z=");
    Serial.print(z);

    // Calculate the rotation angles using the atan2 function
    angleX = atan2(y, z) * 180 / PI;
    angleY = atan2(x, sqrt(y * y + z * z)) * 180 / PI;

    // Map the rotation angles to the range [0, 360]
    angleX = fmod(angleX + 360, 360);
    angleY = fmod(angleY + 360, 360);

  // Print the rotation angles
  Serial.print("Rotation X: ");
  Serial.print(angleX);
  Serial.print(" degrees, Rotation Y: ");
  Serial.print(angleY);
  Serial.println(" degrees");

  BLEDevice central = BLE.central();
  if (central) {
    // Send the value of x to the connected device
    String message = String(TX0)+"/"+String(TX1)+"/"+String(angleX)+"/"+String(angleY);
    greetingCharacteristic.writeValue(message);
   }
  }
}


text:
Pro Micro Double Reset help; Not able to get upload done in 8 seconds
I have timed the double reset as best as possible multiple times but the upload doesn't happen before the board leaves bootloader mode.
this is all I'm given as an error which doesn't appear until after the board leaves bootloader mode  (after the 8 seconds)
The one thing that I haven't been able to find info on is the fact that I do not have a SparkFun version, I have a non branded from ebay if that makes any difference
How can I fix?
Sketch uses 3460 bytes (12%) of program storage space. Maximum is 28672 bytes. Global variables
 use 149 bytes (5%) of dynamic memory, leaving 2411 bytes for local variables. Maximum is 2560 bytes.

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

Failed uploading: uploading error: exit status 1

Remove the power to the board
Hold down reset while you power it up.
Release reset when the IDE says that it is uploading.

but there will be no COM port if the 32u4 is in reset state

@Juraj - It will appear once it leaves reset. The IDE keeps checking for the COM port, I believe.

Yeah I know about the bootloader COM port and set that up. I've been able to connect the board during reset. Just not been able to upload some dummy code with the correct processor speed before it disconnects.       I'll try the holding down process tonight


text:
Running a 5V, 4pin pwm fan with Mega2560
I have a Mega2560 and would like to use it to power a single fan and display. The fan is a 5V fan that draws 260mA and I can't find power specs for this display. I can't find a clear answer for how much current I can safely draw off of the 5V pins on this board. Does anyone know if I'll be able to run these devices off of my Mega2560?
Board: https://www.amazon.ca/dp/B01H4ZLZLQ
Display: https://www.amazon.ca/gp/product/B085NHM5TC/
Fan: https://www.amazon.ca/dp/B07DXR1Y73/

yes, the manufacturer knows ... read their datasheet

Your board has an AMS1117 voltage regulator, google the part number for its datasheet. For display, even you can't find the data, you can measure it easily by turning on all the display segments.

Your board has an AMS1117 voltage regulator, google the part number for its datasheet. For display, even you can't find the data, you can measure it easily by turning on all the display segments.


text:
Help with program upload problem
I'm going to upload some code to my LeArm using an Arduino board. I connected the RX and TX pins of the LeArm to the Arduino, but I got an error message when I tried to upload the code.
I'm not sure if I made the connections correctly. Does anyone have any tips on how to upload the programs successfully?

Diagrams and actual code or error messages rather than photos of them, will help a great deal. If you update your question, please edit the question itself rather than adding comments. But from what I can read of the error messages (board not replying), either: the IDE has not got the right port selected, it has not got the correct board-type selected, the connections to your board are incorrect, or the board doesn't have the correct (or any) bootloader. That's about all I can get from what you've provided. But check out those 4 things thoroughly; one of them is the cause of your failure.

Thank you so much!

Is the Arduino Mega you have a "Chinese" version? If it is, try installing these drivers and try again.


text:
esp8266 r1 mini stops serial print during execution
The setup includes an WEMOS/ESP8266 R1 mini compatible board, a DHT11, a photo resistor and a magnetic reed.
The libs used are:
#include <ESP8266WiFi.h>
#include <PubSubClient.h>
#include <ArduinoJson.h>
#include "DHT.h"

Compilation/loading is successful and the code starts normally, publishes and subscribes correctly.
Executable segment sizes:
ICACHE : 32768           - flash instruction cache
IROM   : 259412          - code in flash         (default or ICACHE_FLASH_ATTR)
IRAM   : 27337   / 32768 - code in IRAM          (IRAM_ATTR, ISRs...)
DATA   : 1524  )         - initialized variables (global, static) in RAM/HEAP
RODATA : 2300  ) / 81920 - constants             (global, static) in RAM/HEAP
BSS    : 26416 )         - zeroed variables      (global, static) in RAM/HEAP
Sketch uses 290573 bytes (27%) of program storage space. Maximum is 1044464 bytes.
Global variables use 30240 bytes (36%) of dynamic memory, leaving 51680 bytes for local variables. Maximum is 81920 bytes.
esptool.py v3.0
Serial port /dev/ttyUSB0
Connecting....
Chip is ESP8266EX
Features: WiFi
Crystal is 26MHz
MAC: 5c:cf:7f:ad:11:6b
Uploading stub...
Running stub...
Stub running...
Changing baud rate to 460800
Changed.
Configuring flash size...
Auto-detected Flash size: 4MB
Compressed 294720 bytes to 215795...
..

However the serial printing commands (ie Serial.println) in the code stop working for no apparent reason. The code/module is working, it is not dead.
I suspected json serialization but various changes that I tried didn't solve it. Then I thought that the dht lib is responsible, because serial printing stops in the dht function routine. But the adafruit stand alone examples work alright.
Here is the initial printing until it stops:
WiFi connected.
IP address:
192.168.xx.xx
ESP Mac Address: xx:xx:xx:xx:xx:xx
Subnet Mask: 255.255.255.0
Gateway IP: 192.168.xx.xx
DNS: 192.168.xx.xx
RRSI: -84
mqtt status in setup: 0
Humidity: 34.00% || Temperature: 24.00°C
before ser

This is the code function that requests dht data:

StaticJsonDocument<128> doc_dht;

void request_temp_hum() {
  float h = dht.readHumidity();
  float t = dht.readTemperature();
  char  h_ch[10];
  char  t_ch[10];
  char buffer[256];
  doc_dht.clear();
  memset (h_ch, 0, sizeof(h_ch));
  memset (t_ch, 0, sizeof(t_ch));
  if (isnan(h) || isnan(t)) {
        Serial.println("Failed to read from the DHT sensor, check wiring.");
        return;
  }
  Serial.print("Humidity: ");
  Serial.print(h);
  //Print out the Temperature
  Serial.print("% || Temperature: ");
  Serial.print(t);
  Serial.println("°C ");

  dtostrf(t, 5, 2, t_ch);

  dtostrf(h, 5, 2, h_ch);

  doc_dht["sensor"] = "dht11";
  doc_dht["temp"] = t_ch;
  doc_dht["humi"] = h_ch;

  Serial.println("before serialization");
  serializeJson(doc_dht, buffer);
  Serial.println("after serialization..");
  client.publish("Home/info/dht", buffer);
  Serial.println("after publish");
  }

This is the mqtt publishes from the device:
02.05.2023 13:11:31 Home/info/dht {"sensor":"dht11","temp":"24.00","humi":"34.00"}
...
02.05.2023 13:26:38 Home/info/dht {"sensor":"dht11","temp":"25.00","humi":"34.00"}

Apart from the fact that I can't debug my code any further, it is evident that something is wrong and it might have further implications that I can't foresee. So why does serial printing stop working?

You can call Serial.flush() after each println() to make sure the log is sent before moving to the next line.

Thank you for the suggestion, I used Serial.flush() is various points in the program and I was able  to move on and further debug. The issue must be the fact that I used GPIO1 (TX) for controlling a relay module.


text:
Program SMT32 black-pill without pushing buttons or propriatary devices
Are there any options for programming an STM32 black-pill from the Arduino IDE without first having to manually push buttons to go into DFU mode or having to buy an ST-Link device?
A solution that leverages a second micro-controller board (I have Arduino Nanos, Pi Picos and ESP32 boards available) or requires some (easy) soldering would be fine.

something like Nucleo F303k8 - it has on board stlink and it also emulates hard drive, so you just drag and drop the binary file (or elf, i don't remember)

Your question is one I was recently interested in as I too have begun using Blue/Black Pills, and I am still learning!

Have you got your Arduino IDE set up, and have you added the plugin for the STM32 boards? If not then you can find a tutorial in many places on the internet, one example being on youtube, if you prefer video tutorials...
https://www.youtube.com/watch?v=b1123kz_3MM
Some are better than others and I prefer a written instruction, with or without pics!
Essentially you have to add:-
https://github.com/stm32duino/BoardManagerFiles/raw/master/STM32/package_stm_index.json
to your list or boards in the preferences. Many Tutorials will explain in detail.

Programming options include:

STLink-v2.1 etc. The STLink-v2.1 is easy to source, cheap, and after it is eventually replaced by something else you can even repurpose it as if it is a STM32 USB stick!
FTDI USB to TTL breakout adapter, 3.3v only, connected to the SWD pins on the opposite end to the USB socket.
An Arduino board acting as a TTL/SWD adapter but already kind (talking) to Arduino!
Burning an STM32-Arduino boot-loader onto the blue/black pill, and plug it in like an Arduino, using tutorials.
Install STM32CubeProg, on your host computer, which is free and a very good IDE.
NO DOUBT a search engine (of traditional values!) can find other options including JTAG, JLink, Bus-Pirate, etc. (Avoid search engines that send you straight to selling sites!)

All of these need to be searched, read and understood before a logical choice is made, but all of them are usable choices. Every reader will know that you will get user advice insisting that you do what they have done, or worse, warning you to avoid methods that others have used successfully. Caveat Emptor!

Follow the easiest path to begin with, one of those that are given in the Arduino site perhaps, and investigate others when you have found what you want the process to do, and which process suits your methods and budget. Much depends on memory needs and applications.

you don't answer the question. the question is how to program it over UART without manually setting the BOOT pin


text:
Problem with some sensors but not with servos
I use a lot Arduino Uno, but in this case, I have some BQ ZUM BT-328 boards, which are based on Arduino BT. The problem with some of BQ ZUM BT-328 boards is that the ultrasonic sensor (HC-SR04) is not working in any pin. However, apparantely, the boards work and the 2 servos (SM-S4306R) work fine too. When I change the ultrasonic sensor to other pins and with other wires, it is not working yet. However, I use that sensor in another different BQ ZUM BT-328 board and it is working fine, and if I add the same setup (2 SM-S4306R) and same code, it continues working fine. Then, the problem is just in some boards, not in everyone.
The ultrasonic example is:
long distance;
long responseTime;

int pinTrig = 9;
int pinEcho = 8;

void setup(){
  Serial.begin(9600);
  pinMode(pinTrig, OUTPUT);
  pinMode(pinEcho, INPUT);
}

void loop(){
  digitalWrite(pinTrig, LOW);
  delayMicroseconds(5);

  digitalWrite(pinTrig, HIGH);
  delayMicroseconds(10);
  responseTime = pulseIn(pinEcho, HIGH);
  Serial.println("Tiempo "+ String(responseTime)+" microsegundos");

  distance = int(0.01716*responseTime);

  Serial.println("Distancia "+ String(distance)+"cm");
  delay(500);
}

Then, I suppose that those BQ ZUM BT-328 boards have some problem and maybe they are starting to fail. I say this, because the same problem works in some boards and in others fails. In those board in which it fails I checked the correct connection of pins (GND, VCC, digitals), change the pin and the wires without result. However, the servos continue to work fine and I can upload the code to the board. My questions are:
Am I correct and they are failing?
Why they are just failing with that sensor and not the SM-S4306R? I mean, maybe some specific component of the board is failing?

the questions are not answerable because your description lacks detail

Which more details do you need? I can add more or test more the board. Just tell me.

include information about the board, the sensors, the connection diagram and minimal program that shows the failure

I have added a reference to the datasheet of the board, the sensor, and the motor. I have explain better the mistakes, and added the code example.

Looks like in your sample code you did not complete the 10us pulse.
  digitalWrite(pinTrig, LOW);
  delayMicroseconds(5);

  digitalWrite(pinTrig, HIGH);
  delayMicroseconds(10);
  digitalWrite(pinTrig, LOW); // you missed this

See example.

Thank you so much for your answer. I tried in all boards adding that line, but the result is the same. The boards which was failing continue failing.