text:
Connecting Common-Anode Seven Segment Display to Shift Register
I recently wired up the following ill-advised circuit:
A common-anode display is wired with its cathodes connected directly to LEDs connected to ground. But the strange thing is that it worked exactly as intended: when an LED turned on, the corresponding segment turned off.
My first question is, why didn't it burn out all the LEDs (plus maybe my microprocessor)? 3.3V should be passing directly from the chip, through the 7-Segment and the LED, and into the ground rail. One page on the chip's website (https://www.pjrc.com/teensy/techspecs.html) says it emits a max of 9mA, but that's just a warning about their tolerances, and the pins don't actually throttle output, right? But if all that's true, why is nothing fried? (note that the real circuit is doubled up from what you see in the diagram, using daisy-chained shift registers. I realized after drawing it that that might make a difference, since the current would be split 14 ways instead of 7).
My other question is, I added a resistor at the input of the 7-Segment to limit current, and the circuit still works as originally intended. How is that possible? If a segment is being lit up, that means there's current passing through it, but once on the other side, it should be going directly into the ground via the standalone LED, not "swimming upstream" through a resistor to reach ground via the shift register. Multimeter readings at the cathodes of the 7-Segment are emitting 2V and 0.3 mA. If 0.3mA are insufficient to light up the standalone LEDs, why do they suffice to light up the internal LEDs of the 7-Segment? (and as I recall, they weren't turning on when it was running with no resistance, either.)
Finally, all this has made me wonder, if the digitalWrite pins are capable of emitting 3.3V, what's the point of having a 3.3V pin?

the shift register powers the LEDs, not the Teensy pin

What you are experiencing here is the forward voltage of diodes. When a diode (here you have light emitting diodes, so LEDs) is places in the forward direction in a circuit, it will only conduct when a certain threshold voltage is reached. This voltage is called forward voltage and is dependent on the individual diode (you can find this info in the diodes datasheet) and on other factors like the temperature. To visualize this you can look at a diodes characteristics curve (plotting current against voltage):

I got this image from the German wikipedia article on diodes. As you can see the current stays minimal until the voltage gets in the range of 0.7V. Then the current rises exponentially.
You yourself measured the forward voltage of the 7-Segment LED. You measured 2V between ground and the LED cathode. With 3.3V power you get a forward voltage of 1.3V.
What's happening? Your other LEDs likely have a higher forward voltage, so that the remaining 2V from the 7 Segment LEDs aren't enough to light them. There might be flowing a small current on the path through both types of LEDs, but it will be very small and cannot burn anything. So that path isn't as favorable for the current as you thought. Then taking into account that the shift register pulls its output to either ground or 3.3V it gets clear, that the shift register still provides the easiest current path.

If 0.3mA are insufficient to light up the standalone LEDs, why do they suffice to light up the internal LEDs of the 7-Segment?

I'm not very sure about that value. Typical LEDs need current in the range of  maybe 5mA. For your LEDs we cannot definitely state it (since we don't know what LEDs you have), but 0.3mA seems to low for me. How did you measure it?

One page on the chip's website (https://www.pjrc.com/teensy/techspecs.html) says it emits a max of 9mA, but that's just a warning about their tolerances, and the pins don't actually throttle output, right?

That's only the current range for the digital outputs of the Teensy. Each digital pin has a driver hardware incorporated in the microcontroller. This hardware can only withstand a certain amount of current, until it fails. And it might fail short (shorting to either 3.3V or ground) or disconnected. When you drive the pin near and over its max ratings the voltage will dip on it, since some of the voltage gets lost on the driver components, which are loaded with more current than they were made for. The internal driver can then be killed by the power dissipation in it (voltage lost on the driver multiplied by the current gives you the waste power, which is dissipated as heat there, until something gets fried).

if the digitalWrite pins are capable of emitting 3.3V, what's the point of having a 3.3V pin?

As mentioned the digital output pins can only provide low current. They are meant for doing digital signaling, not for powering devices. The current is enough to drive a single small LED, but not enough to power a motor or other current hungry devices.
The 3.3V pin is not controlled by anything. It is directly connected to the power supply of the whole board. When you power the Teensy via USB it gets 5V from it. A voltage converter regulates that down to 3.3V and feeds it to the Teensys microcontroller to power it and also to the 3.3V pin. In fact you can also use it to connect your own regulated 3.3V power supply and thus power the Teensy through the 3.3V pin.


text:
Where am I going wrong in modifying Timer0 and the ISR interrupts in this example?
(Arduino) Hello I don't know where I am going wrong here, please advise.
In the end I want to step a bipolar motor, HIGH/LOW, using Timer0 with OCR0A and OCR0B interrupts to adjust the motors step interval and duty cycle. Eventually I would like to do the same thing with a second motor and Timer2.
The idea is that the interrupt at OCR0A triggers step LOW and the interrupt at OCR0B triggers step HIGH. This breaks down into the TCNT count from 0 to OCR0B is the LOW phase and TCNT count from OCR0B to OCR0A is the HIGH phase. Both phases together make up the motor step interval which would be between TCNT0=0 and OCR0A ISR Clear. The duty cycle is determined by value between OCR0B and OCR0A, the duration of the HIGH phase.
My first test was to use Serial.println() to return "LOW" or "HIGH" from the corresponding ISRs to the computer to see if the step sequence is in the correct AB-AB pattern. It is not. The step sequence starts out correctly but after 7(seven) OCR0B ISR interrupts in sequence the OCR0B ISR ceases to repeat while the ISR for OCR0A prints repeatedly. The following is the code:
 ISR(TIMER0_COMPA_vect) { Serial.println("HIGH");} //end ISR COMPA//

 ISR(TIMER0_COMPB_vect) { Serial.println("LOW"); } //end ISR COMPB//

 int long  SPEED_A  = 200; // OCR0B->OCR0A is HIGH PHASE // trigger LOW  // clear to 0 //

 int long  SPEED_B  = 150; // 0->OCR0B is LOW PHASE      // trigger HIGH

   void setup()
   {
      noInterrupts();             // disable interrupts

      OCR0A   = SPEED_A;          // interrupt A compare to TCNT0 value each tick // 0-255

      OCR0B   = SPEED_B;          // interrupt B compare to TCNT0 value each tick // 0-255

      TCCR0A  |= ( 1 << COM0A1);  // clear counter on match // OCR0A

      TIMSK0  |= ( 1 << OCIE0A);  // enable timer compare interrupt A

      TIMSK0  |= ( 1 << OCIE0B);  // enable timer compare interrupt B

      interrupts();               // enable interrupts

      Serial.begin(9600);         // serial

   }  //END setup///

 void loop() { } //END loop//

The Serial return is as follows:
LOW
HIGH
LOW
HIGH
LOW
HIGH
LOW
HIGH
LOW
HIGH
LOW
HIGH
LOW
HIGH
HIGH
HIGH
HIGH
...
Why does the ISR for OCR0B stop executing?

flash an LED instead of printing ... if you still want to print, do not do any printing inside an ISR function ... set a flag inside one ISR ... clear the flag inside the other ISR ... print the state of the flag inside the loop() function

Thank you for the comment, I noticed I was misunderstanding the math of what 1 period equated to microsecond wise and the LED 100% helped me see the issue. I need to include global variable to count the ticks or 'OCR0A revolutions' to time the intervals correctly.

Don't do serial prints inside an ISR. Ever. They require interrupts to work, and inside the ISR interrupts are off. For a while the attempts to print will fill up a buffer which is emptied by another ISR, however when that buffer fills the Serial.print will block. And if it blocks inside an ISR waiting for an interrupt it will block forever. Thus it stops printing.
As Jstola suggested in a comment under the question, turn an LED on and off, or something like that.
I can't explain your 7 prints perfectly, but printing HIGH and LOW repeatedly, with their corresponding carriage-return/linefeeds, would, after 7 turns (7 x 11 = 77), pretty-much fill up the serial buffer which is 64 bytes.
So, you are sending around 77 bytes, some would have "escaped" before the buffer filled up, and when you filled it with 64 bytes, it stops.
Your results would change slightly if you made the baud rate higher, say 115200 baud, which I always use, but still, you should not print inside an ISR.

source: Stack Exchange

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

sort: votes


text:
Integration of MAX30100 and DS18B20 Thermal Probe Integration
This is for my final year project that I have been tasked with designing a patient monitoring system. However, during the last stretch of model prototyping, I am experiencing issues with my MAX30100 and DS18B20 thermal probe.
My thermal probe is giving me a proper reading of the temperature. However, the oximeter values are always stuck to zero and the call back function is not executed. I did read that it was an issue where the thermal probe continues to do conversion and doesn't allow the max30100 sensor to perform any other functions. So for that, i just had to pass sensors.setWaitForConversion(false);
I did try to write the code for the DS18B20 thermal probe and the oximeter sensor seperately and it executed perfectly. However, when I try to integrate everything together into a final project, the max30100 sensor doesn't carry out the reading and is stuck to zero while the thermal probe is perfectly working finding out its temperature. I did the same coding process as the previous when i tried to seperately work with the thermal and oximeter sensor. However, it is the final integration that is causing a lot of issues.
The data will be sent to firebase real-time database via the ESP8266 Wi-Fi module. I have got it to work fine. But i am stuck on the final integration of the BP machine, the MAX30100 Oximeter sensor and the DS18B20 Waterproof Thermal Probe. I am also using the Arduino Mega2560 board.
Could anyone guide me as to how do I perform integration of the MAX30100 Sensor with the DS18B20 Probe?
Attaching code for my project below:
#include <LiquidCrystal_I2C.h>
#include <SoftwareSerial.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#include <Wire.h>
#include "MAX30100_PulseOximeter.h"

#define REPORTING_PERIOD_MS 1000
PulseOximeter pox;
uint32_t tsLastReport = 0;
float oxy_lvl = 0.00;

unsigned char alert = 0;
unsigned char system_alert = 0;
unsigned char alert_flag=0;

LiquidCrystal_I2C lcd(0x27,16,2);
SoftwareSerial myserial(13, 12);    // RX, TX for blood pressure sensor
SoftwareSerial esp8266(3, 2);     // rx,tx for esp8266

#define ONE_WIRE_BUS 3
#define HELP_TONE buzz, 2000, 200

const int buzz=9;

OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
float cel=0.00;

String data_pressure;
char  buff[15];

String send_data_string;

const int no_of_data = 5;
String main_data[10];
int sensorValue = 0;
unsigned int tempVal = 0;

int  sys_u = 130, dia_u = 90, temp_l = 24, temp_u = 37, pulse_l = 30, pulse_u = 120;
int sys, dia, p, stay = 1;

void onBeatDetected()
{
  Serial.println("Heart beat detected!! Oximeter pulse detected!!");
}

void setup()
{
  pinMode(buzz, OUTPUT);
  Serial.begin(9600);
  esp8266.begin(9600);
  myserial.begin(9600);
  sensors.begin();
  sensors.setWaitForConversion(false);
  lcd.begin();
  lcd.clear();
  Serial.print("Initializing Oximeter and other sensors");
  if(!pox.begin())
  {
    Serial.println("Oximeter Failed");
    lcd.print("Oximeter Failed");
    for(;;);
  }
  else
  {
    Serial.println("Oximeter Succeeded");
  }
  //pox.setIRLedCurrent(MAX30100_LED_CURR_7_6MA);
  pox.setOnBeatDetectedCallback(onBeatDetected);
  lcd.print(F("        Patient "));
  lcd.setCursor(0, 1);
  lcd.print(F(" Health  Monitor "));
  delay(2000);
  send_data_string = String(sys) + ',' + String(dia) + ',' + String(p) + ',' + String(cel) + ',' + String(oxy_lvl);
  Serial.println("send_data_string = " + String(send_data_string));
  send_parameters();
  delay(4000);
  lcd.clear();
}

void loop()
{
  digitalWrite(buzz,LOW);
  read_temperature_and_oxi();
  main_display();
   myserial.listen();
   if (myserial.available())
   {
     while (myserial.available())
     {
       data_pressure = myserial.readString();
     }
     data_pressure.trim();
     data_pressure.toCharArray(buff, data_pressure.length() + 1);
     if (sscanf(buff, "%d,%d,%d", &sys, &dia, &p) == 3)
     {
       lcd.clear();
       lcd.print(F("sys | dia | puls"));
       lcd.setCursor(0, 1);
       lcd.print(sys);
       lcd.setCursor(7, 1);
       lcd.print(dia);
       lcd.setCursor(12, 1);
       lcd.print(p);
       delay(7500);
       read_temperature_and_oxi();
       process();
       alerting();
       delay(500);
       send_data_string = String(sys) + ',' + String(dia) + ',' + String(p) + ',' + String(cel) + ',' + String(oxy_lvl);
       Serial.println("send_data_string = " + String(send_data_string));
       send_parameters();
       delay(3000);
     }
     myserial.end();
   }
   myserial.listen();
   delay(1);
}

void read_temperature_and_oxi()
{
  float HeartRate = 3.0, SpO2 = 3.0;
  pox.update();
  HeartRate = pox.getHeartRate();
  SpO2 = pox.getSpO2();
  //oxy_lvl=SpO2;
  if(millis() - tsLastReport > REPORTING_PERIOD_MS)
  {
    Serial.print("Heart Rate: ");
    Serial.print(HeartRate);
    Serial.print("bpm / SpO2: ");
    Serial.print(SpO2);
    Serial.println(" % ");

    sensors.requestTemperatures();
    cel=sensors.getTempCByIndex(0);
    Serial.print("Temperatures: ");
    Serial.print(cel);
    Serial.println("");

    tsLastReport=millis();
  }
}

void main_display()
{
    lcd.clear();
    lcd.print(F("Temp: "));
    lcd.setCursor(6, 0);
    lcd.print(cel);
    lcd.print((char)223);
    lcd.print('C');
    lcd.setCursor(0, 1);
    lcd.print("SpO2: ");
    lcd.setCursor(6 ,1);
    lcd.print(oxy_lvl);
    delay(200);
}

void send_parameters()
{
  esp8266.listen();
  esp8266.flush();
  esp8266.print(send_data_string);
  delay(5000);
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print(F("  Uploaded To "));
  lcd.setCursor(0,1);
  lcd.print(F("  Firebase  "));
  delay(200);
  esp8266.end();
}

void help_display()
{
    lcd.clear();
    lcd.print(F(" PATIENT NEEDS  "));
    lcd.setCursor(6, 1);
    lcd.print(F("HELP      "));
}

void process()
{
   if((sys > sys_u) || (dia > dia_u))
   {
       system_alert = 1;
   }
   else if((p < pulse_l ) || (p > pulse_u))
   {
       system_alert = 2;
   }
   else if((cel < temp_l ) || (cel > temp_u))
   {
       system_alert = 3;
   }
   else
   {
       system_alert = 0;
   }
   delay(200);
}

void alerting()
{
  if(system_alert==1)
   {
    lcd.clear();
    digitalWrite(buzz,HIGH);
    lcd.setCursor(0,0);
    lcd.print("Patient BP");
    lcd.setCursor(0,1);
    lcd.print("Fluctuating");
    delay(3500);
   }
   else if(system_alert==2)
   {
    lcd.clear();
    digitalWrite(buzz,HIGH);
    lcd.setCursor(0,0);
    lcd.print("Patient Pulse");
    lcd.setCursor(0,1);
    lcd.print("Fluctuating");
    delay(3500);
   }
   else if(system_alert==3)
   {
    lcd.clear();
    digitalWrite(buzz,HIGH);
    lcd.setCursor(0,0);
    lcd.print("Temperature");
    lcd.setCursor(0,1);
    lcd.print("Fluctuating");
    delay(3500);
   }
   else
   {
    Serial.print("Continue Monitoring");
    delay(3500);
   }
}

Also attaching the code I wrote for integration of the MAX30100 Oximeter and the DS18B20 Thermal Probe standalone below.
#include <Wire.h>
#include "MAX30100_PulseOximeter.h"
#include <LiquidCrystal_I2C.h>
#include <OneWire.h>
#include <DallasTemperature.h>

#define REPORTING_PERIOD_MS     1000
PulseOximeter pox;
uint32_t tsLastReport = 0;
LiquidCrystal_I2C lcd(0x27, 16, 2);

#define ONE_WIRE_BUS 5
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
float cel=0.00;

// Callback (registered below) fired when a pulse is detected
void onBeatDetected()
{
  Serial.println("Beat!");
}
void setup()
{
  Serial.begin(9600);
  Serial.print("Initializing...");
  sensors.begin();
  sensors.setWaitForConversion(false);
  // Initialize the PulseOximeter instance
  if (!pox.begin()) {
    Serial.println("MAX30100 was not found. Please check the wiring/power.");
    lcd.print("FAILED");
    for (;;);
  } else {
    Serial.println("SUCCESS");
  }
  // pox.setIRLedCurrent(MAX30100_LED_CURR_7_6MA);
  // Register a callback for the beat detection
  pox.setOnBeatDetectedCallback(onBeatDetected);
}
void loop()
{
  float HeartRate = 3.0, SpO2 = 3.0;
  pox.update();
  HeartRate = pox.getHeartRate();
  SpO2 = pox.getSpO2();
  if (millis() - tsLastReport > REPORTING_PERIOD_MS) {
    Serial.print("Heart rate:");
    Serial.print(HeartRate);
    Serial.print("bpm / SpO2:");
    Serial.print(SpO2);
    Serial.println("%");
    sensors.requestTemperatures();
    cel=sensors.getTempCByIndex(0);
    Serial.print("Temperature: ");
    Serial.print(cel);
    Serial.println("");
    tsLastReport = millis();

    lcd.clear();
    lcd.setCursor(0,0);

    lcd.print("HR:");
    lcd.print(HeartRate);
    lcd.print(" bpm");

    lcd.setCursor(0,1);

    lcd.print("SpO2:");
    lcd.print(SpO2);
    lcd.print("%");

    lcd.setCursor(11,1);
    lcd.print("T:");
    lcd.print(cel);
  }
}

The required output when I run the second code:
Heart Rate: 55.38 BPM / SpO2: 96.00%
Temperature: 25.50
Beat!
Heart Rate: 54.07 BPM / SpO2: 95.00%
Temperature: 26.51
Beat!
Heart Rate: 60.38 BPM / SpO2: 97.00%
Temperature: 27.55
Beat!

The output I get when I try to integrate all the sensors together:
Heart Rate: 0.00 BPM / SpO2: 0.00%
Temperature: 27.50
Heart Rate: 0.00 BPM / SpO2: 0.00%
Temperature: 27.30
Heart Rate: 0.00 BPM / SpO2: 0.00%
Temperature: 27.36
Heart Rate: 0.00 BPM / SpO2: 0.00%
Temperature: 28.05

The link for the BP machine: https://www.sunrom.com/566

please delete the screenshots and add the actual text instead ... format it as code ... some people here cannot view images

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


text:
Why can't an Arduino/ATmega328 act as an SPI slave at anywhere approaching the maximum speed claimed in the datasheet?
The ATmega328 datasheet claims a maximum SPI slave speed of Fosc/4. For a chip clocked at 20MHz, that would be 5Mbps.
However, my tests show that even with no processing whatsoever in the interrupt (other than setting the response), any speed over 128Kbps results in corrupted data. I have no idea why this should be the case.
In my setup, the master runs at 3.3V and 12MHz; and the slave at 5V and 20MHz.

Master code:
#include <SPI.h>
#include "pins_arduino.h"

unsigned int successcount = 0;

void setup(void) {
  Serial.begin(9600);
  SPI.begin();
  SPI.setClockDivider(SPI_CLOCK_DIV4);   // 3Mbps
}

void print_successful_transfers() {
  if (successcount > 0) {
    Serial.print("(");
    Serial.print(successcount);
    Serial.println(" successful transfers.)");
    successcount = 0;
  }
}

void loop(void) {
  unsigned char n = 0;
  unsigned char received;
  unsigned int failurecount = 0;

  delay(500);       // wait for the slave to be ready

  digitalWrite(SS, LOW);    // SS is pin 10

  while (failurecount < 10) {
    for (unsigned int count = 0; count < 10000; count++) {
      received = SPI.transfer(n+1);
      if (received != n) {
        print_successful_transfers();
        Serial.print("MISMATCH: sent ");
        Serial.print(n+1);
        Serial.print(", received ");
        Serial.print(received);
        Serial.println(".");
        failurecount++;
        if (failurecount == 10) break;
      } else
        successcount++;
      ++n;
    }
    print_successful_transfers();
  }
  while(true);
}

Slave code:
#include "pins_arduino.h"

volatile char n = 0;

void setup (void) {
  pinMode(MISO, OUTPUT);
  SPCR |= _BV(SPE);
  SPCR |= _BV(SPIE);
}

ISR (SPI_STC_vect) {
  n = SPDR;
  SPDR = n;
}

void loop (void) { }

Sample output:
MISMATCH: sent 1, received 245.
(1290 successful transfers.)
MISMATCH: sent 12, received 5.
MISMATCH: sent 13, received 140.
(1350 successful transfers.)
MISMATCH: sent 84, received 41.
MISMATCH: sent 85, received 212.
(996 successful transfers.)
MISMATCH: sent 58, received 28.
MISMATCH: sent 59, received 186.
(5455 successful transfers.)
MISMATCH: sent 139, received 197.
MISMATCH: sent 140, received 11.
(900 successful transfers.)
(114 successful transfers.)
MISMATCH: sent 131, received 193.

Here is my schematic. I am using bare ATmega328 chips rather than Arduinos, but the situation would be the same if I were using a 5V Arduino Nano and a 3.3V Arduino Nano.
(Except the slave would run at 16MHz instead of 20MHz.)

I also tried with the following level shifter on the MOSI, SCK and SS lines:

EDIT:
To rule out voltage as the possible cause, I ran both ATmega328s at 3.3V and 12MHz. Same problem.

EDIT: I connected two Arduino Nanos together and got different - but still erroneous - behaviour.
The SS pin, despite being set to LOW at the start of the program and never touched again - goes briefly high every so often, corrupting the communication:

(If I use a different pin for slave select, I get the same behavior.)
Note that this is NOT the issue I experienced with my bare ATmega328 circuit.

3.3 V is small and easy to corrupt in wiring.  throw that in with a 5V device and you need some pretty noise resistant wiring

Can you monitor the SPI lines with a scope? That'd be interesting.

There doesn't seem to be anything wrong with the wiring or the signals themselves. I tested with a logic analyser and a scope. Besides, shouldn't 3.3V at the very least be able to cope with 256Kbit?

I'd rather use 1k instead of 4k7 on that level shifter, slowly rising edge will be bottleneck. And also ISR is taking some time too (it could be up to 20 instructions).
And also SS is used for synchronization, so it won't be a bad idea to set it high after the transfer and low before it

At 20MHz, 20 instructions shouldn't be a significant bottleneck.

I tried changing the resistor. Sadly it didn't help.

3.3V output high is only guaranteed to be about 2.7V (from memory, check the datasheet). 5V input high min is 3V (again from memory). If the lines have any length at all, you're in trouble.

A good point. However, one of my previous designs had level shifters on all SPI lines; and I tested that this evening. No dice. I will update the question to show the level shifter circuit I used.

Besides, if it were a voltage issue, then why would it work perfectly at 128KHz? Without even a single glitch?

You need to break down the big problem into smaller steps, so first you can examine if the ISR is fast enough. Add a port pin toggler in the ISR of the slave, to see how the timings are. Don't use digitalWrite() due to its overhead, set/reset the pin directly for optimum speed.

I have reproduced the problem with two standard Nanos running at 5V. I will update my question.

Odd. The problem presents the same with the Nanos, but is actually caused by a completely different issue. Specifically, the SS pin. I have amended the question.

The original problem still happens if I run both chips at 3.3V. So voltage is not the issue here.


text:
failed log in attempts on softAP
I would like to setup an access point using the esp32 that logs any/failed access attempts
i have looked through some source files, and came across esp_event.h, which seems to allow registering an event handler, i wonder if this could be used to do the logging.
#include <WiFi.h>

const char* ssid     = "tmp-AP";
const char* password = "123456789";

static void all_event_handler(void* handler_args, esp_event_base_t base, int32_t id, void* event_data){

    Serial.println("all_event_handler");

}

void setup() {

  delay(3000);
  Serial.begin(9600);
  Serial.println("test started...");

  auto result = esp_event_handler_register(ESP_EVENT_ANY_BASE, ESP_EVENT_ANY_ID, all_event_handler,NULL);

  Serial.print("result : ");
  Serial.printf("result : %d - 0x%04x\n",result,result);

  Serial.println("Setting up AP ...");
  WiFi.softAP(ssid, password);

  IPAddress IP = WiFi.softAPIP();
  Serial.print("AP IP address: ");
  Serial.println(IP);

}

void loop(){
}

the code compiles
esp_event_handler_register returns 259 for me, the handler is never called
i have cobbled together this code from :
Event Loop Library
arduino-esp32/libraries/WiFi/src/
default_event_loop
i guess i would like to hook into at least NOT_AUTHED,  802_1X_AUTH_FAILED  from
WiFi Driver

You sure the return value was 429 (in decimal)? Don't think that maps to anything, whether esp_err_t or errno.

well now im getting 259 printed to serial, using codes from error codes

Print the value in HEX

259 == ESP_ERR_INVALID_STATE according to this. Your error likely came from here:
esp_err_t esp_event_handler_instance_unregister(esp_event_base_t event_base,
                                                int32_t event_id,
                                                esp_event_handler_instance_t context)
{
    if (s_default_loop == NULL) {
        return ESP_ERR_INVALID_STATE;
    }
...

You're perhaps calling the function too early, before a default event loop even exists. I'm guessing that usually this event loop gets created by the WiFi libs when you start WiFi-related calls -- such as here:
static bool _start_network_event_task(){
...
esp_err_t err = esp_event_loop_create_default();

If you try moving your registration to after the softAP() call, you risk missing events, depending on how synchronous that call is. So you can try creating the event loop yourself explicitly:
// Create the default event loop
ESP_ERROR_CHECK(esp_event_loop_create_default());

...before you register the handler. That should be harmless -- anything else that tries to create this same loop later should cleanly handle the returned error that indicates the loop already exists.
EDIT
So I tried out your sketch and met the same issue. After spending more time than should've been needed, the issue boils down to one of compatibility.
My ESP32-Arduino core 1.0.6 (and likely yours as well) is based on the ESP-IDF/SDK 3.3.5 release -- a release that contains some pretty old code, despite being the latest that the Arduino Boards Manager has to offer. So, esp_event_loop_init() looked like this:
esp_err_t esp_event_loop_init(system_event_cb_t cb, void *ctx)
{
    if (s_event_init_flag) {
        return ESP_FAIL;
    }
    s_event_handler_cb = cb;
    s_event_ctx = ctx;
    s_event_queue = xQueueCreate(CONFIG_SYSTEM_EVENT_QUEUE_SIZE, sizeof(system_event_t));

    xTaskCreatePinnedToCore(esp_event_loop_task, "eventTask",
            ESP_TASKD_EVENT_STACK, NULL, ESP_TASKD_EVENT_PRIO, NULL, 0);

    s_event_init_flag = true;
    return ESP_OK;
}

and WiFiGeneric.cpp looked like this:
static bool _start_network_event_task(){
...
    return esp_event_loop_init(&_network_event_cb, NULL) == ESP_OK;

As you can see, there's no mention of the default loop being created, which is why you get *INVALID_STATE for any registrations.
Even if you went and created the default loop yourself, you'd receive no events in your handler because the system events, as of this IDF version, aren't passing through the official esp_event loop pipeline -- esp_event_loop_init() just creates a Task and this task receives events from some external caller as they happen, forwarding them to one application task alone.
If you still want to receive events through this way, you'd need to download/install the very latest ESP32 Arduino core from Github, rather than through the Boards Manager. This core should have a more recent version of the SDK, along with a compatible Arduino HAL.
Alternatively, you can just use the more public API, WiFi.onEvent(). It should cover all the events you're interested in, as well as include any relevant reason codes.
EDIT 2
Yeah, it turns out the SYSTEM_EVENT_AP_STADISCONNECTED reason codes you're looking for, just aren't exposed by the Espressif API, at any layer of the stack. Nor is there any other event which would give you this info AFAICT. You can try raising an issue on the ESP-IDF Github page to see if they can help you there, but chances aren't looking great.

i moved esp_event_handler_register after the call to softAP, same result 259 (0x103)

i kept esp_event_handler_register where it is and added esp_event_loop_create_default before it, both function calls return 0 (0x0) - ESP_OK, but the handler is never called

@mattrichards Did you actually try to do something that would cause the handler to be called -- like connecting a device to the AP?

yes of course, i tried with correct password and incorrect

@mattrichards updated the answer.

i drew the same conclusions, so i decided to order some new boards amazon esp32 devkitc, i'll post my results back here at some point

the wifi.onevent was a no go, i produced two sketches attempting to detail the limitations of this approach, wif ap test, it seems the reason code isnt supplied for SYSTEM_EVENT_AP_STADISCONNECTED, wifi sta test

@mattrichards Yeah, edited the answer, don't think there's any way to get those reason codes.


text:
How fast are IR sensors with Arduino
For an industrial project which requires detecting whether some text is printed on the cable at regular intervals or not, I was wondering if Arduino with IR sensor could work? The cable would be typically black with white text printed at each metre and will be unwounding from a cylindrical drum (To give you an idea of text length, it will contain cable type, metre mark, etc., I'll update the question with the linear velocity of the cable soon).
My approach was to raise an interrupt if the colour change is not recognized in the predetermined time. For this, I think I need to check if I can measure light changes, let's say 4 or 6 times in a time it takes to unwind a metre of the wire. I however don't know how fast IR sensors are to judge whether this approach is feasible.
Also, let me know if this is unfeasible and I should instead move to Raspberry Pi with a camera.

They're fast enough to transfer meaningful digital information faster than the human eye can discern.

Using a camera with pattern detection will be slower than the IR sensor. You won't get numbers about the speed of IR sensors here. This entirely depends on the sensor, what phototransistors are used and if you have additional circuitry on the sensor. When you use a pure phototransistor without any circuitry connected to an analog input it will be limited by the sample rate of the ADC. This again depends on the used microcontroller/ADC, the chosen resolution (lower resolution gets faster) and the further processing of the data (slowest part of the chain dictates the total speed)

Thanks, that was useful!

https://www.instructables.com/IR-Transmitter-and-Receiver-Using-Arduino/
As demonstrated in the project linked above an IR sensor connected to an Arduino is capable of reading and decoding the signal from a typical IR remote sending at about 38 KHz. In the ones I've tried the signal is a burst of 10 or 11 digits.  Given that, sensing the presence or absence of a contrasting color sounds quite a bit less challenging.
I built the decoder in the linked Instructable with a Nano (author used a Mega) and it worked well.
I believe what you're proposing is feasible.

38KHz is the modulation frequency of IR, not the data rate it transmit. The transmission rate using 38KHz modulation is typically around 2400 baud.

I stand corrected. Thanks. Still should be fast enough to capture a 1 bit signal, i.e. a blob of white text on a passing cable.


text:
Interval timer on Arduino: Doubt about TimerOne library
I want to synchronize a timer interrupt from a button is pressed. I want to read a button state 3 seconds later from the first pulse moment (to identify long pressed button, 3 seconds for this example). I'm trying to do with this code:
#include <TimerOne.h>
#define pinButton 3
#define POWER_ON_TIME 3 //Long press in seconds

volatile unsigned long pressed_Time = 0;
volatile unsigned long myTime_button = 0;
volatile unsigned long myTimeOn_button = 0;
volatile unsigned long myTime_pressed = 0;

unsigned long holdTime = 0;
bool button_state = false;

void setup() {
  // put your setup code here, to run once:
  pinMode(pinButton, INPUT_PULLUP);
  pinMode(LED_BUILTIN, OUTPUT);

  Timer1.initialize();
  Timer1.attachInterrupt(pressed_check);
  attachInterrupt(digitalPinToInterrupt(pinButton), button_act, CHANGE);
  Serial.begin(9600);
}

void loop() {

  Serial.println("myTime_pressed");
  Serial.println(myTime_pressed);

  if (!digitalRead(pinButton)){Timer1.attachInterrupt(pressed_check,POWER_ON_TIME*1000000 );}
    else {Timer1.detachInterrupt();}

}

void button_act(){
  if (!digitalRead(pinButton)){myTime_button = micros(); //Flanco de bajada
  }
  else{myTimeOn_button = micros(); } //Flanco de subida
}

void pressed_check(){
  myTime_pressed = micros();

}

This way I can start the timer interrupt when the button is pressed, but the problem is the time is not the time from the function is attached but from the beginning. Any advice to change this?

The function button_act() is missing from the posted code. Please add it. One problem is probably that you need to add L at the end of a big integer number. Otherwise the compiler will by default treat it as integer (which cannot hold the value 1 million). But also: I don't understand the logic of your program. In pressed_check() you don't check the button but only set myTime_pressed, which is only ever printed but not used in any way. In loop() you attach and detach the timer interrupt on button press and release, which doesn't really make sense to me.

And why do you want to use an extra hardware timer to record the press duration? I don't see a reason why millis() and micros() wouldn't be enough for this. No need to go through the hassle of using a hardware timer.

Hi @chrisl . I cut the code, sorry. Now all is ok. I have two interrupts: one external, connected to the button, the other by timer. On this code I'm testing the micros() capture with timer interruption and I wanted to see the results. I thought micros() could capture the time from attachInterrupt action, not from the Arduino start.

micros() gives you the microseconds from the startup. When you need a time difference you need to capture the start and end value and then take the difference. Though I still don't see why you would need a hardware Timer for distinguishing short and long button presses.

I now I now, it is possible that is easier make this without timers, but now I want to know why the timer function attached executes on interval times from the start, not from determinated event.

Why are you using interrupts at all? Look at the State Change Detection example in the IDE (File->examples->02.digital->State Change Detection) to learn how to detect when the button gets pressed or released and then record the time of that event. After the current time - event time is greater than 3 seconds, read your button again.
Or, make your life easier and use the Bounce2.h library. It has a Button class that will track the duration the button has been in any state.

Don't know if I understand what you want to do.
IMHO TimerOne is a good library for repetitive tasks, not for one shot events.
You should use Timer1.stop and Timer1.resume() to start the 3 seconds count whenever you press the button.
But TimerOne has a known issue: when you use restart or start the ISR is fired immediatly
Here is my version of your code. It waits for button press and then starts timer. After 3 seconds pressed_check is fired and the longPressDetected flas is set.
I hope I have correctly interpreted your question
#include <TimerOne.h>
#define pinButton 3
#define POWER_ON_TIME 3UL //Long press in seconds

volatile unsigned long pressed_Time = 0;
volatile unsigned long myTime_button = 0;
volatile unsigned long myTimeOn_button = 0;
volatile unsigned long myTime_pressed = 0;

volatile bool firstISR_Call = true;
volatile bool longPressDetected = false;

unsigned long holdTime = 0;
bool button_state = false;

void setup() {
    // put your setup code here, to run once:
    pinMode(pinButton, INPUT_PULLUP);
    pinMode(LED_BUILTIN, OUTPUT);

    Timer1.initialize();
    // Create an ISR that is called every POWER_ON_TIME seconds
    Timer1.attachInterrupt(pressed_check, POWER_ON_TIME * 1000000UL);
    // Stop Timer1 now
    Timer1.stop();

    //Timer1.attachInterrupt(pressed_check);

    attachInterrupt(digitalPinToInterrupt(pinButton), button_act, CHANGE);
    Serial.begin(9600);
}

void loop() {
    if (longPressDetected) {
        longPressDetected = false;
        Serial.println("Long press detected");
    }
    delay(100);
}

void button_act() {
    if (!digitalRead(pinButton)) {
        myTime_button = micros(); //Flanco de bajada
        firstISR_Call = true;       // Set to true toprevent "phantom" interrupt
        longPressDetected = false;  // Clear long press detection flag
        Timer1.restart();           // Restart timer from 0 - ISSUE: this fires immediatly an interrupt
                                    // causing a so called "phantom" interrupt
    }
    else {
      myTimeOn_button = micros() - myTime_button;
      Timer1.stop();
    } //Flanco de subida
}

void pressed_check() {
    // Detect "phantom" interrupt
    if (firstISR_Call) {
        firstISR_Call = false;
        return;
    }
    longPressDetected = true;
    myTime_pressed = micros() - myTime_button;
    Timer1.stop();
}

Thank you so much! This is the answer for my question! I tried with restart and start but it didn't work like I wanted. Thank you so much!

@Juanma you're welcome, my pleasure.


text:
Using ESP8266 to program Arduino by serial comm
Since ESP8266 can self program on wifi, can we use it to program arduino too with the binary sent via wifi? my arduino is connected with reset+RX+TX pins and shared power.
Has this been already done?

If you use Linux, you can use a simple Telnet to Serial sketch in esp8266 to upload with avrdude to Uno over esp8266. Only on Linux can avrdude use telnet to do a serial upload.
For upload from IDE on any OS there is JeeLabs ESP Link firmware for the esp8266.

plenty of ways on other os to patch things so arduino looks to be connected over serial as far as avrdude is concerned- for example com0com makes virtual serial ports...

@Abel, did you test it?

haven't done it for avrdude yet, but i did have the need to do something similar for a serial user interface program to connect to a stream that had to be encapsulated by ssh first.

tested with pi in the middle (avrdude-com0com-customExe-pi-customProgram-uno).  gotchas found: bootloader baud, and stable re-entry to bootloader.  no reason to believe any other program attempting this over serial would behave differently.  i implemented re-entry via usb port poweroff and poweron via rpi uhubctl, but it might be possible with hardware (reset pin), a modified bootloader, or crashing? the main on command (casting 0 to a function pointer and calling it).

@Abel, my sketch linked in the answer resets the target at new telnet connection. what problem with baud rate?

i didnt use your sketch or telnet.  Just wanted to prove you are not limited to avrdude linux to get the job done- for me avrdude thought it was talking over serial and uploaded just fine.  Can make a connection between avrdude and the nets with other programs.


text:
Code uploading error on NodeMCU v3 "the selected serial port _ does not exist on your connected board"
when trying to upload code to NodeMCU v3, sometimes I get the error "the selected serial port _ does not exist on your connected board" and sometimes "timed out waiting for packet header". My attempts for this problem:

No cable is connected to any pin,
I changed the USB port,
Then I checked the components of the card, everything
seemed fine.
I checked the pin headers, there was no bridge.
Then I cleaned the whole board 4-5 times with 1-minute intervals for the
possibility of solder paste.

Still, the result did not change, what can I do in this case?
EDIT
I opened serial monitor with "74880 baud" and pushed to rst output is,
02:49:04.182 ->
02:49:04.182 ->  ets Jan  8 2013,rst cause:2, boot mode:(3,7)
02:49:04.228 ->
02:49:04.228 -> load 0x4010f000, len 3460, room 16
02:49:04.228 -> tail 4
02:49:04.228 -> chksum 0xcc
02:49:04.228 -> load 0x3fff20b8, len 40, room 4
02:49:04.228 -> tail 4
02:49:04.228 -> chksum 0xc9
02:49:04.228 -> csum 0xc9
02:49:04.228 -> v00062500
02:49:04.228 -> ~ld

On what OS are you? You might need to install the drivers for the CH340 chip, which does the USB communication.

I installed and uptaded driver for CH340

Are you pressing the "boot" button on your NodeMCU during reset, to put it into Flash mode manually before attempting to program it?

I tried that but result doesnt change


text:
How do I instruct the L293D to operate a motor at full speed when using 3.3V GPIO pins?
If the L293D enable and input pins expect [up to] 5V inputs; what is the best way to deliver full power to the output pins when using an ESP32 or any other microcontroller which uses 3.3V GPIO pins?
I've seen several projects which combine the L293D with the ESP32, but none of them seem to mention whether or not this is even an issue.  Am I missing something?  Or should one always use level shifting when using 3.3V logic and the L293D

There is a good discussion of this issue at Quora. They note that the logic levels on the L293D is compatible with either 3.3 or 5v mcus but that you need to supply >4.5v power. https://www.quora.com/How-do-I-connect-an-L293D-motor-shield-to-Arduino-Duo-which-operates-at-3-3v

The voltage level on the control pins does not have any relation to the power provided to the motor.
The inputs are all digital. Above a threshold they are on, and below a threshold they are off.  Those thresholds are compatible with both 3.3V and 5V logic.
What controls the power delivered to the motor is the duty cycle of the PWM signal provided to the EN pin.


text:
What is the difference between Bluetooth module HC-05 and HC-42 for Arduino?
I am looking for differences between HC-05 and HC-42 Bluetooth modules for Arduino. I could not find an answer by searching google.
Both products have 6 pins and accept master and slave but I could not find further details on the differences.

It's different technology. the HC-05 uses the old Bluetooth 2.0 standard. The HC-42 in contrast uses BLE (Bluetooth Low Energy) in version 5.0.
So you have to decide what technology you want to use, either classic Bluetooth 2.0 or Bluetooth Low Energy 5.0.

Anecdotally, a few years ago I tried to use BLE and it had much less library support. Not sure how it is now.


text:
How to build an arduino project with multiple source files?
I'm building an arduino program on linux, using the following Makefile:
ARDUINO_DIR = /usr/share/arduino
BOARD_TAG = uno
ARDUINO_PORT = /dev/ttyAMA0
ARDUINO_LIBS = Wire
include /usr/share/arduino/Arduino.mk

Currently all of my code is spread among a dozen header files and a single .ino file - it gets compiled and it runs properly when flashed. I know that's not correct though and I'm trying to split my code into the proper structure of source and header files but when I do and try to build it I get the following output:
In file included from gear.c:1:0:
gear.h:19:1: error: unknown type name ‘byte’
 byte GEAR = 3;
 ^

Which leads me to believe that the source file is getting compiled separately and does not know what a byte is, which is supposedly defined somewhere within the arduino library.
What's the proper way to build my project with source files?

avrdude is an uploader/downloader ... it does not do any building

@jsotola I'm sorry, my mistake.

There is a byte datatype in C, its called char. for flipping bits in ardunio you could use bitSet, which allows you to change values of bits in a datatype. https://www.arduino.cc/reference/en/language/functions/bits-and-bytes/bitset/
not really sure what exactly your doing.

First of all, I recommend you write in C++ (file extension .cpp) rather
than in plain C (files in .c). The reason is that the Arduino
programming environment is based on C++, some of the libraries are
C++-only, and your main .ino file will be compiled as C++ source. Mixing
this with C is possible, using some extern "C" declarations, but it is
probably more hassle that it's worth.
Now, to answer your actual question, just add thsi near the top of your
source files:
#include <Arduino.h>

This includes the type definitions specific to the Arduino environment,
together with the core API. This include is added automatically to any
file ending in .ino, but you have to add it explicitly to your .cpp
files.

Mixing this with C is possible, using some extern "C" declarations, but it is probably more hassle that it's worth. Are you talking about having to prefix all variable definitions with extern? Even by renaming the file to .cpp I still had to add that or I would get errors that variables were not declared. There's a high probability I'm doing something wrong though, have literally 0 practical experience with C/C++

@php_nub_qq: No, I am not talking about extern. My point is that you cannot access C++ objects (e.g. Serial) from C, and accessing C functions from C++ requires extern "C" declarations.

Well for now it seems to work fine with the Wire library. Thanks for mentioning though, if I come across it I'll know what to look up and not waste 3 hours.


text:
Cubecell AB01 with nRF24L01
I have been trying to connect a nRF24L01 to a Cubecell AB01 without much luck. Most of the time, the radio.available() function always returns true resulting in a bunch of garbage. I have figured out that the nRF24L01 doesn't want to configure properly. With printPrettyDetails() I can confirm that the settings are not stored.
However, with the example sketch contained within the RF24 library, everything works fine (confirming that the AB01 and nRF24L01 are working fine). But as soon as I change the datatype of the receiver payload to uint8_t, the radio.available() is always true, resulting in a bunch of received messages with garbage. PrintPrettyDetails() also shows the wrong settings.
Does anyone have experience with this? I have also tried the example sketch from Robin2. This results in a lot of garbage as described before.
I am using:

nRF24L01 with pcb antenna. I am periodicially using an esp32 to test that the nRF24L01 is still functioning okay
a heltec AB01. The nRF24L01 is connected to the spi interface and CE -> GPIO3 and CSN -> GPIO2
To program I'm using platformio. But in desperation I am also able to use the Arduino IDE (exactly the same behaviour)

RX code:
/**
* See documentation at https://nRF24.github.io/RF24
* See License information at root directory of this library
* Author: Brendan Doherty (2bndy5)
*/
    /**
     * A simple example of sending data from 1 nRF24L01 transceiver to another.
     *
     * This example was written to be used on 2 devices acting as "nodes".
     * Use the Serial Monitor to change each node's behavior.
     */
    #include <SPI.h>
    #include "printf.h"
    #include "RF24.h"

    // instantiate an object for the nRF24L01 transceiver
    RF24 radio(GPIO3, GPIO2); // using pin 7 for the CE pin, and pin 8 for the CSN pin

    // Let these addresses be used for the pair
    uint8_t address[][6] = {"1Node", "2Node"};
    // It is very helpful to think of an address as a path instead of as
    // an identifying device destination

    // to use different addresses on a pair of radios, we need a variable to
    // uniquely identify which address this radio will use to transmit
    bool radioNumber = 1; // 0 uses address[0] to transmit, 1 uses address[1] to                                 transmit

    // Used to control whether this node is sending or receiving
    bool role = false;  // true = TX role, false = RX role

    // For this example, we'll be using a payload containing
    // a single float number that will be incremented
    // on every successful transmission
    float payload = 0;

    void setup() {

      Serial.begin(115200);
      while (!Serial) {
        // some boards need to wait to ensure access to serial over USB
      }
      pinMode(Vext, OUTPUT);
      digitalWrite(Vext, LOW);
      delay(10);
      // initialize the transceiver on the SPI bus
      if (!radio.begin()) {
        Serial.println(F("radio hardware is not responding!!"));
        while (1) {} // hold in infinite loop
      }

      // print example's introductory prompt
      Serial.println(F("RF24/examples/GettingStarted"));

      radioNumber = 1;
      Serial.print(F("radioNumber = "));
      Serial.println((int)radioNumber);

      // Set the PA Level low to try preventing power supply related problems
      // because these examples are likely run with nodes in close proximity to
      // each other.
      radio.setPALevel(RF24_PA_LOW);  // RF24_PA_MAX is default.

      // save on transmission time by setting the radio to only transmit the
      // number of bytes we need to transmit a float
      radio.setPayloadSize(sizeof(float)); // float datatype occupies 4 bytes

      // set the TX address of the RX node into the TX pipe
      radio.openWritingPipe(address[radioNumber]);     // always uses pipe 0

      // set the RX address of the TX node into a RX pipe
      radio.openReadingPipe(1, address[!radioNumber]); // using pipe 1

      // additional setup specific to the node's role
      if (role) {
        radio.stopListening();  // put radio in TX mode
      } else {
        radio.startListening(); // put radio in RX mode
      }

      // For debugging info
      // printf_begin();             // needed only once for printing details
      // radio.printDetails();       // (smaller) function that prints raw register values
       radio.printPrettyDetails(); // (larger) function that prints human readable data

    } // setup

    void loop() {

        // This device is a RX node

        uint8_t pipe;
        if (radio.available(&pipe)) {             // is there a payload? get the pipe         number that recieved it
          uint8_t bytes = radio.getPayloadSize(); // get the size of the payload
          radio.read(&payload, bytes);            // fetch payload from FIFO
          Serial.print(F("Received "));
          Serial.print(bytes);                    // print the size of the payload
          Serial.print(F(" bytes on pipe "));
          Serial.print(pipe);                     // print the pipe number
          Serial.print(F(": "));
          Serial.println(payload);                // print the payload's value
        }

    } // loop

I have tried anything I could think of, without success. Any help would be appreciated!

Turned out to be a corrupt library and an SPI speed mismatch


text:
Different time betweenTiny RTC and IDE
I have time late in my Tiny RTC when i try to set time at sketch downloading.
Library: RTClib.h
Setup line:
if (rtc.lostPower()) {
Serial.println("RTC lost power, lets set the time!");
rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));

The problem is that my computer displays 15:45 and Serial.print displays 15:12.
How can i fix that ?

__TIME__ is the time the sketch was compiled, not when the board starts running. It was compiled at 15:12, but you applied power at 15:45...?

I compiled and then load the sketch just after. Why so much delay?

Try to Serial.println(F(__TIME__)). This will show you the time that you attempted to set in the RTC, which is your compiler's idea of the current time when it is doing the compilation.

The key here is if (rtc.lostPower()) { -- That is, if the RTC loses power then reset the time to what it was back when you compiled the sketch. If you want to set the time to now then you will need to include some mechanism to either query the time from somewhere or allow the user to set the time manually.

I just removed "if" condition and keep rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
Solved!


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

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

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


text:
I2C missing last byte during transmission- solution isn't clear
I am using a Nodemcu-32S to communicate with an I2C device (touchpads). I noticed while uploading the configuration, the CRC (checksum) always comes back incorrect. After doing a little digging with a logic analyzer, I realized that it never transmits the final byte from my configuration array, which is the checksum value. The function I use for writing to the I2C bus is as follows:
bool writeI2C(uint16_t address, uint8_t command, uint8_t *data, uint8_t dataLen)
{
    byte err;
    uint8_t dataPos = 0;
    Wire.beginTransmission(address);
    Wire.write(command);
    for (dataPos; dataPos < dataLen; dataPos++)
    {
        Wire.write(data[dataPos]);
    }
    delay(70);
    err = Wire.endTransmission();
    if (err > 0)
    {
        Serial.printf("writeI2C Error Code: 0x0%d\n", err);
        return false;
    }
    else
        return true;
}

With the following function call:
uint8_t config[128] = {0}; <- (the array is filled with values before the function call)

if (!writeI2C(SLAVE_ADDR, command, config, 128))
        {
            Serial.println("Failed to update config.");
            continue; // try again
        }

According to the logic in my function, it should transmit the address, then the register (command in this case) followed by 128 bytes of data (130 bytes total). With my logic analyzer, however, I get only 129 'chunks' of data. So I figured I'd add dummy writes if dataLen met a condition:
bool writeI2C(uint16_t address, uint8_t command, uint8_t *data, uint8_t dataLen)
{
    byte err;
    uint8_t dataPos = 0;
    Wire.beginTransmission(address);
    Wire.write(command);
    for (dataPos; dataPos < dataLen; dataPos++)
    {
        Wire.write(data[dataPos]);
    }
    if (dataLen > 100)
    {
        Wire.write(0x00);
        Wire.write(0x00);
        Wire.write(0x00);
        Wire.write(0x00);
        Wire.write(0x00);
    }
    err = Wire.endTransmission();
    delay(70);
    if (err > 0)
    {
        Serial.printf("writeI2C Error Code: 0x0%d\n", err);
        return false;
    }
    else
        return true;
}

None of the dummy writes are outputting and the behavior is the same. The final two bytes should be: config[126] = 0x45 and config[127] = 0xC9, but my logic analyzer is shows that the transmission stops at 0x45 + ACK.

Within Wire.h.:
#define I2C_BUFFER_LENGTH 128

Changed the buffer length to 140 and it's working just fine.


text:
On initialising PWM with registers on my Due, why does unrelated duty cycle input influence my output?
I am finding that setting duty cycle on PWM channels 4 or 5 has an influence on whether channel 6 generates output. The following is a design of experiments view of my tests and results, where the outputs are measured on pins associated with PWM channels, high or low. PWM channels 4 and 7 appear not to have a high channel. The configuration allows for 2100 ticks per cycle, so 1050 is 50% and 1575 is 75%.
Why does duty cycle on PWM channels 4 or 5 affect the output of channel 6?
Why does setting a duty on channels 4 or 5 not yield output on those channels?
       Channels included in     Channels included in    Channels given duty cycle                     Measuered PWM Output on Pins/channels
Test   ASBR, PDR                CMR, CPRD               CDTYUPD                                       D6 (PWML7)    D7 (PWML6)    D8 (PWML5)    D9 (PWML4)    D44 (PWMH5)    D45 (PWMH6)
------|------------------------|-----------------------|--------------------------------------------||-------------|-------------|-------------|-------------|--------------|-----------
A      C24, C23, C22, C21       4, 5, 6, 7                       4: 1050, 5: 1050, 6: 1050, 7: 1575   75%           50%           0%            0%            0%             0%
B      C24, C23                 4, 5, 6, 7                       4: 1050, 5: 1050, 6: 1050, 7: 1575   75%           50%           0%            0%            0%             0%
C      C24, C23, C22, C21             6, 7                       4: 1050, 5: 1050, 6: 1050, 7: 1575   75%           50%           0%            0%            0%             0%
D      C24, C23                       6, 7                       4: 1050, 5: 1050, 6: 1050, 7: 1575   75%           50%           0%            0%            0%             0%
E      C24, C23, C22, C21       4, 5, 6, 7                                         6: 1050, 7: 1575   75%           0%            0%            0%            0%             0%
F      C24, C23                 4, 5, 6, 7                                         6: 1050, 7: 1575   75%           0%            0%            0%            0%             0%
G      C24, C23, C22, C21             6, 7                                         6: 1050, 7: 1575   75%           0%            0%            0%            0%             0%
H      C24, C23                       6, 7                                         6: 1050, 7: 1575   75%           0%            0%            0%            0%             0%
I      C24, C23                       6, 7                       4: 1050,          6: 1050, 7: 1575   75%           50%           0%            0%            0%             0%
J      C24, C23                       6, 7                                5: 1050, 6: 1050, 7: 1575   75%           50%           0%            0%            0%             0%
K      C24, C23                       6, 7              3: 1050,                   6: 1050, 7: 1575   75%           0%            0%            0%            0%             0%

Further Information:
Output to PWM7 is not necessary, so have simplified problem. Also the duty value set on channels 4 or 5 can be anything, so long as it is set.
void O_() {
  REG_PMC_PCER1 |= PMC_PCER1_PID36;
  REG_PIOC_ABSR |= PIO_ABSR_P23;
  REG_PIOC_PDR |= PIO_PDR_P23;
  REG_PWM_CLK = PWM_CLK_PREA(0) | PWM_CLK_DIVA(1);
  PWM->PWM_CH_NUM[6].PWM_CMR =  PWM_CMR_CPRE_CLKA;
  PWM->PWM_CH_NUM[6].PWM_CPRD = 2100;
  REG_PWM_ENA = PWM_ENA_CHID6;
  PWM->PWM_CH_NUM[4].PWM_CDTYUPD = 0; // Eliminating this line prevents output on channel 6 for some reason
  PWM->PWM_CH_NUM[6].PWM_CDTYUPD = 1050;
}

Original DOE source code:
void setup() {
  // put your setup code here, to run once:
  L_();
}

void A_() {
  REG_PMC_PCER1 |= PMC_PCER1_PID36;
  REG_PIOC_ABSR |= PIO_ABSR_P24 | PIO_ABSR_P23 | PIO_ABSR_P22 | PIO_ABSR_P21;
  REG_PIOC_PDR |= PIO_PDR_P24 | PIO_PDR_P23 | PIO_PDR_P22 | PIO_PDR_P21;
  REG_PWM_CLK = PWM_CLK_PREA(0) | PWM_CLK_DIVA(1);
  for (uint8_t i = 4; i < PWMCH_NUM_NUMBER; i++)
  {
    PWM->PWM_CH_NUM[i].PWM_CMR =  PWM_CMR_CPRE_CLKA;
    PWM->PWM_CH_NUM[i].PWM_CPRD = 2100;
  }
  REG_PWM_ENA = PWM_ENA_CHID7 | PWM_ENA_CHID6;

  PWM->PWM_CH_NUM[4].PWM_CDTYUPD = 1050;
  PWM->PWM_CH_NUM[5].PWM_CDTYUPD = 1050;
  PWM->PWM_CH_NUM[6].PWM_CDTYUPD = 1050;
  PWM->PWM_CH_NUM[7].PWM_CDTYUPD = 1575;
}

void B_() {
  REG_PMC_PCER1 |= PMC_PCER1_PID36;
  REG_PIOC_ABSR |= PIO_ABSR_P24 | PIO_ABSR_P23;
  REG_PIOC_PDR |= PIO_PDR_P24 | PIO_PDR_P23;
  REG_PWM_CLK = PWM_CLK_PREA(0) | PWM_CLK_DIVA(1);
  for (uint8_t i = 4; i < PWMCH_NUM_NUMBER; i++)
  {
    PWM->PWM_CH_NUM[i].PWM_CMR =  PWM_CMR_CPRE_CLKA;
    PWM->PWM_CH_NUM[i].PWM_CPRD = 2100;
  }
  REG_PWM_ENA = PWM_ENA_CHID7 | PWM_ENA_CHID6;

  PWM->PWM_CH_NUM[4].PWM_CDTYUPD = 1050;
  PWM->PWM_CH_NUM[5].PWM_CDTYUPD = 1050;
  PWM->PWM_CH_NUM[6].PWM_CDTYUPD = 1050;
  PWM->PWM_CH_NUM[7].PWM_CDTYUPD = 1575;
}

void C_() {
  REG_PMC_PCER1 |= PMC_PCER1_PID36;
  REG_PIOC_ABSR |= PIO_ABSR_P24 | PIO_ABSR_P23 | PIO_ABSR_P22 | PIO_ABSR_P21;
  REG_PIOC_PDR |= PIO_PDR_P24 | PIO_PDR_P23 | PIO_PDR_P22 | PIO_PDR_P21;
  REG_PWM_CLK = PWM_CLK_PREA(0) | PWM_CLK_DIVA(1);
  for (uint8_t i = 6; i < PWMCH_NUM_NUMBER; i++)
  {
    PWM->PWM_CH_NUM[i].PWM_CMR =  PWM_CMR_CPRE_CLKA;
    PWM->PWM_CH_NUM[i].PWM_CPRD = 2100;
  }
  REG_PWM_ENA = PWM_ENA_CHID7 | PWM_ENA_CHID6;

  PWM->PWM_CH_NUM[4].PWM_CDTYUPD = 1050;
  PWM->PWM_CH_NUM[5].PWM_CDTYUPD = 1050;
  PWM->PWM_CH_NUM[6].PWM_CDTYUPD = 1050;
  PWM->PWM_CH_NUM[7].PWM_CDTYUPD = 1575;
}

void D_() {
  REG_PMC_PCER1 |= PMC_PCER1_PID36;
  REG_PIOC_ABSR |= PIO_ABSR_P24 | PIO_ABSR_P23;
  REG_PIOC_PDR |= PIO_PDR_P24 | PIO_PDR_P23;
  REG_PWM_CLK = PWM_CLK_PREA(0) | PWM_CLK_DIVA(1);
  for (uint8_t i = 6; i < PWMCH_NUM_NUMBER; i++)
  {
    PWM->PWM_CH_NUM[i].PWM_CMR =  PWM_CMR_CPRE_CLKA;
    PWM->PWM_CH_NUM[i].PWM_CPRD = 2100;
  }
  REG_PWM_ENA = PWM_ENA_CHID7 | PWM_ENA_CHID6;

  PWM->PWM_CH_NUM[4].PWM_CDTYUPD = 1050;
  PWM->PWM_CH_NUM[5].PWM_CDTYUPD = 1050;
  PWM->PWM_CH_NUM[6].PWM_CDTYUPD = 1050;
  PWM->PWM_CH_NUM[7].PWM_CDTYUPD = 1575;
}

void E_() {
  REG_PMC_PCER1 |= PMC_PCER1_PID36;
  REG_PIOC_ABSR |= PIO_ABSR_P24 | PIO_ABSR_P23 | PIO_ABSR_P22 | PIO_ABSR_P21;
  REG_PIOC_PDR |= PIO_PDR_P24 | PIO_PDR_P23 | PIO_PDR_P22 | PIO_PDR_P21;
  REG_PWM_CLK = PWM_CLK_PREA(0) | PWM_CLK_DIVA(1);
  for (uint8_t i = 4; i < PWMCH_NUM_NUMBER; i++)
  {
    PWM->PWM_CH_NUM[i].PWM_CMR =  PWM_CMR_CPRE_CLKA;
    PWM->PWM_CH_NUM[i].PWM_CPRD = 2100;
  }
  REG_PWM_ENA = PWM_ENA_CHID7 | PWM_ENA_CHID6;

  PWM->PWM_CH_NUM[6].PWM_CDTYUPD = 1050;
  PWM->PWM_CH_NUM[7].PWM_CDTYUPD = 1575;
}

void F_() {
  REG_PMC_PCER1 |= PMC_PCER1_PID36;
  REG_PIOC_ABSR |= PIO_ABSR_P24 | PIO_ABSR_P23;
  REG_PIOC_PDR |= PIO_PDR_P24 | PIO_PDR_P23;
  REG_PWM_CLK = PWM_CLK_PREA(0) | PWM_CLK_DIVA(1);
  for (uint8_t i = 4; i < PWMCH_NUM_NUMBER; i++)
  {
    PWM->PWM_CH_NUM[i].PWM_CMR =  PWM_CMR_CPRE_CLKA;
    PWM->PWM_CH_NUM[i].PWM_CPRD = 2100;
  }
  REG_PWM_ENA = PWM_ENA_CHID7 | PWM_ENA_CHID6;

  PWM->PWM_CH_NUM[6].PWM_CDTYUPD = 1050;
  PWM->PWM_CH_NUM[7].PWM_CDTYUPD = 1575;
}

void G_() {
  REG_PMC_PCER1 |= PMC_PCER1_PID36;
  REG_PIOC_ABSR |= PIO_ABSR_P24 | PIO_ABSR_P23 | PIO_ABSR_P22 | PIO_ABSR_P21;
  REG_PIOC_PDR |= PIO_PDR_P24 | PIO_PDR_P23 | PIO_PDR_P22 | PIO_PDR_P21;
  REG_PWM_CLK = PWM_CLK_PREA(0) | PWM_CLK_DIVA(1);
  for (uint8_t i = 6; i < PWMCH_NUM_NUMBER; i++)
  {
    PWM->PWM_CH_NUM[i].PWM_CMR =  PWM_CMR_CPRE_CLKA;
    PWM->PWM_CH_NUM[i].PWM_CPRD = 2100;
  }
  REG_PWM_ENA = PWM_ENA_CHID7 | PWM_ENA_CHID6;

  PWM->PWM_CH_NUM[6].PWM_CDTYUPD = 1050;
  PWM->PWM_CH_NUM[7].PWM_CDTYUPD = 1575;
}

void H_() {
  REG_PMC_PCER1 |= PMC_PCER1_PID36;
  REG_PIOC_ABSR |= PIO_ABSR_P24 | PIO_ABSR_P23;
  REG_PIOC_PDR |= PIO_PDR_P24 | PIO_PDR_P23;
  REG_PWM_CLK = PWM_CLK_PREA(0) | PWM_CLK_DIVA(1);
  for (uint8_t i = 6; i < PWMCH_NUM_NUMBER; i++)
  {
    PWM->PWM_CH_NUM[i].PWM_CMR =  PWM_CMR_CPRE_CLKA;
    PWM->PWM_CH_NUM[i].PWM_CPRD = 2100;
  }
  REG_PWM_ENA = PWM_ENA_CHID7 | PWM_ENA_CHID6;

  PWM->PWM_CH_NUM[6].PWM_CDTYUPD = 1050;
  PWM->PWM_CH_NUM[7].PWM_CDTYUPD = 1575;
}

void I_() {
  REG_PMC_PCER1 |= PMC_PCER1_PID36;
  REG_PIOC_ABSR |= PIO_ABSR_P24 | PIO_ABSR_P23;
  REG_PIOC_PDR |= PIO_PDR_P24 | PIO_PDR_P23;
  REG_PWM_CLK = PWM_CLK_PREA(0) | PWM_CLK_DIVA(1);
  for (uint8_t i = 6; i < PWMCH_NUM_NUMBER; i++)
  {
    PWM->PWM_CH_NUM[i].PWM_CMR =  PWM_CMR_CPRE_CLKA;
    PWM->PWM_CH_NUM[i].PWM_CPRD = 2100;
  }
  REG_PWM_ENA = PWM_ENA_CHID7 | PWM_ENA_CHID6;

  PWM->PWM_CH_NUM[4].PWM_CDTYUPD = 1050;
  PWM->PWM_CH_NUM[6].PWM_CDTYUPD = 1050;
  PWM->PWM_CH_NUM[7].PWM_CDTYUPD = 1575;
}

void J_() {
  REG_PMC_PCER1 |= PMC_PCER1_PID36;
  REG_PIOC_ABSR |= PIO_ABSR_P24 | PIO_ABSR_P23;
  REG_PIOC_PDR |= PIO_PDR_P24 | PIO_PDR_P23;
  REG_PWM_CLK = PWM_CLK_PREA(0) | PWM_CLK_DIVA(1);
  for (uint8_t i = 6; i < PWMCH_NUM_NUMBER; i++)
  {
    PWM->PWM_CH_NUM[i].PWM_CMR =  PWM_CMR_CPRE_CLKA;
    PWM->PWM_CH_NUM[i].PWM_CPRD = 2100;
  }
  REG_PWM_ENA = PWM_ENA_CHID7 | PWM_ENA_CHID6;

  PWM->PWM_CH_NUM[5].PWM_CDTYUPD = 1050;
  PWM->PWM_CH_NUM[6].PWM_CDTYUPD = 1050;
  PWM->PWM_CH_NUM[7].PWM_CDTYUPD = 1575;
}

void K_() {
  REG_PMC_PCER1 |= PMC_PCER1_PID36;
  REG_PIOC_ABSR |= PIO_ABSR_P24 | PIO_ABSR_P23;
  REG_PIOC_PDR |= PIO_PDR_P24 | PIO_PDR_P23;
  REG_PWM_CLK = PWM_CLK_PREA(0) | PWM_CLK_DIVA(1);
  for (uint8_t i = 6; i < PWMCH_NUM_NUMBER; i++)
  {
    PWM->PWM_CH_NUM[i].PWM_CMR =  PWM_CMR_CPRE_CLKA;
    PWM->PWM_CH_NUM[i].PWM_CPRD = 2100;
  }
  REG_PWM_ENA = PWM_ENA_CHID7 | PWM_ENA_CHID6;

  PWM->PWM_CH_NUM[3].PWM_CDTYUPD = 1050;
  PWM->PWM_CH_NUM[6].PWM_CDTYUPD = 1050;
  PWM->PWM_CH_NUM[7].PWM_CDTYUPD = 1575;
}

void L_() {
  REG_PMC_PCER1 |= PMC_PCER1_PID36;
  REG_PIOC_ABSR |= PIO_ABSR_P24 | PIO_ABSR_P23 | PIO_ABSR_P22 | PIO_ABSR_P21;
  REG_PIOC_PDR |= PIO_PDR_P24 | PIO_PDR_P23 | PIO_PDR_P22 | PIO_PDR_P21;
  REG_PWM_CLK = PWM_CLK_PREA(0) | PWM_CLK_DIVA(1);
  for (uint8_t i = 4; i < PWMCH_NUM_NUMBER; i++)
  {
    PWM->PWM_CH_NUM[i].PWM_CMR =  PWM_CMR_CPRE_CLKA;
    PWM->PWM_CH_NUM[i].PWM_CPRD = 2100;
  }
  REG_PWM_ENA = PWM_ENA_CHID7 | PWM_ENA_CHID6;

  PWM->PWM_CH_NUM[4].PWM_CDTYUPD = 1050;
  PWM->PWM_CH_NUM[5].PWM_CDTYUPD = 1050;
  PWM->PWM_CH_NUM[6].PWM_CDTYUPD = 1050;
  PWM->PWM_CH_NUM[7].PWM_CDTYUPD = 1575;
}

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

}


text:
Using IN1/ IN2 pins for PWM instead of ENA in L298N
So basically i tried providing PWM directly to the IN1/IN2 Of L298n motor driver instead of using ENA pin i got more or less the same result
Im using ESP32 with 30000Hz freq for my PWM
My question is if both ways it can be used why aren't people using this method? Or am i missing something?
I would love to know the reason if someone has any idea about it.

"why aren't people using this method?" It's not true, it's a widley used method.

When using only IN1/2 to control speed and direction, you must apply PWM to IN1 for one direction and to IN2 for the other direction, while the other pin will be connected to ground. This method is easy to implement with a MCU but uses two PWM channels.I think the EN pin is used for applications without MCUs or where there is only one PWM channel. In these situations, pins IN1/2 are used for STOP/CW/CCW selection and EN for speed from a single PWM source.


text:
external power supply for servo motor attached to redboard arduino
I'm new to this page but I was hoping to get some advice on a servo motor arduino project I'm currently working on.
I have a HS-815BB servo motor (4.8~6V, max stall current draw 6,000mA) and a Spark Fun Redboard. I know I should hook up an external power supply to my servo motor to avoid frying my board. I've seen x4 AAA battery packs that can output 6V, as well as breadboard power supply modules with 3.3V/5V output. However, the breadboard power supply module has a max output current of 700mA and I'm not sure about the battery pack.
Where can I find a power supply that is arduino compatible and outputs ~6V while having a max current draw of 6A or over? Am I looking for the right thing?
Thanks in advance

With 6A you are at a very high current.
First about the batteries: I wouldn't trust in 4 AAA batteries in supporting that high of a current. You may get away with it, if you only have very short bursts of 6A, but I guess the voltage will take a significant dip here. I would look into LiIon or LiPo battery packs, like the ones used for drones (which also can have high current spikes). But please take care to also use a fitting charging circuit. You can find many resources about that on the web.
Now about the breadboard: Just don't pull 6A through a breadboard! Breadboards are not made for currents this high. The contacts have a resistance that is significant in this situation and the metal strips used in there are also not meant for carrying that much. Going over 1A is probably no good for a breadboard. Instead you should connect the power supply outside of the breadboard by soldering or using proper connectors, which can handle the current. You can hook up your breadboard power regulator to the same battery if you want to provide it from the same source.

Where can I find a power supply that is arduino compatible and outputs ~6V while having a max current draw of 6A or over?

There is no "Arduino compatibility" with power supplys. For the Arduino its just about having the correct voltage and being able to provide the needed current to the Arduino (excluding the servo, since it shouldn't be plugged into the breadboard in the first place). When you use a battery and also want to charge it in your circuit, then you need to find a charger board compatible with your chosen battery. Often these boards also have a voltage regulator from which you can get the 5V that you need to power an Arduino. Otherwise you can buy voltage regulator boards, which can take a full range of input voltages and output a regulated voltage of your liking (controlled via a small potentiometer on the board). These can also be used if you want to use a power supply connected to mains (like the often seen 12V power supplies for LED strips).
So called "breadboard power supply modules" are often not more than a board with pins in positions fitting for a breadboard. They are a pure convenience product. You can also solder pin to the cable of power source and put these into the breadboard. Sometimes these boards also have a voltage regulator, which you can also get without the breadboard connector part.


text:
I have some problem with 433 MHz transmitter
I want to transfer float data between two Arduinos. This is what I sent:
0.00
0.00
0.00
0.00
-9.06
-9.80
16.85
16.24
0.00
-16.93
8.13
0.00
0.00

And this is what I received:
 0.001****8u
  0.001****8u
  0.001****8u
  0.001****8u
 -9.061****8u
 -9.801****8u
 16.851****8u
 16.241****8u
  0.001****8u
-16.931****8u
  8.131****8u
  0.001****8u
  0.001****8u

The code I have uploded in sender and receiver:
Sender:
#include <RH_ASK.h>
#include <SPI.h> // Not actually used but needed to compile
#include <Wire.h>
#include <MPU6050.h>

MPU6050 mpu;

RH_ASK driver;

void setup() {
  while(!mpu.begin(MPU6050_SCALE_2000DPS, MPU6050_RANGE_2G)) {
    Serial.println("Could not find a valid MPU6050 sensor, check wiring!");
    delay(500);
  }
  Serial.begin(9600);    // Debugging only
  if (!driver.init())
    Serial.println("init failed");

  mpu.calibrateGyro();
  mpu.setThreshold(3);
}

void loop() {
  Vector rawGyro = mpu.readRawGyro();
  Vector normGyro = mpu.readNormalizeGyro();
  char msg = "";
  dtostrf(normGyro.XAxis, 6, 2,msg);
  driver.send((uint8_t *)msg, strlen(msg));
  driver.waitPacketSent();
  Serial.println(normGyro.XAxis);
}

Receiver:
#include <RH_ASK.h>
#include <SPI.h> // Not actualy used but needed to compile

RH_ASK driver;

void setup() {
  Serial.begin(9600);  // Debugging only
  if (!driver.init())
    Serial.println("init failed");
}

void loop() {
  uint8_t buf[12];
  uint8_t buflen = sizeof(buf);
  if (driver.recv(buf, &buflen)) { // Non-blocking
    int i;
    // Message with a good checksum received, dump it.
    Serial.println((char*)buf);
  }
}

Can anyone tell me what is wrong?

Please print the msg string in your sender code and then include that output in your question too. That way we can see what exactly you send over radio.

i had actually done this , the first msg was the printed one from the first arduino

Actually no, you printed normGyro.XAxis and not msg. You don't send normGyro.XAxis. You send a string representation of it, which is saved in msg. Thus please print msg in the sender code. That way we can see if the difference lies in the creation of the string representation or in the transmission.

look at this https://www.mediafire.com/view/mrb6c9ua3qfdwzb/%25D8%25AA%25D8%25B5%25D9%2588%25DB%258C%25D8%25B1_%25D8%25B5%25D9%2581%25D8%25AD%25D9%2587_2022-02-18_162300.png/file

Oh, I've overlooked an error in your receiver code char msg = "" needs to be char msg[10] = "". The first version is a single character, which you try to assign a string. The second version can actually hold a string (up to 9 characters + the terminating null character). Please try again with that change. And please don't post links to images of text. Instead you can edit your question and copy and paste the text directly in there, formatting it as code, just as you did before.

No links please. Edit your question

it fix the output of sender but the output of reciever is still the same as before

any one knows ?NO ONE ?


text:
Serial read and send to UDP?
I was trying to send whatever is received from serial by udp, but it doesn't work properly.
the receiver side showing number 50 51 53 ..... the result like below screenshot:

can anyone help me please to fix ?
sender sketch:
#include <ESP8266WiFi.h>
#include <WiFiUdp.h>

const char* ssid = "MikroTik";
const char* password = "12345678";
unsigned int localPort = 2390;

WiFiUDP Udp;
void setup() {
  delay(1000);
  Serial.begin(115200);
  WiFi.begin(ssid, password);
  Udp.begin(localPort);
}

void loop() {
  Udp.beginPacket("10.5.50.23", localPort);
  int val = Serial.read();
  Udp.print(val);
  Udp.endPacket();
  delay(10);
}

receiver sketch:
#include <ESP8266WiFi.h>
#include <WiFiUdp.h>

const char* ssid = "MikroTik";
const char* password = "12345678";
unsigned int localPort = 2390;
char packetBuffer[255];
WiFiUDP Udp;

void setup() {
  Serial.begin(115200);
  WiFi.begin(ssid, password);
    while (WiFi.status() != WL_CONNECTED){
    delay(500);
    Serial.print(".");
  }
  Udp.begin(localPort);
}

void loop() {
  delay(10);
  if (Udp.parsePacket()) {
    int len = Udp.read(packetBuffer, 255);
    if (len > 0) {
      packetBuffer[len] = 0;
      Serial.println(packetBuffer);
    }
  }
}

thanks for reply. sorry I'm new to coding arduino can you help me and edit my code to working properly ?

What help do you need exactly? I explained that you should replace Udp.print() by Udp.write(). Further edits depends on what you want the code to do. You did describe that.

ok I changed to Udp.write(val) but on the receiver side only show first number of serial read side.
for example Instead of showing the number 300, it displays the number 3

Thats the part about reading up to a delimiter character. For example you could use Serial.readStringUntil('\n') for this. It is a blocking function, but that should be ok for your case. Sorry, but I won't write the code for you. There are lots of example codes and tutorials on the web about that. You can also look at the SerialEvent example, that comes with the Arduino IDE

Besides the issues with the code, I hope you understand that UDP is not a "reliable" protocol. It doesn't guarantee that you'll receive everything that's sent, and it won't tell you if something gets dropped.

The problem is with the different interpretations of the binary data and lies in these two lines:
int val = Serial.read();
Udp.print(val);

What you write into the Serial Monitor is ASCII encoded text. Each byte of data corresponds to one character. If you write an a this is taken as the ASCII representation. In hexadecimal this character is 0x61 and in decimal 97. Thats the actual value that gets transmitted to the ESP over Serial. Then you read that into an integer. SO val would have the value 97. Then you use Udp.print(val). All print() functions are there for producing a human readable representation of the data, meaning ASCII encoded (Thats a standard Arduino convention). So basically you said here: "Here you have a number (integer). Print it into the UDP packet in human readable (ASCII) form." So the UDP packet now contains the ASCII string "97". You probably typed the digit 5 and then 4 a few times. Their decimal values are 53 and 52.
There probably also is a function called Udp.write(). The write() functions by convention don't change the data. They just write it without interpretation. So by using Udp.write() the actual binary value of the received data would be send and the letter a would appear as letter a in the Serial output of the receiver.
This works good as long as you only want to send single bytes in your packets. Also note, that Serial.read() will return -1 if there is no data to read in the buffer. So to handle that you need to step up the sender code:

Only read from Serial, if there is actually data in the buffer. You can use an if statement for this like:
  if(Serial.available()){ // read in this if statement

Read all data from Serial up to a specific delimiter character, which marks the end of a complete message. Typically the newline character \n is used for that. You can configure the Serial Monitor to use newline as line ending (it then gets appended to the typed text when you press Enter). There are a lot of example codes for this on the web.


text:
How to calibrate an accelerometer?
I'm confused about a few points on how to best calibrate an accelerometer, whose data will be used in an orientation sensor fusion algorithm.
As a summary, the most common approaches I've seen take measurements in 6 different orientations (1G in +x, -x, +y, -y, +z, -z), to then arrive at a max, min measured value. Offsets are then calculated as averages: (max - min)/2. And then a scaling factor is calculated. There's a few aspects of this that I'm unclear about, and was hoping it's okay to ask in a single question, since they are related.
1) the examples calculate the average as written above, rather than sum all vals / N vals. Isn't that approach more error-prone?
2) should the offset per axis be calculated once for each orientation, and then summed?
3) what's the best approach to calculate scale bias?
Example 1 (pseudo-code):
chordlengthX = (max - min)/2
chordlengthY = (max - min)/2
chordlengthZ = (max - min)/2

avg_rad = (chordlengthX + chordlengthY + chordlengthZ)/3

scaleX = avg_rad/chordlengthX

calibratedX = (x - offset)*scaleX

Example 2:
rawrange = max - min
refrange = refmax - refmin // 1G??

calibratedX = (((x - min)*refrange)/rawrange) +refmin

Something else altogether (as you can probably tell I need to revise my maths)?
4) if my surface is not completely level, I cannot trust my measurements since my 1G reference is not accurate?

Most accelerometers are usable out of the box.  (It is the magnetometers that are difficult to use w/o calibration.)
That said, example 1 looks good until the last line.  You need an x-offset which is simply the difference between the x-maximum and x-minimum.
Consider how the coordinates of the X, Y and Z values of an accelerometer would appear if plotted in 3D space.  One that is perfectly aligned would appear spherical.  But if one of the sensors is more sensitive than the others, the 3D plot might take on an egg shape.  You have corrected for this in the first 5 lines of example 1.
Now, if one of the sensors is not centered the 3D plot would be shifted off the 0,0,0 point of the 3D plot.  You can correct for that by finding the  x-offset, y-offset and z-offset.
You should not need to find the value for 1G.  You should not need to find a perfectly flat surface. To calibrate you need to rotate the accelerometer smoothly about its center.  Take care not to expose the accelerometer to greater than 1G during calibration.  Rotate the accelerometer in a random fashion until you are satisfied that all 3 sensors have experienced their most negative and most positive values.

Thank you for taking the time to answer. Apologies for being dumb, but still confused about a couple of points. What's the error in the last line of example 1? From my understanding of your explanation, it seems it should be correct. We subtract bias, and then multiply by the sensitivity? I'm probably missing something. Secondly, if the sensor is moving about the wouldn't the maximum and minimum just be the range from the datasheet, for example if I'm yanking it about quite quickly?

It would be good if you carefully selected your variable names.  Even in fake code.  It was easy to assume the 6 "max" & "min" values were actually "x-maximum", "x-minimum", "y-maximum", "y-minimum", ect.  But I did not know what "x" was in the last line of example 1.  If I needed to guess, I think the last line is an example of how to use the 2 calibration values you seek.  And might be written: "calibratedX = (x-raw - x-offset) * scaleX".  Take care to smoothly rotate the accelerometer during calibration. Do not expose it to > 1G by jerking it around. Again, calibration may not be necessary.

Thank you again for taking the time to help out. I really appreciate it. I'll test this tomorrow and see how it goes. :)


text:
Safely extend TCNT1 / ICR1 to 24 bits using TOV1
I'm hoping to time external events on a '328p Arduino that will occur slowly enough that they'll overflow the 16-bit counter TCNT1. In a different scenario I'd prescale the counter, but I need the full timer resolution in this case for other purposes.
So I enable the TOV1 interrupt and just increment an 8-bit value, letting it roll over as needed.
Then on an ICP1 interrupt, I shift this value << 16 into a 32-bit variable, and add in the value captured in ICR1, yielding a 24-bit value that I can use to measure the slow interval.
Are there hidden gotchas in this plan? Possible race conditions where TOV1 hasn't yet been updated if ICR1 is latched just when TCNT1 has just rolled over, or generates a TOV1 after capturing ICR1 but before I shift in the overflow count?

There is, indeed, a possible race condition. Consider this naive code,
which provides 32-bit timestamps:
/* Count overflows. */
volatile uint16_t timer1_overflow_count;
ISR(TIMER1_OVF_vect)
{
    timer1_overflow_count++;
}

/* Timestamp input events. */
volatile uint32_t captured_timestamp;
volatile bool did_capture;
ISR(TIMER1_CAPT_vect)
{
    captured_timestamp = timer1_overflow_count << 16 | ICR1;
    did_capture = true;
}

Since TIMER1_CAPT has higher priority than TIMER1_OVF, then:

If ICF1 rises before TOV1, TIMER1_CAPT_vect runs first, which
is fine.

If ICF1 and TOV1 rise simultaneously, TIMER1_CAPT_vect runs
first, which is still fine, as the captured value is 0xffff.

If TOV1 rises before ICF1, either ISR may run first:

if the CPU can process the TIMER1_OVF IRQ right away, then
TIMER1_OVF_vect runs first and the result is correct

if the interrupt processing is delayed until after ICF1 has
risen, then TIMER1_CAPT_vect runs first and grabs a wrong value
for timer1_overflow_count.

Solution
There is an unhandled overflow when bit_is_set(TIFR1, TOV1). The
overflow may have happened at the same time or after the capture, in
which case it doesn't affect the timestamp. We know it happened before
the capture when the captured value is small, where “small” could be
defined as having its most significant bit clear. If this is the case,
we have to add 0x10000 to the timestamp we obtained.
A race-proof ISR can be written as follows:
ISR(TIMER1_CAPT_vect)
{
    uint16_t captured_low = ICR1;
    uint16_t captured_high = timer1_overflow_count;
    if (bit_is_set(TIFR1, TOV1) && !(captured_low & 0x8000)) {
        captured_high++;
    }
    captured_timestamp = (uint32_t) captured_high << 16 | captured_low;
    did_capture = true;
}

Thanks for your analysis. I get everything about your solution except the phrase we have to add 0x0100 to the timestamp. In code you (effectively) add 0x10000, which is what I'd expect for a missed overflow. Typo?

@JimMack: Oops! You are right, I made a typo. Fixed, thanks!


text:
Why does the official tutorial for LED matrix scanning writes column pin twice?
I was following the official tutorial and confused by the source code.
Arduino Official built-in example: RowColumnScanning
// when the row is HIGH and the col is LOW,
// the LED where they meet turns on:
digitalWrite(col[thisCol], thisPixel);
// turn the pixel off:
if (thisPixel == LOW) {
  digitalWrite(col[thisCol], HIGH);
}

Here is my understanding:

If thisPixel is LOW, the pin col[thisCol] would be HIGH.
If thisPixel is HIGH, the pin col[thisCol] would still be HIGH.

Question
Because it col[thisCol] is always HIGH regardless of thisPixel, does it make sense to have an extra if statement?
In case the URL is dead

/*
  Row-Column Scanning an 8x8 LED matrix with X-Y input

  This example controls an 8x8 LED matrix using two analog inputs.

  This example works for the Lumex LDM-24488NI Matrix. See
  https://sigma.octopart.com/140413/datasheet/Lumex-LDM-24488NI.pdf
  for the pin connections.

  For other LED cathode column matrixes, you should only need to change the pin
  numbers in the row[] and column[] arrays.

  rows are the anodes
  cols are the cathodes
  ---------

  Pin numbers:
  Matrix:
  - digital pins 2 through 13,
  - analog pins 2 through 5 used as digital 16 through 19
  Potentiometers:
  - center pins are attached to analog pins 0 and 1, respectively
  - side pins attached to +5V and ground, respectively

  created 27 May 2009
  modified 30 Aug 2011
  by Tom Igoe

  This example code is in the public domain.

  https://www.arduino.cc/en/Tutorial/BuiltInExamples/RowColumnScanning
*/

// 2-dimensional array of row pin numbers:
const int row[8] = {
  2, 7, 19, 5, 13, 18, 12, 16
};

// 2-dimensional array of column pin numbers:
const int col[8] = {
  6, 11, 10, 3, 17, 4, 8, 9
};

// 2-dimensional array of pixels:
int pixels[8][8];

// cursor position:
int x = 5;
int y = 5;

void setup() {
  // initialize the I/O pins as outputs iterate over the pins:
  for (int thisPin = 0; thisPin < 8; thisPin++) {
    // initialize the output pins:
    pinMode(col[thisPin], OUTPUT);
    pinMode(row[thisPin], OUTPUT);
    // take the col pins (i.e. the cathodes) high to ensure that the LEDS are off:
    digitalWrite(col[thisPin], HIGH);
  }

  // initialize the pixel matrix:
  for (int x = 0; x < 8; x++) {
    for (int y = 0; y < 8; y++) {
      pixels[x][y] = HIGH;
    }
  }
}

void loop() {
  // read input:
  readSensors();

  // draw the screen:
  refreshScreen();
}

void readSensors() {
  // turn off the last position:
  pixels[x][y] = HIGH;
  // read the sensors for X and Y values:
  x = 7 - map(analogRead(A0), 0, 1023, 0, 7);
  y = map(analogRead(A1), 0, 1023, 0, 7);
  // set the new pixel position low so that the LED will turn on in the next
  // screen refresh:
  pixels[x][y] = LOW;

}

void refreshScreen() {
  // iterate over the rows (anodes):
  for (int thisRow = 0; thisRow < 8; thisRow++) {
    // take the row pin (anode) high:
    digitalWrite(row[thisRow], HIGH);
    // iterate over the cols (cathodes):
    for (int thisCol = 0; thisCol < 8; thisCol++) {
      // get the state of the current pixel;
      int thisPixel = pixels[thisRow][thisCol];
      // when the row is HIGH and the col is LOW,
      // the LED where they meet turns on:
      digitalWrite(col[thisCol], thisPixel);
      // turn the pixel off:
      if (thisPixel == LOW) {
        digitalWrite(col[thisCol], HIGH);
      }
    }
    // take the row pin low to turn off the whole row:
    digitalWrite(row[thisRow], LOW);
  }
}

It prevents ghosting when the next row is brought high ... also reduces the overall current  because only one LED is lit at any one time

Would you mind to copy the complete sketch into your question, please? External resources tend to vanish... and we like to help future readers understand the issue completely.

@thebusybee Thanks for the reminder. I have updated the question.

You are right, the if does not make sense. Not all tutorials are correct, and even if, they are often not very good.
The reason for the second digitalWrite() is to switch the pixel off after it was potentially on. If it stays on when the row is changed, you could see ghosting.
However, I would switch all pixel of a row, delay a bit, and then in a second loop, switch them all off again, before I process the next row.

I'm going to split this answer into two parts, the first about matrix displays in general, and the latter considering this particular dubious example.
The fundamental idea of a matrix display is that the LEDs don't need to be on continuously. If they are illuminated sufficiently often and for a sufficient proportion of the time, then the human eye will average things out.
Exactly what "sufficiently often", and a "sufficient proportion" of the time are can be hard to pin down. The former depends on the particular person viewing, but I would aim for at least 100Hz. The latter depends mostly on how bright your LEDs are when turned on (more on that later).
This is useful because it saves you a lot of IO lines, if you wanted individual control of 256 LEDs you would need 256 IO lines. By using a row/column matrix you only need 16. Of course with a row/colum matrix, it isn't possible to illuminate all combinations of LEDs at the same time, but that doesn't actually matter because as long as you illuminate each active LED sufficiently often the human eye won't notice the difference.
It's good practice to turn off the LEDs that you have turned on for one row before moving on to the next row. Otherwise you can get "ghosting" where an unintended LED illuminates. How much of a problem ghosting is in practice depends heavily on the specifics of your matrix drive code.

Several things however set this example apart from a "Normal" matrix drive implementation.

This example only lights a single LED at a time. Most matrix drive implementations light a whole row (or column) at a time. That means the LEDs are illuminated a much greater proportion of the time, it does have downsides though, it means your row drivers have to have enough current drive capacity to drive a whole row at once.
This example has no series resistors! the current through the LEDs is limited only by the internal resistance of the LEDs and the IO pin drivers in the AVR. This likely results at the LEDs and the GPIO pins operating significantly above their nominal max current!
There is nothing to control the timing in the code, and the LED on time is very short. Depending on how well the compiler optimizes the code, it may only be a few clock cycles.

Some of these factors cancel each other out, the drive current is likely very high, but it's only applied very briefly and only to one LED at a time. So the overall result is likely that nothing gets fried and the display has a usable brightness.
But nevertheless, I think it's the sort of example that gets Arduino a bad name. It presumably works (or it wouldn't have been posted), but it's driving components out of specification, and the brightness of the display is totally at the mercy of poorly specified internal resistances and code execution speed.


text:
Can the Blink class be used on a 5v to 240v relay?
I have found the following code and it works fine on a breadboard controlling small LEDs but I want it to work with LED strip lighting with external 240v transformers. We have built the circuit using a 5v to 240v relay and the connections are functional but the code does not seem to translate. Does the built in blink class in Arduino function with relays? As it is either High or Low with no variation in voltage I don't see why it wouldn't work as a switch. Has anyone got any suggestions?
Thank you
class LED
{
  public :

    LED();

    void init( uint8_t pin );

    void update();

    void toggle( bool const on );
    void on()  { toggle( true  ); };
    void off() { toggle( false ); };

    void blink( uint16_t const * const pattern, size_t const length, int8_t const count = -1 );
    void blink( uint16_t const timeOn = 1000, uint16_t const timeOff = 1000, int8_t const count = -1 );
    void flash( uint16_t const timeOn );

  private :

    uint8_t          m_pin;
    bool             m_isOn;
    uint32_t         m_millis;
    uint16_t         m_time;
    int8_t           m_count;
    uint16_t const * m_patternPtr;
    uint16_t         m_pattern[2];
    size_t           m_patternLength;
    size_t           m_patternIndex;

    void write( bool const on );
};

LED::LED()
: m_pin           ( 255 )
, m_isOn          ( false )
, m_millis        ( 0 )
, m_time          ( 0 )
, m_count         ( 0 )
, m_patternPtr    ( nullptr )
, m_pattern       { 0, 0 }
, m_patternLength ( 0 )
, m_patternIndex  ( 0 )
{
}

void LED::init( uint8_t pin )
{
  m_pin = pin;
  pinMode( pin, OUTPUT );
  write( false );
}

void LED::toggle( bool const on )
{
  m_count = 0;
  m_patternPtr = nullptr;
  m_patternIndex = 0;
  m_patternLength = 0;
  write( on );
}

void LED::write( bool const on )
{
  m_isOn = on;
  digitalWrite( m_pin, on ? HIGH : LOW );
}

void LED::blink( uint16_t const * const pattern, size_t const length, int8_t const count )
{
  if ( count != 0 && length > 0 && pattern != nullptr )
  {
    write( true );
    m_millis = millis();
    m_count = count;
    m_patternPtr = pattern;
    m_patternLength = length;
    m_patternIndex = 0;
    m_time = m_patternPtr[0];
  }
}

void LED::blink( uint16_t const timeOn, uint16_t const timeOff, int8_t const count )
{
  m_pattern[0] = timeOn;
  m_pattern[1] = timeOff;
  blink( m_pattern, 2, count );
}

void LED::flash( uint16_t const timeOn )
{
  m_pattern[0] = timeOn;
  blink( m_pattern, 1, 1 );
}

void LED::update()
{
  if ( m_count != 0 && millis() - m_millis >= m_time )
  {
    if ( m_patternLength == 1 )
    {
      toggle( false );
    }
    else if ( ++m_patternIndex < m_patternLength )
    {
      m_time = m_patternPtr[ m_patternIndex ];
    }
    else
    {
      if ( m_count != -1 )
      {
        m_count--;
      }

      if ( m_count == 0 )
      {
        toggle( false );
      }
      else
      {
        m_patternIndex = 0;
        m_time = m_patternPtr[0];
      }
    }

    if ( m_count != 0 )
    {
      m_millis = millis();
      write( !m_isOn );
    }
  }
}

LED led1;
LED led2;
LED led3;

void setup()
{
  led1.init( 10 );
  led2.init( 11 );
  led3.init( 9 );

  // 2 flashs toutes les secondes           on   off    on   off
  static const uint16_t led1_pattern[] = { 100,  100,  2000,  400, 5000, 5000, 1000, 200 };
  led1.blink( led1_pattern, 8 );

  // 2 flashs toutes les deux secondes      on   off    on   off
  static const uint16_t led2_pattern[] = { 2000,  100,  250, 1400, 2000, 400, 800  };
  led2.blink( led2_pattern, 8);

 // 2 flashs toutes les secondes           on   off    on   off
  static const uint16_t led3_pattern[] = { 100,  5000,  2000,  400, 5000, 500, 1000, 2000 };
  led3.blink( led3_pattern, 8 );

}

void loop()
{
  led1.update();
  led2.update();
  led3.update();
}

the whole library reduces to digitalWrite( ) ... that command actually sets the state of a hardware pin ... the library is actually irrelevant to controlling a 250 V light ... build a circuit that allows a GPIO pin to control a light ... test with digitalWrite( ) command ... if that works, then the library should also work

Post a schematic of your 240V circuit. Transformers do not like to be cycled as fast as you appear to be doing.  Not all lights will work either.


text:
Arduino HX711 load cell lots of drift
I am trying to make this 50kg load cell work with this HX711 chip. I currently have the following connections :

Load cell red -> E+
Load cell black -> E-
Load cell white -> A-
Load cell green -> A+

I am using this library and this code :
#include "HX711.h"

#define calibration_factor -7050

HX711 scale;

void setup()
{
  Serial.begin(9600);
  scale.begin(2, 3);
  scale.set_scale(calibration_factor);
  scale.tare();
}

void loop()
{
  Serial.println(scale.get_units(1));
  delay(100);
}

The load cell appears to register load changes but the value is constantly going up (or down if the calibration_factor is positive). The value change rate is very high (from 0 to 300 in a couple of seconds).
Edit : I have 2 load cells and both of them do the same thing (with different HX711 chips).
Edit 2 : My question is : has anyone experienced this ? Or does anyone have an idea as to why this is happening ?

what is your specific question?

Oups ! I edited the question @jsotola

The solution was to solder all the wires, now the drift seems to be very minimal or non existant.


text:
Flight controller board Reprogram
Recently in my scrap yard visits, more and more I find cheap quad-copters and remote controllers of all kind. I have built up quite a collection of boards and spare parts to create my own army of drones.
Now, my question is, how can I access the microprocessor on the board to upload code, say MultiWii, Ardupilot or similar.
I know every board is different, but very often I see STM32 processors on these boards, with I2c connections available.
Should there be also TX and Rx pins for USB communication in order to flash the controller? Or can it be done with I2c and an arduino as a master?

Have you googled on how to program a standalone STM32? Tx and Rx are commonly for UART interfaces and has nothing to do with USB. For programming over serial you need a bootloader on the chip

Well, of course one does his fair bit of research before asking a question...

Have you seen this guide. It explains how to flash an STM32 via the SWD/JTAG interface. You need an SWD/JTAG debugger to do this. Does that help?

No, that is one of the many things I have probably missed, it explains exactly what to do. Thank you.