body:
I am attempting to read and write from/to an EEPROM chip, and have got access to [this][1] 64 kbit device.

It appears I can write to the device and read from it, but there appears to be some strangeness around addressing the written data for later writing.

I am using [this][2] page as a reference for my code, and getting some strange results. For starters, the 64 kbit is in fact 8k, and I was able to write to the 10000 the byte and read from it (though I suspect it rolled over on the memory address).

The strangeness was when I attempted to write two adjacent bytes to two adjacent addresses. The subsequent read of the two addresses read the second byte both times. It was as if the location pointer was stuck on the last read.

when I reset my code, I can read the previously written addresses, confirming they are not just stuck in memory.

Similarly when I write an array of bytes to an address, I can read back the bytes, but if I change the read pointer to read again, the bytes are returned all the same, until the pointer goes a significant distance away from the read address (over say 50 bytes). At this point the return data is all 255.

Finally if I read many bytes, requesting say 50, the most I get back is 32 bytes.

Say I write:

    [60, 61, 62, 63, 64, 65] to position 8000 in memory

if I attempt to read from the address or addresses near it or anywhere else, I either get the exact bytes I wrote at whatever position I request, or I get nothing (all 255).

I have managed to read old data from other locations from previous compiles, so the data is for sure in the chip, just accessing it seems uncertain.

Some read results:

    7000: [255, 255, ..., 255]
    7500: [255, 255, ..., 255]
    7980: [60, 61, 62, 63, 64, 65, 255, 255, ..., 255]
    8040: [60, 61, 62, 63, 64, 65, 255, 255, ..., 255]
    7960: [60, 61, 62, 63, 64, 65, 255, 255, ..., 255]
    8060: [60, 61, 62, 63, 64, 65, 255, 255, ..., 255]
    7940: [60, 61, 62, 63, 64, 65, 255, 255, ..., 255]
    8500: [255, 255, ..., 255]
    8150: [60, 61, 62, 63, 64, 65, 255, 255, ..., 255]

Code:

      const int memoryI2CAddress = 0x50;

      void Initialise() {
        Wire.begin();
        Test();
      }

      void Test() {
        unsigned int baseAddress = 8000;
        byte data[6] = {64, 65, 66, 66, 65, 61};
        Wire.beginTransmission(memoryI2CAddress);
        Wire.write((byte)(baseAddress >> 8));
        Wire.write((byte)(baseAddress && 0xFF));
        Wire.write(data, 6);
        Wire.endTransmission();
        delay(10);

        ReadTest(7000);
        ReadTest(7500);
        ReadTest(7980);
        ReadTest(8040);
        ReadTest(7960);
        ReadTest(8060);
        ReadTest(7940);
        ReadTest(8000);
        ReadTest(8500);
        ReadTest(8150);
      }

      void ReadTest(unsigned int baseAddress) {
        Serial.println(baseAddress);
        Wire.beginTransmission(memoryI2CAddress);
        Wire.write((byte)(baseAddress >> 8));
        Wire.write((byte)(baseAddress && 0xFF));
        Wire.endTransmission();

        int count = Wire.requestFrom(memoryI2CAddress, 50);
        Serial.print(count);
        while (Wire.available()) { Serial.println(Wire.read()); }
      }

**Update:**

The data addressing seems to be sensitive to the first address byte and not the second. When inverting the order of the most and least significant bytes and comparing to the MSB change with the address, I can reliably return the byte at the correct address. This appears to explain why I either get the same data for some addresses and not others, where the MSByte is or is not changing.

So why is the system insensitive to the least significant byte in the address?

  [1]: https://4donline.ihs.com/images/VipMasterIC/IC/MCHP/MCHPS04099/MCHPS04099-1.pdf?hkey=52A5661711E402568146F3353EA87419
  [2]: https://www.hobbytronics.co.uk/arduino-external-eeprom

title: Erratic behaviour using a DUE with the Microchip 24FC64 EEPROM chip?

Answers: 1

body:
Sadly the simple answer is in how the least significant byte was being calculated, and the boolean operator generating it.

    Wire.write((byte)(baseAddress && 0xFF));

should have been

    Wire.write((byte)(baseAddress & 0xFF));

Tough lesson to check my assumptions!


body:
Now I've been pulling my hair for two days over this one. I've tried everything. I've turned every stone, looked at every search result, and every Arduino Forums thread.

The problem is that Arduino IDE does not recognize the Arduino when connected to the PC, thus I can't upload compiled sketches. As usual, the serial port dropdown menu is greyed-out.

Things I have tried so far:
 1. Tried a different USB cable. Same results.
 2. Tried it on a Mac. It works flawlessly with different sketches.
 3. Looked at dmesg logs for Arduino when connecting. It connects to the PC successfully.
 4. Created a custom udev rule for it to be symlinked from /dev/bus/usb/001/00X to /dev/ttyACMX.
 5. Modified the custom udev rule for it to be symlinked from /dev/bus/usb/001/00X to /dev/ttyUSBX (since for some reason IDE was looking for ttyUSB0 first).
 6. Tried Arduino IDE from snap, apt, and from arduino.cc. All of them work the same.
 7. Tried different versions of AVR board packages from the Boards Manager, none of them work at all.
 8. Tried a NodeMCU (ESP8266), it works flawlessly.
 9. Tried Arduino Due, it works flawlessly.
 10. Added myself to dialout, uucp, and tty groups. Nothing changed.
 11. Changed permissions to a+rwx for all possible Arduino device file nodes.
 12. Changed group ownership to dialout, uucp, and tty for all possible Arduino device file nodes.
 13. Tried running Arduino IDEs as root. Nothing changed.
 14. Installed different firmware and libraries for linux (ex. libserialport0)
 15. Patched the apt version of Aruino IDE with patchelf.
 16. Updated.
 17. Rebooted.

"But hey man, why don't you just use the Mac to compile and upload the sketch, or any other MCU for that matter?" - Because I need to get output from my main PC and delegate it via serial to the Arduino. And Arduino Due is too clunky. And NodeMCU has disputable support for FastLED.

If any of you crazy mfs has an idea on how to solve this, I owe you a beer.

title: Arduino Uno R3 not recognized by Arduino IDE on Ubuntu 21.04

Answers: 2

body:
I have experienced that with several new installs of the Linux OS.  Try this:

Linux does not see board Run:

Type 'groups', is 'dialout' there ?

sudo usermod -a -G tty yourUserName

sudo usermod -a -G dialout yourUserName

Log off and log on again for the changes to take effect.
https://playground.arduino.cc/Linux/All/#Permission
sudo ln -s /usr/bin/python3 /usr/bin/python

body:
After upgrading to Ubuntu 22.04 from 20.10, I could no longer upload anything to Arduino UNO boards. Issue was, the correct port was not listed in the Arduino IDE. All I had available as a port was ttyS0. It won't work with USB boards. I am using Arduino IDE 1.8.19, but I believe this is irrelevant to the issue.

After checking the logs :

    sudo dmesg

I got this output:

    usb 4-2: Product: USB2.0-Serial
    ch341 4-2:1.0: ch341-uart converter detected
    usb 4-2: ch341-uart converter now attached to ttyUSB0
    input: BRLTTY 6.4 Linux Screen Driver Keyboard as /devices/virtual/input/input27
    usb 4-2: usbfs: interface 0 claimed by ch341 while 'brltty' sets config #1
    ch341-uart ttyUSB0: ch341-uart converter now disconnected from ttyUSB0
    ch341 4-2:1.0: device disconnected

So, my Arduino UNO boards all seem to be recognized as some braille tty device (!). Then braille support tries to establish dialog with the UNO board. This of course fails, resulting in a disconnection of the UNO board, causing removal of device /dev/ttyUSB0. This is the reason why it does not show up in the IDE.

The quick fix is to simply remove braille tty display devices support if you don't need it.

    sudo apt remove -y brltty

This worked for me. Hopefully it works for you too.

The issue might be related to some udev rule installed with the package brltty. If I am not mistaken, udev rules are processed in alphabetical order. So it could be that some braille udev rule matches in first, causing the above mentioned scenario.


body:
I recently wired up the following ill-advised circuit: [![A common-anode display is wired with its cathodes connected directly to an LED connected to ground.][1]][1]

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

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?

title: Connecting Common-Anode Seven Segment Display to Shift Register

Answers: 1

body:
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):

[![diode characteristics curve][1]][1]

I got this image from the [German wikipedia article on diodes][2]. 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.

  [1]: https://i.stack.imgur.com/U3mK6.png
  [2]: https://de.wikipedia.org/wiki/Diode


body:
(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?

title: Where am I going wrong in modifying Timer0 and the ISR interrupts in this example?

Answers: 1

body:
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.


body:
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

title: Integration of MAX30100 and DS18B20 Thermal Probe Integration

Answers: 0


body:
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.)

[![schematic][1]][1]

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

[![active level shifter][2]][2]

---

**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:

[![SS pin logic analysis][3]][3]

(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.

  [1]: https://i.stack.imgur.com/Zb1ke.png
  [2]: https://i.stack.imgur.com/0F1LL.png
  [3]: https://i.stack.imgur.com/SftCW.png

title: Why can't an Arduino/ATmega328 act as an SPI slave at anywhere approaching the maximum speed claimed in the datasheet?

Answers: 0


body:
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 - 0xx\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][1]

[arduino-esp32/libraries/WiFi/src/][2]

[default_event_loop][3]

i guess i would like to hook into at least NOT_AUTHED,  802_1X_AUTH_FAILED  from

 [WiFi Driver][4]

  [1]: https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/system/esp_event.html
  [2]: https://github.com/espressif/arduino-esp32/tree/master/libraries/WiFi/src
  [3]: https://github.com/espressif/esp-idf/blob/20847eeb96c486629a678d6ffbe73670013fb771/examples/system/esp_event/default_event_loop/main/main.c
  [4]: https://demo-dijiudu.readthedocs.io/en/latest/api-guides/wifi.html#esp32-wi-fi-soft-ap-general-scenario

title: failed log in attempts on softAP

Answers: 1

body:
259 == `ESP_ERR_INVALID_STATE` according to [this][1]. 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][2]:

    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][3]:

    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][4]:

    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.

  [1]: https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/error-codes.html
  [2]: https://github.com/espressif/arduino-esp32/blob/master/libraries/WiFi/src/WiFiGeneric.cpp
  [3]: https://github.com/espressif/esp-idf/blob/85c43024cb133cd81d3e3a95c1da49d51291d306/components/esp32/event_loop.c#L111
  [4]: https://github.com/espressif/arduino-esp32/blob/46d5afb17fb91965632dc5fef237117e1fe947fc/libraries/WiFi/src/WiFiGeneric.cpp#L96


body:
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.

title: How fast are IR sensors with Arduino

Answers: 1

body:
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.


body:
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?

title: Interval timer on Arduino: Doubt about TimerOne library

Answers: 1

body:
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();
}
```


body:
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?

title: Using ESP8266 to program Arduino by serial comm

Answers: 1

body:
If you use Linux, you can use a simple [Telnet to Serial sketch][1] 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][2] for the esp8266.

  [1]: https://github.com/jandrassy/lab/blob/master/AvrDudeTelnet/AvrDudeTelnet.ino
  [2]: https://github.com/jeelabs/esp-link


body:
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
```

title: Code uploading error on NodeMCU v3 "the selected serial port _ does not exist on your connected board"

Answers: 0


body:
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

title: How do I instruct the L293D to operate a motor at full speed when using 3.3V GPIO pins?

Answers: 1

body:
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.


body:
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.

title: What is the difference between Bluetooth module HC-05 and HC-42 for Arduino?

Answers: 1

body:
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.


body:
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?

title: How to build an arduino project with multiple source files?

Answers: 1

body:
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:

```c++
#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.


body:
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!

title: Cubecell AB01 with nRF24L01

Answers: 1

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


body:
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 ?

title: Different time betweenTiny RTC and IDE

Answers: 1

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


body:
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?][1],
but dont know how to apply the solution on my CONTROLLINO MEGA

Thank you!!

  [1]: https://arduino.stackexchange.com/questions/22591/did-i-brick-my-controllino

title: CONTROLLINO MEGA – Timeout communicating with programmer

Answers: 0


body:
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:

``` cpp
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:
``` cpp
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:

```cpp
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`.

title: I2C missing last byte during transmission- solution isn't clear

Answers: 1

body:
Within `Wire.h.`:

```
#define I2C_BUFFER_LENGTH 128
```

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


body:
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:

    }

title: On initialising PWM with registers on my Due, why does unrelated duty cycle input influence my output?

Answers: 0


body:
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.

title: Using IN1/ IN2 pins for PWM instead of ENA in L298N

Answers: 1

body: 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.<br>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.


body:
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

title: external power supply for servo motor attached to redboard arduino

Answers: 1

body:
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.


body:
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:

```c++
#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:

```c++
#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?

title: I have some problem with 433 MHz transmitter

Answers: 0


body:
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:

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

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

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);
        }
      }
    }

title: Serial read and send to UDP?

Answers: 1

body:
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.


body:
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][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][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?

  [1]: https://github.com/kriswiner/MPU6050/wiki/Simple-and-Effective-Magnetometer-Calibration
  [2]: https://learn.adafruit.com/adxl345-digital-accelerometer/programming

title: How to calibrate an accelerometer?

Answers: 1

body:
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.


body:
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?

title: Safely extend TCNT1 / ICR1 to 24 bits using TOV1

Answers: 1

body:
There is, indeed, a possible race condition. Consider this naive code,
which provides 32-bit timestamps:

```c++
/* 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:

```c++
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;
}
```


body:
I was following the official tutorial and confused by the source code.

[Arduino Official built-in example: RowColumnScanning](https://docs.arduino.cc/built-in-examples/display/RowColumnScanning)

```cpp
// 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:

1. If `thisPixel` is `LOW`, the pin `col[thisCol]` would be `HIGH`.
2. 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

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

```cpp
/*
  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);
  }
}
```

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

title: Why does the official tutorial for LED matrix scanning writes column pin twice?

Answers: 2

body:
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.

body:
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.


body:
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();
    }

title: Can the Blink class be used on a 5v to 240v relay?

Answers: 0


body:
I am trying to make [this][1] 50kg load cell work with [this][2] HX711 chip. I currently have the following connections :
<br>

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

I am using [this][3] 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 ?

  [1]: https://www.robotshop.com/ca/en/micro-load-cell-50-kg.html?gclid=Cj0KCQiA9OiPBhCOARIsAI0y71COwRpGv_NHrT68xsmCCZL6BTN8nYfXpjPnluj4AhdVfCZT5KRI-xcaAjk8EALw_wcB
  [2]: https://www.amazon.ca/-/fr/gp/product/B07MTYT95R/ref=ox_sc_rp_title_rp_1?smid=&psc=1&pf_rd_p=9e23f442-1cd8-4ea2-a936-d77b2d58e3f5&pd_rd_wg=gbmVg&pd_rd_i=B07MTYT95R&pd_rd_w=Ik5oB&pd_rd_r=d4e1d9b9-e72f-453c-b6d9-3bd255d99539
  [3]: https://github.com/bogde/HX711

title: Arduino HX711 load cell lots of drift

Answers: 1

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


body:
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?

title: Flight controller board Reprogram

Answers: 0


body: I have a very simple touch sensor program that works fine and lights an led to show the sensor works; while hooked up to the computer via usb cable it works fine.  When using a power bank with the same usb cable the board lights up but does not read the touch sensor.  I have tried other cables with the same result.

title: My ESP32 WROOM clone will not register touch sensor when using a 5v power bank with usb cable

Answers: 1

body: This is hard to explain but your problem in not unique. I hope this helps. It is your ground reference. When connected to the computer which is grounded either/or a ground wire or capacitive coupling to earth. Your body is capacitively connected to ground that way and when you touch the switch it is recognized.  To make it work with the battery pack you need to couple to the person touching it. You can do that capacitively by adding a ground plain to your circuit. This can be a conductive plate that will capacitively couple the ground to the atmosphere or any other practical means.


body:
I was following [the official tutorial of LED matrix integration][source] and couldn't figure out why there is no resistor.

I assumed there are built-in resistors in the LED matrix, so I did an experiment by connecting pin 9 of the LED matrix to v5 of my Arduino Leonardo board and pin 13 of the LED matrix to GND of the same board. You can refer to the schematic diagram below to know I was trying to lit up the LED at the position [0, 0].

Unfortunately, the LED next to [0, 0] burned immediately and I still couldn't figured out it.

![](https://i.stack.imgur.com/haoD5.jpg)

# Question

1. Are resistors necessary for 8x8 LED matrix?
   1. If yes, why the official example doesn't have any resistor?
   2. If no, why my experiment failed?
   3. If no, why are there so many unofficial examples use resistors for each wire?

# Source

https://docs.arduino.cc/built-in-examples/display/RowColumnScanning

# Circuit

![](https://i.stack.imgur.com/PEvsg.png)

# Schematic

![](https://i.stack.imgur.com/jFRqg.png)

[source]: https://docs.arduino.cc/built-in-examples/display/RowColumnScanning

Answers: 1

body:
Well done Arduino, you did a great job providing a magic-smoke tutorial [sarkasm off]. IDK how this tutorial could make it into their official docs, it should not be there!

You definitely need series resistors at each column or at each row to protect the LEDs/GPIOs (that's 8 resistors). There may be matrices that integrate resistors, but your one and the one they use in their docs does not.

An alternative is to configure the column GPIOs as inputs with enabled pullups and the row GPIOs as ordinary outputs. This way, current will be limited by the pullup resistors. But as those are quite large (several 10kOhm depending on MCU) the LEDs will be very dim.