# Question
Title: Issues Uploading Code to ATTiny84 with Sparkfun AVR Pocket Programmer and ATTinyCore
I am getting back into programming with Arduino and built a POV fidget spinner inspired by an instructable by MakersBox. I am using the SparkFun AVR Pocket Programmer and an ATTiny84 (8MHz internal clock) with ATTinyCore as the board manager.

I was able to upload the code without error a few days ago using the 'USBTinyISP (ATTinyCore) FAST, for parts running \>= 2MHz' programmer selection but it stopped working. Now the below error shows:

```
avrdude: Version 6.3-20201216
         Copyright (c) 2000-2005 Brian Dean, http://www.bdmicro.com/
         Copyright (c) 2007-2014 Joerg Wunsch

         System wide configuration file is "C:\Users\Franklin Marquette\AppData\Local\Arduino15\packages\ATTinyCore\hardware\avr\1.5.2/avrdude.conf"

         Using Port                    : usb
         Using Programmer              : usbtiny
         Setting bit clk period        : 0.3
avrdude: usbdev_open(): Found USBtinyISP, bus:device: bus-0:\\.\libusb0-0001--0x1781-0x0c9f
         AVR Part                      : ATtiny84
         Chip Erase delay              : 15000 us
         PAGEL                         : P00
         BS2                           : P00
         RESET disposition             : possible i/o
         RETRY pulse                   : SCK
         serial program mode           : yes
         parallel program mode         : yes
         Timeout                       : 200
         StabDelay                     : 100
         CmdexeDelay                   : 25
         SyncLoops                     : 32
         ByteDelay                     : 0
         PollIndex                     : 3
         PollValue                     : 0x53
         Memory Detail                 :

                                  Block Poll               Page                       Polled
           Memory Type Mode Delay Size  Indx Paged  Size   Size #Pages MinW  MaxW   ReadBack
           ----------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- ---------
           eeprom        65     6     4    0 no        512    4      0  4000  4500 0xff 0xff
           flash         65     6    32    0 yes      8192   64    128  4500  4500 0xff 0xff
           signature      0     0     0    0 no          3    0      0     0     0 0x00 0x00
           lock           0     0     0    0 no          1    0      0  9000  9000 0x00 0x00
           lfuse          0     0     0    0 no          1    0      0  9000  9000 0x00 0x00
           hfuse          0     0     0    0 no          1    0      0  9000  9000 0x00 0x00
           efuse          0     0     0    0 no          1    0      0  9000  9000 0x00 0x00
           calibration    0     0     0    0 no          1    0      0     0     0 0x00 0x00

         Programmer Type : USBtiny
         Description     : USBtiny simple USB programmer, http://www.ladyada.net/make/usbtinyisp/
avrdude: programmer operation not supported

avrdude: Setting SCK period to 1 usec
avrdude: initialization failed, rc=-1
         Double check connections and try again, or use -F to override
         this check.

avrdude done.  Thank you.

Failed programming: uploading error: exit status 1

```

**NOW** if I upload using the "USBtinyISP (ATtinyCore) SLOW, for new or 1 MHz parts" programmer option, the code does upload. It is 8x slower though. I uploaded the Blink sketch to a separate ATTiny84 on a breadboard and the connected LED stayed on for ~7.75s when it was programmed to stay on for 1s.

I have no idea what is going on and would really appreciate any help that I can get. **Thank you!**

For reference, the code is below.

```
/*

Not all Attiny cores support the tone() function. Try this one
https://github.com/SpenceKonde/ATTinyCore

// ATMEL ATTINY84 / ARDUINO
//
//                           +-\/-+
//                     VCC  1|    |14  GND
//             (D  0)  PB0  2|    |13  AREF (D 10)
//             (D  1)  PB1  3|    |12  PA1  (D  9)
//                     PB3  4|    |11  PA2  (D  8)
//  PWM  INT0  (D  2)  PB2  5|    |10  PA3  (D  7)
//  PWM        (D  3)  PA7  6|    |9   PA4  (D  6)
//  PWM        (D  4)  PA6  7|    |8   PA5  (D  5)        PWM

*/

#include <EEPROMex.h>
#include <avr/pgmspace.h>
#include "font.h"
#include "textAndShapes.h"

const int charHeight = 8;
const int charWidth = 5;
int rows= 8;                // Total LED's in a row
int LEDS[] = {0, 1, 2, 3, 4, 5, 7, 6};
bool STATES[] = {LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW};

char charArray[6];              // holds characters to display
unsigned long lastTimeUs;                // time (us) magnet sensed
unsigned long revTimeUs;                 // time (us) of last full rotation
unsigned long dwellTimeUs;               // time (us) between LED changes (based on rotation speed)
volatile unsigned long revolutions = 0;  // track number of revolutions since last start
long totalRevolutions;          // track total number of revolutions (stored in EEPROM)
bool spinning = true;          // track reset of time & counts
unsigned long startTimeUs;               // time (us) current spinning started

int mode;                       // current operating mode, stored in EEPROM
int modes = 8;                  // number of modes available
  // 0 -> text "Hello World!"
  // 1 -> RPM
  // 2 -> time in seconds
  // 3 -> spin count
  // 4 -> spin count (total)
  // 5 -> "lilly pad" pattern
  // 6 -> shape 1 (heart)
  // 7 -> shape 2 (smile)

byte ledPin = 0;
byte magPin = 0;                // Hall effect sensor, pulled-up, goes low when magnet passes
byte magPullUp = 10;            // Pin A0 / D10
byte touchPin = 1;              // Push button A1 / D9
byte touchPullUp = 9;

volatile boolean rotationFlag = false;  // modified by ISR

void setup(){
  // setup inputs
  pinMode(touchPin, INPUT);
  digitalWrite(touchPullUp, HIGH);
  pinMode(magPin, INPUT);
  digitalWrite(magPullUp, HIGH);

  // setup other LEDs
  for(int LED=0; LED<(sizeof(LEDS)/sizeof(int)); LED++){
    pinMode(LEDS[LED], OUTPUT);
    digitalWrite(LEDS[LED], STATES[LED]);
  }

  // Interupt setting
  GIMSK  = bit (PCIE0);  // Pin change interrupt enable
  PCMSK0 = bit (PCINT0); // Enable interupt on PCINT0 (D10)
  sei();                 // enables interrupts

  // get saved mode from eeprom
  mode = EEPROM.read(0);
  if (mode >= modes) {
    mode = 0; // may be very large first time
  }

  // get saved revolution total from eeprom
  totalRevolutions = EEPROMReadlong(1);
  if (totalRevolutions < 0 || totalRevolutions > 999999UL){ // will be -1 first time.
    totalRevolutions = 0;
    EEPROMWritelong(1, 0);
  }

  // show we are alive and what mode is active
  blipLEDs();

  lastTimeUs = micros();
}

void loop(){
  int sigFigs = 6;               // number of significant figures to deplay
  unsigned long curTimeUs;
  int seconds;
  unsigned int rpm;

  checkButton();
  if (((micros() - lastTimeUs) > 1000000UL)){ // less than 1 rev / sec
    if (spinning){
      spinning = false;
      totalRevolutions = totalRevolutions + revolutions;
      EEPROMWritelong(1, totalRevolutions);
      revolutions = 0;
      clearArray();
      blipLEDs();
    }
    else {
      //digitalWrite(LEDS[mode], LOW);
    }
  }

  if (mode == 5){  // lilly pad pattern, show regardles of magnet.
    for(int LED=0; LED<(sizeof(LEDS)/sizeof(int)); LED++){
       digitalWrite(LEDS[LED], HIGH);
       delay(1);
       digitalWrite(LEDS[LED], LOW);
    }
    for(int LED=(sizeof(LEDS)/sizeof(int))-1; LED >= 0; LED--){
       digitalWrite(LEDS[LED], HIGH);
       delay(1);
       digitalWrite(LEDS[LED], LOW);
    }
  }

  else if (rotationFlag){ // we are spinning!
    rotationFlag = false;
    if (!spinning){
      spinning = true;
      startTimeUs = micros();
    }
    curTimeUs = micros();
    revTimeUs = curTimeUs - lastTimeUs;
    dwellTimeUs = revTimeUs * 3UL / 360UL;   // 3 degrees
    seconds = (curTimeUs - startTimeUs) / 1000000UL;
    rpm = 60000 * 1000 / revTimeUs;
    lastTimeUs = curTimeUs;
    clearArray();
    if (mode == 0){
      strcpy (charArray, text);
      //sprintf(charArray, "%lu", dwellTimeUs);
    }
    else if (mode == 1){
      sprintf(charArray, "%d", rpm);
      sigFigs = 2;
    }
    else if (mode == 2){
      sprintf(charArray, "%d", seconds);
    }
    else if (mode == 3){
      sprintf(charArray, "%lu", revolutions);
    }
    else if (mode == 4){
      sprintf(charArray, "%lu", totalRevolutions + revolutions);
    }
    else if (mode == 6){ // shape 1 (heart)
      for(int k=0; k< sizeof(shape_1);k++){
        if (rotationFlag){
          break;
        }
        char b = pgm_read_byte_near(&(shape_1[k]));
        for (int j=0; j<charHeight; j++) {
          digitalWrite(LEDS[j], bitRead(b, 7-j));
        }
        dwellTimeUs = revTimeUs * 4UL / 360UL;   // 5 degrees
        delayMicroseconds(dwellTimeUs);
      }
    }
    else if (mode == 7){ // shape 2 (smile)
      for(int k=0; k< sizeof(shape_2);k++){
        if (rotationFlag){
          break;
        }
        char b = pgm_read_byte_near(&(shape_2[k]));
        for (int j=0; j<charHeight; j++) {
          digitalWrite(LEDS[j], bitRead(b, 7-j));
        }
        dwellTimeUs = revTimeUs * 4UL / 360UL;   // 5 degrees
        delayMicroseconds(dwellTimeUs);
      }
    }

    // Text in top half
    if (mode < 5) {
      int digits = 0;
      for(int k=0; k< sizeof(charArray);k++){
        char c = charArray[k];
        if (rotationFlag){
          break;
        }
        if(c){
          if (digits < sigFigs){
            printLetter(c);
            //digits += 1;
          }
          else{
            printLetter('0');
          }
          digits += 1;
        }
      }

      // Handle display in lower section
      clearArray();
      if(1 && (revTimeUs < 200000)){
        char * ptr = (char *) pgm_read_word (&string_table[mode]);
        //char buffer [6]; // must be large enough!
        strcpy_P (charArray, ptr);

        // wait for it . . .
        while((micros() < (lastTimeUs + revTimeUs / 2)) && !rotationFlag){};

        // show it
        for (int k=sizeof(charArray)-1; k>=0; k--){
          if (rotationFlag){
            break;
          }
          printLetterLower(charArray[k]);;
        }
      }
    }
  }
}

ISR(PCINT0_vect){  // Magnet sensed
  if (!digitalRead(magPullUp)){
    rotationFlag = true;             // Increment volatile variables
    revolutions += 1;
  }
}

void dwellDelay(){ // avoid glitch on first rotation having erronious value
  if (dwellTimeUs > 2000){
    dwellTimeUs = 2000;
  }
  if (dwellTimeUs < 100){
    dwellTimeUs = 100;
  }
  delayMicroseconds(dwellTimeUs);
}

void printLetter(char ch){
// https://github.com/reger-men/Arduion-POV-clock/blob/master/clock.ino
  // make sure the character is within the alphabet bounds (defined by the font.h file)
  // if it's not, make it a blank character
  if (ch < 32 || ch > 126){
    ch = 32;
    }
  // subtract the space character (converts the ASCII number to the font index number)
  ch -= 32;
  // step through each byte of the character array
  for (int i=0; i<charWidth; i++) {
    char b = pgm_read_byte_near(&(font[ch][i]));

    for (int j=0; j<charHeight; j++) {
      digitalWrite(LEDS[j], bitRead(b, 7-j));
    }
    dwellDelay();
  }

  //clear the LEDs
  for (int i = 0; i < rows; i++)
    digitalWrite(LEDS[i] , LOW);
  dwellDelay();
}

void printLetterLower(char ch){
  // make sure the character is within the alphabet bounds (defined by the font.h file)
  // if it's not, make it a blank character
  if (ch < 32 || ch > 126){
    ch = 32;
    }
  // subtract the space character (converts the ASCII number to the font index number)
  ch -= 32;
  // step through each byte of the character array
  for (int i=charWidth-1; i>-1; i--) {
    char b = pgm_read_byte_near(&(font[ch][i]));
    for (int j=0; j<charHeight; j++) {
      digitalWrite(LEDS[j+1], bitRead(b,j));
    }
    dwellDelay();
  }
  //clear the LEDs
  for (int i = 0; i < rows; i++)
    digitalWrite(LEDS[i] , LOW);

  // space between letters
  dwellDelay();
}

bool touched(){
  // returns true if touched, false if not.  Light LED until touch released
  bool touchVal = digitalRead(touchPullUp);
  if (!touchVal){
    while(!digitalRead(touchPullUp)){ // wait till touch release
      delay(10);
      digitalWrite(LEDS[mode], LOW);
    }
    //digitalWrite(LEDS[0], LOW);
    return (true);
  }
  else{
    return (false);
  }
}

void checkButton(){
  // check button for mode change and display current mode
  if (touched()){
    mode += 1;
    if (mode >= modes){
      mode = 0;
    }
    EEPROM.write(0, mode);
    blipLEDs();
  }
}

void blipLEDs(){
  // something to show we are alive
  for(int LED=0; LED<(sizeof(LEDS)/sizeof(int)); LED++){
    digitalWrite(LEDS[LED], HIGH);
    delay(10);
    digitalWrite(LEDS[LED], LOW);
  }
  for(int LED=sizeof(LEDS)/sizeof(int); LED>mode; LED--){
    digitalWrite(LEDS[LED], HIGH);
    delay(10);
    digitalWrite(LEDS[LED], LOW);
  }
  digitalWrite(LEDS[mode], HIGH);
}

void EEPROMWritelong(int address, long value)  {
  //This function will write a 4 byte (32bit) long to the eeprom at
  //the specified address to address + 3.
  //https://playground.arduino.cc/Code/EEPROMReadWriteLong

  //Decomposition from a long to 4 bytes by using bitshift.
  //One = Most significant -> Four = Least significant byte
  byte four = (value & 0xFF);
  byte three = ((value >> 8) & 0xFF);
  byte two = ((value >> 16) & 0xFF);
  byte one = ((value >> 24) & 0xFF);

  //Write the 4 bytes into the eeprom memory.
  EEPROM.write(address, four);
  EEPROM.write(address + 1, three);
  EEPROM.write(address + 2, two);
  EEPROM.write(address + 3, one);
}

long EEPROMReadlong(long address){
  //Read the 4 bytes from the eeprom memory.
  long four = EEPROM.read(address);
  long three = EEPROM.read(address + 1);
  long two = EEPROM.read(address + 2);
  long one = EEPROM.read(address + 3);

  //Return the recomposed long by using bitshift.
  return ((four << 0) & 0xFF) + ((three << 8) & 0xFFFF) + ((two << 16) & 0xFFFFFF) + ((one << 24) & 0xFFFFFFFF);
}

void clearArray(){
  for(int i=0; i<sizeof(charArray); i++){      // clear array
    charArray[i] = 0;
  }
}

```

# Answer
When you first get one of those chips, it's always internally configured to down-clock the internal oscillator by 8. So, it's still running at 8MHz physical, but the actual chip clock speed is 1 MHz.

If you tell the IDE it's the 8 MHz version (divider turned off), it will take ~8x longer to run any sort of delay (which is why you're seeing the 7.75s LED pulse rather than 1s).

To fix this problem, set the IDE to the chip settings you want (8 MHz internal oscillator\*), then click "Burn Bootloader." This won't actually set the bootloader, as this chip doesn't use one, but it *will* set the internal fuses so the clock divider is turned off and it will work at 8 MHz as expected.

Note that the programmer will still need to be set to the low speed (why it says "SLOW, for **new** \[emphasis mine\] or 1 MHz parts") when you do the "Burn Bootloader" as the chip will otherwise be running too slowly at 1 MHz to receive the commands at the programmer's default speed (the other cause of the rc=-1 error, aside from bad wiring).

Note that sometimes the programmer will also fail to work if any of the programming pins have LEDs or switches attached - are you removing the chip before programming, or is it still attached to the circuit? If the latter, also try isolating it before programming.

\*Make sure you **do not** select any of the external clock options unless you know what you're doing. Doing this will brick your chip *unless* you happen to have an external clock source of that type or a high voltage programmer. I'm not sure how those work, but they're a special (expensive) variant that uses a higher-than normal voltage to override the fuse settings even if the chip won't clock.
> 2 votes

---
Tags: arduino-ide, attiny, avr, avrdude
---


# Question
Title: How many stepper motors can you run on one Arduino Uno? Ideas on how to run 9?
I am in middle school and new to Arduino. I just learned to set up and code a stepper motor on my Arduino Uno from watching YouTube videos. I want to set up 9 stepper motors to all run at the same time and at the same rotation speed for a science project I am working on. Right now I have the Arduino Uno with a 830 breadboard, ULN2003 stepper motor driver and 28BYJ-48 stepper motor. I think I will need to use something different because I can see that my driver doesn't have more than one set of plugs for the wires. I got a budget for my science project so I am allowed to buy some new equipment. But I am confused about what I need to run 9. If anyone can help to suggest the best and simplest way to do this, I would be very happy. I feel like once I have the equipment, I can try to figure out how to put it together and figure out the code. Thanks for the help!

# Answer
You can use 4 N-Channel MOSFETs, get the logic level avalanche rated ones. Get something in the 5A or higher current range (lower RDSon). Your motors draw 240mA each. The higher the amperage rating the of the MOSFET the cooler the MOSFET will run. I am a firm believer silicon in place of heatsinks. In small it is not that expensive and you do not have the hassle of a heatsink.

You can then drive the MOSFETs from four port pins through a 50 Ohm resistor to each of the gates. Then put a 10K pull down resistor on the port pin, not the gate. Putting the pull down on the gate creates a voltage divider for the gate voltage. This is to guarantee the MOSFETs are all off when the system is first turned on and during initialization until your code takes over. I use the low gate resistors one to control oscillation and two to drive it hard so it switches faster keeping it out of the linear range where it will get hot. Be sure the Source of each output is connected to the ground of the motor power supply and that the arduino ground is also connected to this ground.

You then connect all of the motors in parallel and connect them to the drains of the MOSFET. I am assuming 4 leds (Pink, Yellow, Orange and Blue) from the motor to the MOSFETs drain and a common (Red) for +5 power.

This will give you about 1.4V more per phase when operating not dropping across the driver thereby increasing the efficiency. Also the wiring is much simpler.
> -1 votes

---
Tags: arduino-uno, arduino-mega, stepper-motor
---


# Question
Title: ESP32 Hardware Serial Flow control and full espressif/arduino-esp32 support
I have a similar issue. I want to use the ESP32 with RS485. I have used the Arduino and this works well assigning pins, but it seems not to allow full use of the UART.

I see the new uarts in the ESP32 can support the direction control (RTS) of the direction pin and there is actually a hardware RS485 mode. See the repository that the board package is based on: https://github.com/espressif/arduino-esp32

Then https://github.com/espressif/arduino-esp32/tree/master/tools/sdk/include/driver/driver uart.h

This shows we can actually have full hardware flow control, so no more guessing delays for controlling the DIR lines or getting interrupts when the send buffer is empty in order to know when to switch back to receive.

I found using board manager this did not all get installed, so I followed some tutorials on how to install it manually. The board either doesn't appear at all, or I can't reference "uart.h".

Any ideas or examples? Thanks, Mark

# Answer
> 1 votes
your example was of great help solving the problem of driving RTS properly, thanks a lot!

I found a small bug in the code example, the data buffer is allocated in the loop() function instead of setup() and as a result, eventually the memory leak will fill-up all available memory.

Ciao! Alessandro

# Answer
> 0 votes
Espressif and Arduino use the same UART numbering, and there are no hidden properties of hardwareSerial that are bound to it UART instance So it's possible to perform a reach-around and replace the arduino harwareSerial UART driver instance with an espressif RS485 uart instance and then use Arduinos `hardwareSerial` methods to communicate with the UART.

```
#include <Arduino.h>
#include <stdlib.h>
#include <stdint.h>
#include <stddef.h>
#include <driver/uart.h>

#define ECHO_UART_PORT UART_NUM_1
#define ECHO_TEST_TXD   (25)
#define ECHO_TEST_RXD   (26)
#define ECHO_TEST_RTS   (27)
#define ECHO_TEST_CTS  UART_PIN_NO_CHANGE
#define BUF_SIZE        (127)
#define BAUD_RATE       (9600)

#if   ECHO_UART_PORT == UART_NUM_0
#define         SERIAL_485 Serial
#error  Serial is already committed elsewhere in this code

#elif ECHO_UART_PORT == UART_NUM_1
#define         SERIAL_485 Serial1

#elif ECHO_UART_PORT == UART_NUM_2
#define         SERIAL_485 Serial2
#endif

static const char *TAG = "RS485_ECHO_APP";

void setup() {
    Serial.begin(115200); //uses UART_NUM_0
    //configure UART_NUM_2 for RS485
    const uart_port_t uart_num = ECHO_UART_PORT;
    uart_config_t uart_config = {
        .baud_rate = BAUD_RATE,
        .data_bits = UART_DATA_8_BITS,
        .parity = UART_PARITY_DISABLE,
        .stop_bits = UART_STOP_BITS_1,
        .flow_ctrl = UART_HW_FLOWCTRL_DISABLE,
        .rx_flow_ctrl_thresh = 122,
    };

    Serial.println("Start RS485 application test and configure UART.");

    // start arduino serial port
    SERIAL_485.begin(BAUD_RATE);
    SERIAL_485.setTimeout(1+(10000/BAUD_RATE) ); // 10000 is 10 symbols per byte * 1000 ms per second

    // drop rhe Arduino installed UART driver!
    // we will replace this with a 485 capable driver.
    uart_driver_delete(uart_num);

    // Configure UART parameters
    uart_param_config(uart_num, &uart_config);

    Serial.println("UART set pins, mode and install driver.");
    // Set UART1 pins(TX: IO23, RX: I022, RTS: IO18, CTS: IO19)
    uart_set_pin(uart_num, ECHO_TEST_TXD, ECHO_TEST_RXD, ECHO_TEST_RTS, ECHO_TEST_CTS);

    // Install UART driver (we don't need an event queue here)
    // In this example we don't even use a buffer for sending data.
    uart_driver_install(uart_num, BUF_SIZE * 2, 0, 0, NULL, 0);

    // Set RS485 half duplex mode
    uart_set_mode(uart_num, UART_MODE_RS485_HALF_DUPLEX);

    ESP_LOGI(TAG, "UART start recieve loop.\r\n");
    SERIAL_485.printf("Start RS485 UART test.\r\n");
}

```

---
Tags: esp32, uart, rs485
---


title: Replace char based on user input

text:
# Question
Title: Replace char based on user input
I am developing a hangman game on tinyduino(tinycircuits) and I am currently stuck on how to **properly** replace a `char` based on user input within a `for loop`. My current code does actually replace the correct underscore(blank), if a user inputs a correct letter.

As per the game hangman, it will print out a series of blanks(in my case, underscores) based on number of letters, that serve as placeholders for the correct letter and will reveal the letter only if a user inputs a correct letter.

However, whenever a user inputs another correct letter (after inputting a correct letter prior), my program creates another 'line' and replaces the underscore in that new line instead.

For example, say the word to guess is kotlin. If user inputs 'k', my console shows me:

```
k_____

```

The output above is still correct. But, when the user inputs another letter, say 'o' which is also correct, the result I get is:

```
k______o____

```

To further re-emphasize, now if a user inputs 't', I would get:

```
k______o______t___

```

What do I need to modify in my code in order to replace the underscores in the original line whenever a user enters a correct letter? Below is my current code.

```
if (k == 1) { // Str1 is "kotlin"
    display.setCursor(10,50);
    length = strlen(Str1);

    String user_input = String(phone_input);
    String word = String(Str1);

    for (i = 0; i < length; i++) {
      word[i] = '_';

      if (user_input == "k") {
        word[0] = 'k';
      }

      if (user_input == "o") {
        word[1] = 'o';
      }

      if (user_input == "t") {
        word[2] = 't';
      }

      if (user_input == "l") {
        word[3] = 'l';
      }

      if (user_input == "i") {
        word[4] = 'i';
      }

      if (user_input == "n") {
        word[5] = 'n';
      }

      display.print(word[i]);
      SerialMonitorInterface.print(word[i]);
    }
  }

```

# Answer
Attention spoiler (If it's ok for you just to enhance it to a playable version by enhancing the shortcuts! )

If you want to replace single characters in a word, `String` and `std::string` is way too much overhead. Use good old char \[\] instead.

```
const char* result { "kotlin" }; // shortcut
const size_t size = 6; // shortcut

char guess[size+1]; // The guessed intermediate result

const byte wrongMax = 22;
byte wrong = 0; // number of wrong guesses

void setup() {
  for (char& c : guess) c='_';
  guess[size] = 0;

  Serial.begin(9600);
  Serial.println(guess);
}

void loop() {
  if (strcmp(result,guess)== 0) {
    Serial.println("Got it !"); while (1){} // Stop, reset required
  }
  if (wrong >= wrongMax) {
    Serial.println("Failed !"); while (1){} // Stop, reset required
  }

  int c = Serial.read();
  if (c >= 'a' && c <= 'z') {
    // shortcut: only lower characters allowed
    byte p;
    for (p=0; p < size; p++) {
       if (c == result[p] && guess[p] == '_') {
         // found a new correct one
         guess[p] = c;
         break;
       }
    }
    if (p == size) {Serial.print( ++wrong ); Serial.println( " wrong guesses");}
    Serial.println (guess);
  }
}

```
> 2 votes

---
Tags: arduino-ide, string, loop
---


# Question
Title: Send a 2d PROGMEM array over SoftwareSerial
I have a 2d array:

```
const byte messages_for_measurement[2][8] PROGMEM =
{
  { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 },
  { 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10 },
};

```

I want to send one of these sub-array over software serial.

Initially, this produced junk data:

```
swSerial.write( messages_for_measurement[0], sizeof(messages_for_energy_meter[0]) );

```

Then I learned about `pgm_read_byte_near()` and `pgm_read_word()`. I tried every combination but I did not get this to work:

```
swSerial.write(pgm_read_byte_near(pgm_read_word(messages_for_measurement[0]))), sizeof(pgm_read_byte_near(pgm_read_word(messages_for_measurement[0])));

```

and

```
swSerial.write(pgm_read_byte_near(&pgm_read_word(messages_for_measurement[0]))), sizeof(pgm_read_byte_near(pgm_read_word(&messages_for_measurement[0])));

```

and

```
swSerial.write(char(pgm_read_byte_near(pgm_read_word(messages_for_measurement[0])))), sizeof(char(pgm_read_byte_near(pgm_read_word(messages_for_measurement[0]))));

```

and

```
swSerial.write(char(pgm_read_byte_near(pgm_read_word(&messages_for_measurement[0])))), sizeof(char(pgm_read_byte_near(pgm_read_word(&messages_for_measurement[0]))));

```

How can I send the sub-array over serial, when the 2d array is in PROGMEM?

# Answer
The `write()` method from `SoftwareSerial` (which is inherited from the abstract `Print` class) does not support printing PROGMEM-based binary buffers. The `print()` method does have some PROGMEM support, but it is limited to printing NUL-terminated character strings, and is meant to be used with the `F()` macro. You could coerce this method into printing your data, but this would require you to add a null byte at the end of each inner array, and the trick would break if you ever have to send a null byte.

Also, the `pgm_read_stuff()` macros cannot read an array at a time. You could do achieve this with `memcpy_P()`, but that would require allocating an array in RAM. I think the simplest solution here is to get the bytes from the flash one by one with `pgm_read_byte()`:

```
const byte *message = messages_for_measurement[0];
size_t size = sizeof messages_for_measurement[0];
for (size_t i = 0; i < size; i++) {
    swSerial.write(pgm_read_byte(&message[i]));
}

```

Note that the first line does not attempt to access the array data: it only copies into `message` the address of the first byte: this is the decay-to-pointer semantics.
> 1 votes

---
Tags: serial, softwareserial, array, progmem
---


# Question
Title: power 12v solenoid from DC jack of Arduino Uno
I was wondering if it is possible to power up a 12V solenoid valve from the DC jack of the Arduino Uno, provided that I'm powering the Arduino from the same jack:

# Answer
> 1 votes
Sure, that's the same as if you were directly soldering a second plug to your power supply. Just make sure the power supply delivers enough current for your solenoid (the power used by the Arduino will be comparably negligible).

---
Tags: arduino-uno, voltage, voltage-protection
---


# Question
Title: Having a problem with DS18B20 getTempC using an array containing the addresses of the sensors
I have been struggling with this and am at a total loss as to why its not working. Here is my program:

```
#include <OneWire.h>
#include <DallasTemperature.h>

// Data wire is Arduino pin A0
#define ONE_WIRE_BUS A0

// Setup a oneWire instance
OneWire oneWire(ONE_WIRE_BUS);

// Pass our oneWire reference to Dallas Temperature.
DallasTemperature sensors(&oneWire);

// Define array for holding all the sensors addresses and load addresses.
//======================================================================
DeviceAddress SensorAddr [13] =
                 {
 ( 0x28, 0xAA, 0x30, 0x41, 0x38, 0x14, 0x01, 0x14 ), // Sensor 1
 ( 0x28, 0xAA, 0x24, 0x31, 0x38, 0x14, 0x01, 0xDF ), // Sensor 2
 ( 0x28, 0xAA, 0xE4, 0x30, 0x38, 0x14, 0x01, 0x72 ), // Sensor 3
 ( 0x28, 0xAA, 0xD4, 0xC2, 0x38, 0x14, 0x01, 0x80 ), // Sensor 4
 ( 0x28, 0xAA, 0x6C, 0xDA, 0x38, 0x14, 0x01, 0xD5 ), // Sensor 5
 ( 0x28, 0xAA, 0xCA, 0x39, 0x38, 0x14, 0x01, 0xBB ), // Sensor 6
 ( 0x28, 0xAA, 0x75, 0x28, 0x38, 0x14, 0x01, 0x2C ), // Sensor 7
 ( 0x28, 0xAA, 0xFB, 0xB2, 0x38, 0x14, 0x01, 0xBF ), // Sensor 8
 ( 0x28, 0xAA, 0x0F, 0x3A, 0x38, 0x14, 0x01, 0xC3 ), // Sensor 9
 ( 0x28, 0xAA, 0x6F, 0x26, 0x38, 0x14, 0x01, 0xF8 ), // Sensor 10
 ( 0x28, 0xFF, 0x64, 0x1E, 0x1E, 0x6A, 0x74, 0xF1 ), // Sensor 11
 ( 0x28, 0xFF, 0x64, 0x1E, 0x1E, 0x7D, 0x29, 0x55 ), // Sensor 12
 ( 0x28, 0xFF, 0x64, 0x1E, 0x1E, 0x73, 0xAC, 0x3A )  // Sensor 13
                   };

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

//Test first Sensor Address  - This works
//=======================================

  byte Sensor1Test[8] = { 0x28, 0xAA, 0x30, 0x41, 0x38, 0x14, 0x01, 0x14};
  Serial.print("Test Sensor 1: ");
  float tempTest = sensors.getTempC( Sensor1Test );
  Serial.print(tempTest, 2);
  Serial.print("\xC2\xB0"); // shows degree symbol
  Serial.print("C");
  Serial.println();
}

void loop(void)
// Get all temperatures - This does not work??
//============================================

{
  sensors.requestTemperatures();
  for (int S =0; S<13; S++)
      {
        Serial.print("Sensor # "); Serial.print(S+1); Serial.print(": ");
        float tempC = sensors.getTempC(SensorAddr [S]);
        Serial.print(tempC,2);
        Serial.print("\xC2\xB0"); // shows degree symbol
        Serial.print("C");
        Serial.println();
        delay(1000);
      }
 Serial.println();
}

```

# Answer
> 0 votes
The `DeviceAddress` internally is defined as an array of `uint8_t` (see definition:

```
typedef uint8_t DeviceAddress[8];

```

That is, each address is an array itself.

```
DeviceAddress Sensor1 = { 0x28, 0xAA, 0x30, 0x41, 0x38, 0x14, 0x01, 0x14 };

```

So if you have 13 `DeviceAdrress`, you are dealing with a two-dimension array, and you need to declare it as:

```
#define NUMBER_OF_SENSORS 13
DeviceAddress SensorAddr [NUMBER_OF_SENSORS] = {
 { 0x28, 0xAA, 0x30, 0x41, 0x38, 0x14, 0x01, 0x14 }, // Sensor 1
 { 0x28, 0xAA, 0x24, 0x31, 0x38, 0x14, 0x01, 0xDF }, // Sensor 2
 { 0x28, 0xAA, 0xE4, 0x30, 0x38, 0x14, 0x01, 0x72 }, // Sensor 3
 { 0x28, 0xAA, 0xD4, 0xC2, 0x38, 0x14, 0x01, 0x80 }, // Sensor 4
 { 0x28, 0xAA, 0x6C, 0xDA, 0x38, 0x14, 0x01, 0xD5 }, // Sensor 5
 { 0x28, 0xAA, 0xCA, 0x39, 0x38, 0x14, 0x01, 0xBB }, // Sensor 6
 { 0x28, 0xAA, 0x75, 0x28, 0x38, 0x14, 0x01, 0x2C }, // Sensor 7
 { 0x28, 0xAA, 0xFB, 0xB2, 0x38, 0x14, 0x01, 0xBF }, // Sensor 8
 { 0x28, 0xAA, 0x0F, 0x3A, 0x38, 0x14, 0x01, 0xC3 }, // Sensor 9
 { 0x28, 0xAA, 0x6F, 0x26, 0x38, 0x14, 0x01, 0xF8 }, // Sensor 10
 { 0x28, 0xFF, 0x64, 0x1E, 0x1E, 0x6A, 0x74, 0xF1 }, // Sensor 11
 { 0x28, 0xFF, 0x64, 0x1E, 0x1E, 0x7D, 0x29, 0x55 }, // Sensor 12
 { 0x28, 0xFF, 0x64, 0x1E, 0x1E, 0x73, 0xAC, 0x3A }  // Sensor 13
};

for (int s=0; s<NUMBER_OF_SENSORS; S++) {
  float tempC = sensors.getTempC(SensorAddr[s]);
}

```

---
Tags: ds18b20
---


# Question
Title: Multiple if else statements for distance-triggered LEDs
I have a sketch that calculates simple distance from the device to the nearest preset GPS coordinate (there are 3 in total) and I would like to have LEDs in the neopixel strip light up according to the proximity of the location.

I managed to make it work with only one 5mm led and a simple if (shortestDist \< 10) then digitalWrite(ledPin, HIGH); - else ledpin low. But I want to use a neopixel strip with 7 leds to light up according to various distance criteria.

In my attempt here, I tried to make specific leds light up when 50, 30 and 10m away but it doesn't work properly, and it's a pretty crude approach, as are my coding "skills" :D

I would also like some help on how to make some kind of shorthand for specific led strip setup depending on distance - for example at 50m distance, 2 leds red, 5 leds off, at 30m distance 5 leds red, 2 leds off and so on.

Hope someone can assist the newb :D Currently the leds don't all shut off when the distance is higher than 50.

```
void loop()
{

while (ss.available() > 0)
    gps.encode(ss.read());
if (gps.location.isUpdated())
{
    Serial.print(F("Lat Lon = "));
    Serial.print(gps.location.lat(), 6);
    Serial.print(", ");
    Serial.println(gps.location.lng(), 6);
}
else if (millis() - last > 1000)
{
    Serial.println();
    if (gps.location.isValid())
    {
        double shortestDist;
        for (int i = 0; i < 3; ++i)
        {
            double distanceToDest =
                TinyGPSPlus::distanceBetween(
                    gps.location.lat(),
                    gps.location.lng(),
                    positions[i].lat,
                    positions[i].lon);
            if (!i || distanceToDest < shortestDist)
                shortestDist = distanceToDest;
        }
        Serial.print(F("Next in range = "));
        Serial.print(shortestDist, 2); // decimal
        Serial.println(" m");

        if (shortestDist < 50)
        {
          pixels.clear();
          pixels.setPixelColor(0, pixels.Color(0, 250, 0));
          pixels.setPixelColor(1, pixels.Color(0, 0, 0));
          pixels.setPixelColor(2, pixels.Color(0, 0, 0));
          pixels.setPixelColor(3, pixels.Color(0, 0, 0));
          pixels.setPixelColor(4, pixels.Color(0, 0, 0));
          pixels.setPixelColor(5, pixels.Color(0, 0, 0));
          pixels.setPixelColor(6, pixels.Color(0, 250, 0));
          pixels.show();
          delay(50);
        }

        else if (shortestDist < 30)
        {
          pixels.clear();
          pixels.setPixelColor(0, pixels.Color(0, 250, 0));
          pixels.setPixelColor(1, pixels.Color(250, 250, 0));
          pixels.setPixelColor(2, pixels.Color(0, 0, 0));
          pixels.setPixelColor(3, pixels.Color(0, 0, 0));
          pixels.setPixelColor(4, pixels.Color(0, 0, 0));
          pixels.setPixelColor(5, pixels.Color(250, 250, 0));
          pixels.setPixelColor(6, pixels.Color(0, 250, 0));
          pixels.show();
          delay(50);
        }

        else if (shortestDist < 10)
        {
          pixels.clear();
          pixels.setPixelColor(0, pixels.Color(250, 0, 0));
          pixels.setPixelColor(1, pixels.Color(0, 250, 0));
          pixels.setPixelColor(2, pixels.Color(0, 0, 0));
          pixels.setPixelColor(3, pixels.Color(250, 0, 250));
          pixels.setPixelColor(4, pixels.Color(0, 0, 0));
          pixels.setPixelColor(5, pixels.Color(0, 250, 0));
          pixels.setPixelColor(6, pixels.Color(250, 0, 0));
          pixels.show();
          delay(50);
        }

        else
        {
          pixels.clear();
          pixels.setPixelColor(0, pixels.Color(0, 0, 0));
          pixels.setPixelColor(1, pixels.Color(0, 0, 0));
          pixels.setPixelColor(2, pixels.Color(0, 0, 0));
          pixels.setPixelColor(3, pixels.Color(0, 0, 0));
          pixels.setPixelColor(4, pixels.Color(0, 0, 0));
          pixels.setPixelColor(5, pixels.Color(0, 0, 0));
          pixels.setPixelColor(6, pixels.Color(0, 0, 0));
          pixels.show();
          delay(50);
        }

    }
    if (gps.charsProcessed() < 10)
        Serial.println(F("No GPS data."));
    last = millis();
    Serial.println();
}

```

}

# Answer
> 0 votes
* Common inexpensive GPS modules are likely to report positions that appear to jump around by perhaps 5 meters in good conditions. Many factors affect GPS accuracy and this uncertainty. Some are listed here. It might be problematic to implement a 10 meter distance threshold feature unless conditions are favorable.
* Consider constraining your "if" tests more. For example, use "if ((shortestDist \<= 50) && (shortestDist \> 30))" instead of "if (shortestDist \< 50)". Continue similarly with the other "if" tests. Otherwise, once shorttestDist is less then 50 only the 1st "if" test is executed as it will become true and stay true and none of the other "it" tests will be considered.
* Consider only using mills(). The posted code uses delay() & millis(). Calling delay() is fine but using millis() is almost always better. Mixing the 2, though, should be avoided.
* The logic in the code might be incorrect. It appears GPS data is only process and the LEDs updated when GPS information is unavailable (not new).
* When writing embedded firmware, always consider hardware problem sources. Many find small batteries problematic during momentary current demands. Batteries with small Amp-Hour ratings are more prone to dropping their voltage during a high current events. Such as when a processor operates a relay or activates a sensor.

---
Tags: arduino-ide, gps, neopixel, tinygps
---


# Question
Title: Alternative to GPS location being calculated by radius around a point
Hopefully the thread title isn't confusing - I'm trying to find out how would it be possible to make a different way of proximity warning with GPS.

Default/simplest way is by forming a radius around a goal waypoint, so the proximity criteria will get triggered when you're "inside" the circle. I know about geofencing but that does seem very demanding and complex, so I'd like to ask if something like shown in this pic would be achievable.

So instead of proximity criteria being a radius around a waypoint, forming a circular geofence so to speak, would it be possible to create a half-circle like this, at a specific angle.

# Answer
> 2 votes
Let

* (`x`, `y`) be the Cartesian coordinates of the vector going from the waypoint to your position
* `radius` be the radius of the circle
* `theta` be the orientation of the straight line, in radians.

You can then build a unit vector normal to the straight line:

**n** = (cos(θ+π/2), sin(θ+π/2)) = (−sin θ, cos θ)

You are on the colored side of the line if the scalar product of **n** with (`x`, `y`) is positive.

In code:

```
bool is_inside(float x, float y)
{
    float product = - x * sin(theta) + y * cos(theta);
    float r2 = x * x + y * y;
    return r2 <= radius * radius && product >= 0;
}

```

---
Tags: gps
---


# Question
Title: How to convert Unicode char to “Unicode HEX Position” in Arduino
How to convert Unicode char to "Unicode HEX Position" in Arduino or C

i will share a picture here :

for example in JavaScript you can do that with `charCodeAt();` ! this function will return exactly the char-code and then you can convert it to hex!

for example in JavaScript i can do that like this to return exact table value

```
 var inpString = 'س';
    var myChar=0;
    var output = 0;
    myChar = inpString.charCodeAt(0);
    output = (ToHex((myChar&0xff00)>>8 )) + (ToHex( myChar&0xff ));

    function ToHex(i)
    {
        var sHex = "0123456789ABCDEF";
        var Out = "";
        Out = sHex.charAt(i&0xf);
        i>>=4;
        Out = sHex.charAt(i&0xf) + Out;
        return Out;
    }
 alert(output);

```

So how can i do that in Arduino ? its using to send unicode char in PDU mode in Arduino i just need to convert unicode char like this -\> 'س' to correct Unicode HEX Position that i shared in the picture above

for example 'س' is 0633 or 'A' is 0041 or 'ب' is 067E

# Answer
> 1 votes
Unlike JavaScript, C++ makes no difference between a character and its code point. Thus, `'A'`, `0x41` and `65` are just different ways of writing the same number.

Note, however, that the `char` type is intended to hold ASCII only. For everything else, you may try using wide characters. For example, the program

```
void setup() {
    Serial.begin(9600);
    wchar_t c = L'س';
    Serial.println(c, 16);
}

void loop() {}

```

outputs `633` on the serial port. Note the second argument to `Serial.println()` which specifies base 16. Default is to print numbers in decimal.

Beware that the representation of wide characters is implementation defined, and the avr-libc doesn't provide support for manipulating them or strings made with them. If you want to transmit them, you will also have to decide for yourself how to break them down into a sequence of bytes, as that's the only thing a serial port (or I2C, or SPI for that matter) can transmit. UTF-8 is the most popular choice. I doubt wide characters are popular in embedded systems at all.

# Answer
> 0 votes
This will read and print unicode characters from/to Serial Monitor and print their HEX codes. Please set the line ending in Serial Monitor to NL and confirm the entered character with Enter.

```
void setup() {
  Serial.begin(115200);
}

void loop() {
  if (Serial.available()) {
    char buff[4];
    int l = Serial.readBytesUntil('\n', buff, sizeof(buff) - 1);
    if (l > 0) {
      buff[l] = 0;
      Serial.println(buff);
      Serial.print(buff[0], HEX);
      if (l > 1) {
        Serial.print(buff[1], HEX);
      }
      Serial.println();
    }
  }
}

```

# Answer
> 0 votes
A reliable way to output Unicode chars is to use Octal equivalents in the string you are printing. e.g.

```
Serial.print("\342\204\211");

```

will output ℉ provided the receiver has font for that unicode.

Using Non-ASCII chars in Arduino has a .jar file that converts between Unicode chars, \u... strings and Octal

Hex \x.. is not used because C compilers can get confused if the next character after the two hex digits is 'a' to 'f'. Using octal avoids this problem. The GCC compiler used by Arduino also does not accept all unicode sequences such as \u0020

---
Tags: programming, c, communication
---


# Question
Title: Constantly Stream data vía Bluetooth to monitoring
I am using a Bluetooth module HC-05 to Stream data from Arduino to My computer. In they computer I am using a python script to receive

They specifications: Baud rate: 9600

But I am getting an error. The right data got in the computer should be:

b'123.098x726.8393x123x\r\n'

Which I almost always get, but sometimes I get the following:

b'123.098x726.8393x123x123.098x726.8393x123\r\n'. **wrong**

So I don't know happens, in python I use the method reset\_input\_buffer() and reset\_output\_buffer() and in Arduino ide I use Serial.flush()

The error keep happens, would it be the baudrate? I increase it would it be the solutionn?

Thanks in advance

```
String str;
String strs[8];

int pwm=9;

int tech;
String sync_fromApp = "?";
String sync_ok = "okx";

int cyc_num;
int PWM_0;
int PWM_i;
int PWM_f;

float volt;
float cur;
int t;

void setup() {
  // put your setup code here, to run once:
  TCCR1B = TCCR1B & B11111000 | B00000001;
  Serial.begin(9600);
  Serial.setTimeout(5);
  pinMode(A0, INPUT);
  pinMode(pwm, OUTPUT);
  analogWrite(pwm, 130);
  delay(1000);
}

void loop() {
  // put your main code here, to run repeatedly:
  int strCount = 0;
  if (Serial.available() > 0) {

    str = Serial.readString();
    str.trim();

    if (str == sync_fromApp) {
      Serial.println(sync_ok);
      //Serial.flush();
    }

    while (str.length() > 0) {
      int index = str.indexOf('x');
      if (index == -1) {
        strs[strCount++] = str;
        break;
      }
      else {
        strs[strCount++] = str.substring(0, index);
        str = str.substring(index + 1);
      }
    }

    tech = strs[0].toInt();
    float E0 = strs[1].toInt() / 1000.0;
    float Ei = strs[2].toInt() / 1000.0;
    float Ef = strs[3].toInt() / 1000.0;
    cyc_num = strs[4].toInt();
    int scan_rate = strs[5].toInt();
    int t_chro = strs[6].toInt();
    int t_step_chro = strs[7].toInt();
    float e00 = ((995.0 / 1986.0) * 5.06 + (995.0 / 1004.0) * E0);
    PWM_0 = e00 * (255 / 4.99); //Starting Voltage
    float eii = ((995.0 / 1986.0) * 5.06 + (995.0 / 1004.0) * Ei);
    PWM_i = eii * (255 / 4.99)-1; //Min Voltage
    float eff = ((995.0 / 1986.0) * 5.06 + (995.0 / 1004.0) * Ef);
    PWM_f = eff * (255 / 4.99)+1; //Max Voltage
    long t = (4990000L) / (256L * scan_rate); //delay scan rate
    //default:
    analogWrite(pwm, PWM_0);
    switch (tech) {
      //---Cyclic voltammetry---
      case 1:
        delay(3000);
        for (int n = 1; n <= cyc_num; n++) {
          for (int val = PWM_0; val < PWM_f; val++) {
            analogWrite(pwm, val);

            volt = 0.01974563 * val - 2.558; //0.01974563
            cur = 0.51469 * (analogRead(A0)) - 255.226; //254.226

            Serial.print(volt, 3);
            Serial.print('x');
            Serial.print(cur, 3);
            Serial.print('x');
            Serial.print(val);
            Serial.println('x');
            Serial.flush();
            delay(t);
          }

          for (int val = PWM_f; val > PWM_i; val--) {
            analogWrite(pwm, val);

            volt = 0.01974563 * val - 2.558;
            cur = 0.50669 * (analogRead(A0)) - 255.226;
            //cur_ave = analogRead(A0);
            Serial.print(volt, 3);
            Serial.print('x');
            Serial.print(cur, 3);
            Serial.print('x');
            Serial.print(val);
            Serial.println('x');
            Serial.flush();
            delay(t);
          }
          PWM_0 = PWM_i;
          //Serial.println(n);
        }
        Serial.println("Nx");
        Serial.flush();
        analogWrite(pwm, 130);
        tech = 0;
        break;
      default:
        break;
    }
  }
  else {
    digitalWrite(13, HIGH);
    delay(200);
    digitalWrite(13, LOW);
    delay(200);
  }
}

```

Above left the arduino sketch.

Below is the python code

```
            self.ser.write(self.parametersToArduino.encode()) #command to start stream
            pass

        self.ser.reset_input_buffer()   #flush input buffer
        self.ser.reset_output_buffer()   #flush output buffer
        COM.stop_button["state"] = "active"

        while self.threading:
            try:
                data.RowMsg = self.ser.readline()  # read data from arduino
                data.DecodeMsg()                   #decode data from arduino
                if len(data.RowMsg)>0:
                    if b'N' in data.RowMsg:
                        #print("It's over")

                        self.threading = False
                        break
                    data.upXData()  #update a list to plot
                    data.upYData()  #update a list to plot
                    self.ser.reset_input_buffer()
                    self.ser.reset_output_buffer()
                    pass
                pass
            except Exception as e:
                print(e)
                pass

```

DecodeMsg is the code below

```
    def DecodeMsg(self):
        temporal = self.RowMsg.decode('utf8')
        if len(temporal)>0:
            if "x" in temporal:
                self.msg = temporal.split("x")
                del self.msg[-1]
                pass
            print(self.msg) #debugg
            pass
        pass

```

# Answer
> 0 votes
I'm not sure that this an answer, but it is easy to implement and may help you figure out what is going on.

I don't think it is a baud rate problem because the characters appear to be intact, but some are missing. I think it is a serial buffer overflow resulting in a mix of old and new characters.

To test this out, I would insert a counter into the beginning of the "packet" being sent. My suspicion is that when you see the error, you will be able to see that one packet is being messed up when it overflows. So, you might get something like this (where the first 3 digits are the packet number):

b'**001**123.098x726.8393x123x\r\n' b'**001**123.098x726.8393x123x123.098x726.8393x123\r\n b'**003**123.098x726.8393x123x\r\n'

It may not be definitive, but might help to more clearly see what is happening.

Before doing this, I would probably comment out: TCCR1B = TCCR1B & B11111000 | B00000001; which is increasing the PWM frequency on 9. That, just to see if this changes the behavior since it is so easy to test out.

Hope it helps, but I admit that it is just a suggestion.

BTW: interesting problem and I hope you will tell us what happens.

---
Tags: arduino-nano, python, hc-05, data, stream
---


title: EspAsyncWebServer process HTTPS to HTTP

text:
# Question
Title: EspAsyncWebServer process HTTPS to HTTP
I read this issue. But I didn't understand it. Like the author I don't have an SSL certificate and I don't want to have one (because if I had one I could live with HTTPS!).

I just want to process any `https://<url>` request like it was `http://<url>`. It can be a redirect but the answer states:

```
server.on("/redirect/internal", HTTP_GET, [](AsyncWebServerRequest *request){
  request->redirect("/hello");
});

server.on("/redirect/external", HTTP_GET, [](AsyncWebServerRequest *request){
  request->redirect("https://techtutorialsx.com/");
});

```

Ok, but how to detect if the request was HTTP or HTTPS?

# Answer
This isn't something you can do.

What you're asking for is like saying "I have to screw something together but I really only want to use a hammer, so how do I hammer the screw?". The answer is, you don't.

In this case the ESP32 is a server. The web browser is a client. The web browser is speaking HTTPS. When the browser makes an HTTPS request to the server, HTTPS is the **only** thing the browser will accept. HTTPS include a security layer (that's the "S" part) which is what requires certificates. If the server is not capable of handling that security layer (which it's not if it doesn't have an SSL certificate) then the only thing it can do is reject the connection by either not listening for it or immediately closing it

There is no communication between the client and server if the server isn't configured with certificates and can't speak TLS (the security layer) with the client. Allowing the server to downgrade the security when the client requests it would be a huge general security issue for the web. It's designed to not allow this.

Either support HTTPS properly, get the client to speak HTTP, or just don't do this at all. Those are your options.

As for detecting HTTP vs HTTPS, it depends on the port your server listened on. If you listen on port 80, you get HTTP requests. If you listen on port 443 you get HTTPS. If you're not listening on a port, the request of that type is refused (reset).
> 2 votes

---
Tags: esp32, web-server, http
---


# Question
Title: Best way to "hack" a library without forking it
I'm using Visual Studio Code and PlatformIO. I added some libraries to my project using `platformio.ini`:

```
lib_deps =
    olikraus/U8g2@^2.34.4
    crankyoldgit/IRremoteESP8266@^2.8.4
    plerup/EspSoftwareSerial@^6.16.1
    rlogiacco/CircularBuffer@^1.3.3
    https://github.com/me-no-dev/ESPAsyncWebServer.git
    makuna/NeoPixelBus@^2.7.0
    adafruit/Adafruit BusIO@^1.13.2
    bblanchon/ArduinoJson@^6.19.4
    adafruit/Adafruit PN532@^1.2.2
    khoih-prog/ESPAsync_WiFiManager@^1.15.1
    https://github.com/guestisp/ESP32AsyncDNSServer.git

```

Now, let's say I have to "hack" few lines of code inside a library to fit my needs. Since it's a very specific change (not something that can be useful to others) I can easily change directly the source code without forking it on github.

The downside is every time I download again the libraries (or set up another dev machine) I lose all my changes.

I can also move the downloaded library to the `lib/` subfolder in the project tree, removing the dependency from `lib_deps`.

I wonder if there is a more reliable way to do this, i.e. applying a patch after downloading the code (yocto-like).

# Answer
> 2 votes
Use a local source control and repository of your choice. Obtain the latest published rev of the library and make your changes to it (I assume you have already done this, probably a number of times). Check in your changed revision of the library to your local repository. When a new rev becomes available, obtain it and *merge* it into your local repository.

Update:

> One problem of this approach is I will end up with nested repositories.

I'm coming from old-school source control - file management. rcs, in my case (don't laugh). I'm guessing your local modifications affect only one or a few of the library files. Mightn't something that simple - a file-level merge - solve your issue (regardless of which tool you choose to do it)?

---
Tags: library, platformio, vscode
---


title: Pause code untill a button is pressed

text:
# Question
Title: Pause code untill a button is pressed
I need some code to pause the Arduino code until a button is pressed. I have a long program and at point I need a condition that if a Button on pin A2 is pressed then go forward, otherwise wait.

I tried using `if` with a condition but it failed for my purpose. I think this is because when `if(...)` detects that the button is not pressed, it moves to next lines (as usual). But I have a long program and I want to wait forever until the button is pressed.

# Answer
> 3 votes
The construct you are looking for is called `while`.

Instead of doing "If the button is pressed then continue" you need to do "while the button is not pressed do nothing".

Assuming you have an "active low" button (that is, a resistor pulling it up to +5V when not pressed, so `digitalRead(A2) == LOW` is "pressed"), you can do:

```
while (digitalRead(A2) == HIGH) {
  // Do nothing
}

```

So while it's not pressed (`digitalRead(A2) == HIGH`) don't do anything. As soon as `digitalRead(A2)` returns LOW (so it is not `== HIGH` any more) the `while` loop will finish and your sketch can continue.

I write all about the `while` loop in an article here.

# Answer
> 2 votes
> I need a code to pause arduino code until a button is pressed.

I wrote a simple function to do this.

### Usage:

```
buttonWait(<pin_number>);

```

### Code:

```
/* the function */
void buttonWait(int buttonPin){
  int buttonState = 0;
  while(1){
    buttonState = digitalRead(buttonPin);
    if (buttonState == HIGH) {
      return;
    }
  }
}

void loop() {
  buttonWait(2); // wait for button press on pin 2
  // do something
  // ...
}

```

This code assumes that you have a pulldown resistor, but you can easily modify it to work with a pullup resistor instead, if you feel the need:

simulate this circuit – Schematic created using CircuitLab

See example code here!

# Answer
> 1 votes
Here are two ways you might have wired the button. If you wired it with a pullup, you will need to test for LOW (the button will ground its output when pressed). If pulldown, the button will raise its output when pressed and you would test for HIGH.

If you will be testing the button again within less than a second, don't forget to debounce it. Switches send a bunch (technical term :) of pulses for a significant fraction of a second during a make or bread. See Nick Gammon's "Switches" page for a thorough discussion.

# Answer
> -1 votes
Pausing a program can be accomplished using Light Sleep mode as demonstrated in given URL: https://www.youtube.com/watch?v=GIbSt5mJ5VY

---
Tags: arduino-uno
---


title: Driving APA102C strips from Mega 2560

text:
# Question
Title: Driving APA102C strips from Mega 2560
I have written (cobbled together from code snippets) an Arduino program that pushes various patterns down 160 APA102C LED strips (5). I originally was using a 5V 40A power supply and everything worked peachy. That was when the length from the clock and data pins was maybe 6-8 inches. Now I am try to get ready for a XMAS parade and attaching 100 LED strips. I have the power but the data and clock pins aren't getting to the strips. Is there some quick and dirty (not a real electronics guy here, just a code pusher) method to get signals out to the strips, maybe 6 feet? I would greatly appreciate any help I could get and I'm sure the kiddies would have Santa throw some extra goodies your way if I could get this figured out. I've got like 10 days.....YIKES!!!!

Thanks so much!!!! And Happy Holidays

Joe B

# Answer
> 1 votes
For a quick and dirty way you could cut a few LEDs from your strip, so that you have a number of single LEDs. Then you can place one LED after X feet of cable. Each LED receives its own data and outputs the signal for the next LED. So the signal after an LED is of the same quality as of the first signal. At least that is what can be done with other similar RGB LED strips. I would bet, that this is also the case for this type.

Before wiring everything up you should probably experiment a bit with the cable length. Test how long you can make the cable until you see problems. Then make the cables inbetween the LEDs shorter than that.

If you don't want these intermediate LEDs to light up, you can set them to off in your program.

Another - not so quick and dirty - way would be to put one microcontroller near the start of each cluster of strips (where one or multiple or all strips start) and let them communicate with a master microcontroller using an interface for longer distances (like RS485).

Depending on your situation the quick and dirty method might be enough.

---
Tags: power
---


title: Arduino 16 MHz with only 3.3V?

text:
# Question
Title: Arduino 16 MHz with only 3.3V?
Now I have these Arduino Pro Mini from Sparkfun. They are the latest version that I know (yeah, it's the one that have those horrible misaligned pins). Now they are designed around the ATmega328P and have a 16MHz crystal on them.

Now, my question is: Can I run an ATmega328 with a 16MHz crystal while supplying ONLY 3.3V.

The reason I'm doing this is because 5V / 16MHz Pro Minis from China are way cheaper then 3.3 / 8MHz.

Facts that I already know:

If I follow the datasheet to the the letter, this configuration should not work. BUT... After some test, it did work.

Also, I want an answers based on *personal experience* (NOT OPINIONS) and not datasheet and specs.

---

***\[EDIT\]*** Including a way to use the internal clock (at 8MHz) of the ATmega328P would really help!

# Answer
> 9 votes
Officially, no. Practically, often but not always.

> If I follow the datasheet to the the letter, this configuration should not work. BUT... After some test, it did work.

The data sheet does not say that it "should not" work, it says that it is that the part is *not qualified* for operation at 16 MHz below some voltage higher than you want to use. That does not mean that a given chip cannot work there, it only means that a chip that fails to may not be considered "bad". Failure may be total and obvious or subtle.

In practice I have seen it work, both on small modified import boards and those with switchable power supply voltage. But I also recall seeing it fail to work.

Two factors that can make a theoretical difference are part-to-part manufacturing variation and operating temperature.

Note that with an ISP setup you can change the fuses to run the chip on what was sold as a 5v external crystal board, to operate from the internal 8 MHz oscillator instead, *and you can do this even while leaving the crystal on the board*. If you also change the brownout detector fuse, you can lower the voltage further, for example to operate without a regulator directly on two AA cells. Of course that applies to the ATmega itself - any other active components on the board would have to be qualified for the intended voltage too.

# Answer
> 5 votes
According to the datasheet you need 3.78V to run at 16 MHz, and 3.3V isn't that far off. I would be surprised, for example, if it stopped working at 3.77V, because that would mean that the operating at 3.78V was marginal.

I have operated these chips out of spec, for example under voltage, or with a 24 MHz crystal. They *seem* to work. However I would guess that Atmel's position would be: *if you operate out of our specs, don't come crying to us if it is unreliable*.

A few percent out of spec will probably work - and 3.3V is 87% of 3.78V. They write those specs to allow for fluctuations in the manufacturing process, and are confident that *all* their chips would meet them. Probably a lot of chips would be over spec.

---

> Including a way to use the internal clock (at 8MHz) of the ATmega328P would really help!

Set the fuses appropriately. See Engbedded Atmel AVR® Fuse Calculator

For the Atmega328P making the low fuse be 0xE2 should do it.

---

> The reason I'm doing this is because 5V / 16MHz Pro Minis from China are way cheaper then 3.3 / 8MHz.

Be cautious that cheap clone boards may be manufactured with manufacturers' "seconds".

# Answer
> 4 votes
A little test, not very scientific, but shows it runs fine on 3.3V - https://www.youtube.com/watch?v=If0eOa0Uj5I.

Again, if you would like to stay withing the specification just use a "clock divider/2" and run your MCU at 8MHz if they have a 16MHz Crystal:

```
clock_prescale_set(clock_div_2)

```

http://www.nongnu.org/avr-libc/user-manual/group\__avr\__power.html

# Answer
> 3 votes
I've built a few 3.3v home-brew-duinos with 16Mhz crystals (because I have a bag of 50 xtals!) - they run fine in the conditions I've put them in so far (on my desk). Some of them may be closer to their margins than others, and might fail at at some otherwise in-spec temperature, for example. If these were intended to go outside (enclosed, of course), I'd have to test them against the conditions they might be subjected to. Or redesign them to keep them in spec in the first-place.

I think the only way to know is to try it on your board and see. I don't have or know of a test-suite for the chip; I've just uploaded known-working sketches to my experimental boards and had no obvious glitches. Yet.

# Answer
> 1 votes
I am running my atmega328p chip with 3.3 volts because I did not wanted to use a voltage divider when powering the NRF24L01 that is part of my circuit. Because I only have 16mhz crystals and I don't know how to lower the frequency to 8mhz I been running my project with 3.3v and it works great. I been running this code for over a year and I have had no problems.

The code works great even at 2.8v running at 16mhz. At 2.65v it stops working.

# Answer
> 1 votes
You can use the clock prescaler in conjunction with the CKDIV8 fuse to operate with an 8MHz clock but using a 16MHz crystal.

See the "CLKPR – Clock Prescale Register" details in the data sheet for details (Page 36 in my data sheet 07/2012).

Basically you set the CKDIV8 fuse so the processor runs at 2MHz after power-up. Then once up and running you set the division ratio to 2 which would give 8MHZ operation which is guaranteed at 3.3V.

# Answer
> 1 votes
Atmega48/168/328's datasheet graph (under *"29.3: Speed Grades"*) presents maximum safe clock speed for given *VDD* voltage. It consists of three mathematical functions - 1 constant and 2 linear. I managed to calculate their formulas and sum them up:

where:

*x* is a *VDD* voltage \[V\] and *y* \- max safe clock speed \[MHz\] you can achieve with the voltage. I've done it, because I've had a need to check, if 3.3V power supply is enought for a 12MHz crystal - and it is (around 13,3MHz max.).

---
Tags: atmega328, arduino-pro-mini, oscillator-clock
---


title: Multiple unique I2C devices interfere

text:
# Question
Title: Multiple unique I2C devices interfere
I'm trying to make a fairly simple program that interfaces with the Adafruit TSL2591 light sensor as well as a MAX30102 pulse oximeter. They both use I2C for communication. I'm using the recommended libraries for both, Adafruit\_TSL2591\_Library *Version 1.4.3* and SparkFun\_MAX3010x\_Sensor\_Library *Version 1.1.2* respectively. This is all running on an Arduino UNO, although I will be transferring it to a NANO in the near future. All of the following is using *Version 2.0.2* of the Arduino IDE.

The issue I'm running into is that both sensors will work perfectly fine in isolation, but when trying to run at the same time it locks up and outputs nothing.

Example code that works for the Light sensor.

Example code that works for the pulse oximeter.

I know my wiring is good because the sensors work individually with either program even when both sensors are plugged in simultaneously.

The code that almost works:

```
#include <Wire.h>
#include "MAX30105.h"
#include "spo2_algorithm.h"
#include <Adafruit_Sensor.h>
#include "Adafruit_TSL2591.h"

MAX30105 particleSensor;

const byte LUX_ADDR = 0x29;
const byte OX_ADDR = 0x57;

Adafruit_TSL2591 tsl = Adafruit_TSL2591(2591);

#define MAX_BRIGHTNESS 255

#if defined(__AVR_ATmega328P__) || defined(__AVR_ATmega168__)
//Arduino Uno doesn't have enough SRAM to store 100 samples of IR led data and red led data in 32-bit format
//To solve this problem, 16-bit MSB of the sampled data will be truncated. Samples become 16-bit data.
uint16_t irBuffer[100]; //infrared LED sensor data
uint16_t redBuffer[100];  //red LED sensor data
#else
uint32_t irBuffer[100]; //infrared LED sensor data
uint32_t redBuffer[100];  //red LED sensor data
#endif

int32_t bufferLength; //data length
int32_t spo2; //SPO2 value
int8_t validSPO2; //indicator to show if the SPO2 calculation is valid
int32_t heartRate; //heart rate value
int8_t validHeartRate; //indicator to show if the heart rate calculation is valid

void setup()
{
  Serial.begin(115200); // initialize serial communication at 115200 bits per second:

  // Initialize sensor
  if (!particleSensor.begin(Wire, I2C_SPEED_FAST, OX_ADDR)) //Use default I2C port, 400kHz speed
  {
    Serial.println(F("MAX30105 was not found. Please check wiring/power."));
    while (1);
  }

  byte ledBrightness = 60; //Options: 0=Off to 255=50mA
  byte sampleAverage = 4; //Options: 1, 2, 4, 8, 16, 32
  byte ledMode = 2; //Options: 1 = Red only, 2 = Red + IR, 3 = Red + IR + Green
  byte sampleRate = 100; //Options: 50, 100, 200, 400, 800, 1000, 1600, 3200
  int pulseWidth = 411; //Options: 69, 118, 215, 411
  int adcRange = 4096; //Options: 2048, 4096, 8192, 16384

  particleSensor.setup(ledBrightness, sampleAverage, ledMode, sampleRate, pulseWidth, adcRange); //Configure sensor with these settings

  light_sensor_details();

  light_sensor_configure();

}

void loop()
{
  bufferLength = 100; //buffer length of 100 stores 4 seconds of samples running at 25sps

  //read the first 100 samples, and determine the signal range
  for (byte i = 0 ; i < bufferLength ; i++)
  {
    while (particleSensor.available() == false) //do we have new data?
      particleSensor.check(); //Check the sensor for new data

    redBuffer[i] = particleSensor.getRed();
    irBuffer[i] = particleSensor.getIR();
    particleSensor.nextSample(); //We're finished with this sample so move to next sample

    Serial.print(F("red="));
    Serial.print(redBuffer[i], DEC);
    Serial.print(F(", ir="));
    Serial.println(irBuffer[i], DEC);
  }

  //calculate heart rate and SpO2 after first 100 samples (first 4 seconds of samples)
  maxim_heart_rate_and_oxygen_saturation(irBuffer, bufferLength, redBuffer, &spo2, &validSPO2, &heartRate, &validHeartRate);

  //Continuously taking samples from MAX30102.  Heart rate and SpO2 are calculated every 1 second
  while (1)
  {
    //dumping the first 25 sets of samples in the memory and shift the last 75 sets of samples to the top
    for (byte i = 25; i < 100; i++)
    {
      redBuffer[i - 25] = redBuffer[i];
      irBuffer[i - 25] = irBuffer[i];
    }

    //take 25 sets of samples before calculating the heart rate.
    for (byte i = 75; i < 100; i++)
    {
      while (particleSensor.available() == false) //do we have new data?
        particleSensor.check(); //Check the sensor for new data

      redBuffer[i] = particleSensor.getRed();
      irBuffer[i] = particleSensor.getIR();
      particleSensor.nextSample(); //We're finished with this sample so move to next sample

      //send samples and calculation result to terminal program through UART
      Serial.print(F("red="));
      Serial.print(redBuffer[i], DEC);
      Serial.print(F(", ir="));
      Serial.print(irBuffer[i], DEC);

      Serial.print(F(", HR="));
      Serial.print(heartRate, DEC);

      Serial.print(F(", HRvalid="));
      Serial.print(validHeartRate, DEC);

      Serial.print(F(", SPO2="));
      Serial.print(spo2, DEC);

      Serial.print(F(", SPO2Valid="));
      Serial.println(validSPO2, DEC);
    }

    //After gathering 25 new samples recalculate HR and SP02
    maxim_heart_rate_and_oxygen_saturation(irBuffer, bufferLength, redBuffer, &spo2, &validSPO2, &heartRate, &validHeartRate);

    light_sensor_read();

  }
}

void light_sensor_details () {

  sensor_t sensor;
  tsl.getSensor(&sensor);

  delay(500);

}

void light_sensor_configure () {

  delay(200);
  tsl.setGain(TSL2591_GAIN_MED);
  delay(200);
  tsl.setTiming(TSL2591_INTEGRATIONTIME_100MS);
  delay(200);
  tsl2591Gain_t gain = tsl.getGain();

}

void light_sensor_read() {

  uint32_t lum = tsl.getFullLuminosity();
  uint16_t ir, full;
  ir = lum >> 16;
  full = lum & 0xFFFF;

  Serial.print(F("Lux: ")); Serial.println(tsl.calculateLux(full, ir), 6);
}

```

The pulse oximeter part will function correctly with the last two lines of `setup()` and the last line of `loop()` commented. `light_sensor_details();`,`light_sensor_configure();` and `light_sensor_read();` respectively. The output with these two lines commented is as follows:

```
red=4229, ir=3967
red=4530, ir=3790
red=3629, ir=4104
red=3563, ir=5211
red=4555, ir=9076
red=7091, ir=16753
red=13068, ir=23695
red=10753, ir=11273
...
red=31031, ir=48271, HR=-999, HRvalid=0, SPO2=-999, SPO2Valid=0
red=31044, ir=48283, HR=-999, HRvalid=0, SPO2=-999, SPO2Valid=0
red=31017, ir=48289, HR=-999, HRvalid=0, SPO2=-999, SPO2Valid=0
red=31027, ir=48306, HR=-999, HRvalid=0, SPO2=-999, SPO2Valid=0
red=31022, ir=48291, HR=-999, HRvalid=0, SPO2=-999, SPO2Valid=0
red=31016, ir=48271, HR=-999, HRvalid=0, SPO2=-999, SPO2Valid=0
red=30997, ir=48294, HR=-999, HRvalid=0, SPO2=-999, SPO2Valid=0
red=30981, ir=48268, HR=-999, HRvalid=0, SPO2=-999, SPO2Valid=0
red=30966, ir=48289, HR=-999, HRvalid=0, SPO2=-999, SPO2Valid=0
red=30981, ir=48293, HR=-999, HRvalid=0, SPO2=-999, SPO2Valid=0
...

```

(An expected output given my finger wasn't on the sensor for this.)

If I uncomment the 2nd last line of `setup()` then it still manages to show the red and ir values but never starts to show the calculated values. Instead it will occasionally (unpredictably) show chunks of invalid characters, like so:

Going further and uncommenting the other two lines simply locks up and prints nothing to the serial monitor.

Also to clarify the three light sensor related functions do work in their own file, I'll include it here for the sake of completeness:

```
#include <Wire.h>
#include <Adafruit_Sensor.h>
#include "Adafruit_TSL2591.h"

Adafruit_TSL2591 tsl = Adafruit_TSL2591(2591);

void setup()
{
  Serial.begin(115200); // initialize serial communication at 115200 bits per second:

  light_sensor_details();
  light_sensor_configure();
}

void loop()
{
  light_sensor_read();
}

void light_sensor_details () {

  sensor_t sensor;
  tsl.getSensor(&sensor);

  delay(500);

}

void light_sensor_configure () {

  tsl.setGain(TSL2591_GAIN_MED);
  tsl.setTiming(TSL2591_INTEGRATIONTIME_300MS);

  tsl2591Gain_t gain = tsl.getGain();

}

void light_sensor_read() {

  uint32_t lum = tsl.getFullLuminosity();
  uint16_t ir, full;
  ir = lum >> 16;
  full = lum & 0xFFFF;

  Serial.print(F("Lux: ")); Serial.println(tsl.calculateLux(full, ir), 6);
}

```

Running this outputs:

```
...
Lux: 41.283641
Lux: 36.879783
Lux: 10.549278
Lux: 2.826355
Lux: 11.158865
Lux: 1.489472
Lux: 1.713600
Lux: 31.461915
Lux: 48.357471
Lux: 50.827312
...

```

I think the issue is something to do with the I2C bus, but because both sensors use their own libraries for communication I can't use the online examples for manually starting and stopping communication with the *Wire* library. I can't find anyone else online with this issue or any examples of multiple I2C devices that I'm able to make use of (to my understanding).

Am I on the right track with it being an I2C problem? Is there a simple fix that I'm simply unaware of? Or is there a separate issue with my code?

Many thanks for any help!

Edit: Changed Title

# Answer
> 3 votes
It turns out the issue was with limited dynamic memory. The MAX30105 requires a lot of space for its calculations and adding anything else, whether that be another sensor or even a software serial connection, would crash it. Even using `Serial.println()` put it over the edge. **It became unstable beyond around 89% full, or about 250 bytes of empty dynamic memory.**

I ended up using a 32u4 equipped board to solve the memory issue and it worked perfectly after that.

It had nothing to do with I2C.

---
Tags: arduino-uno, serial, i2c
---


# Question
Title: 3.5mm jack frequency response at low frequency (20Hz)
I'm trying to drive a bass shaker at low frequencies, down to 20Hz, with an Arduino. Has anyone ever done something like this?

I found an audio amp that takes in 3.5mm aux, and I was hoping to get a 3.5mm jack to drive the amp from an Arduino. However, I can't find any technical specs on audio jacks so I am not sure if they support low frequencies. Are there any audio jacks with frequency response data available?

If not, are there other ways to achieve this?

# Answer
> 0 votes
You can send DC (i.e. 0 Hz) through an audio jack, so I would not worry about its low-frequency response.

---
Tags: audio
---


# Question
Title: Arduino code works when connected to laptop, not when connected to battery or wall socket
So I have an Arduino nano, and I am using two SG90 servos, and 1 BMP280, and 1 MPU6050. My code works fine when I plug my nano into my computer, but when I connect the battery to my nano, it doesn't run. The servo moves to 90 degrees, but it seems that it is not detecting the sensor data and not moving the servo. I commented out all calls to `Serial`. Here is my code:

```
/***************************************************************************
  This is a library for the BMP280 humidity, temperature & pressure sensor

  Designed specifically to work with the Adafruit BMP280 Breakout
  ----> http://www.adafruit.com/products/2651

  These sensors use I2C or SPI to communicate, 2 or 4 pins are required
  to interface.

  Adafruit invests time and resources providing this open source code,
  please support Adafruit andopen-source hardware by purchasing products
  from Adafruit!

  Written by Limor Fried & Kevin Townsend for Adafruit Industries.
  BSD license, all text above must be included in any redistribution
 ***************************************************************************/

#include <Wire.h>
#include <SPI.h>
#include <Adafruit_BMP280.h>

// MPU
#include <MPU6050.h>

// Servo
#include <Servo.h>

Servo servoY;
Servo servoX;

MPU6050 mpu;

// Timers
unsigned long timer = 0;
float timeStep = 0.01;

// Pitch, Roll and Yaw values
float pitch = 0;
float roll = 0;
float yaw = 0;

#define BMP_SCK  (13)
#define BMP_MISO (12)
#define BMP_MOSI (11)
#define BMP_CS   (10)

Adafruit_BMP280 bmp; // I2C
//Adafruit_BMP280 bmp(BMP_CS); // hardware SPI
//Adafruit_BMP280 bmp(BMP_CS, BMP_MOSI, BMP_MISO,  BMP_SCK);

void pitch_roll_yaw(){
  // Serial.print("Pitch: ");
  // Serial.println(pitch);

  // Serial.print("Roll: ");
  // Serial.println(roll);

  // Serial.print("Yaw: ");
  // Serial.println(yaw);
  int thsjsojf = 1;
}

void setup() {
  // Servo
  servoY.attach(8);
  servoY.write(90);

  servoX.attach(9);
  servoX.write(90);

  // Serial.begin(115200);
  // while ( !Serial ) delay(100);   // wait for native usb
  // Serial.println(F("BMP280 test"));
  unsigned status;
  //status = bmp.begin(BMP280_ADDRESS_ALT, BMP280_CHIPID);
  status = bmp.begin();
  if (!status) {
    // Serial.println(F("Could not find a valid BMP280 sensor, check wiring or "
    //                   "try a different address!"));
    // Serial.print("SensorID was: 0x"); Serial.println(bmp.sensorID(),16);
    // Serial.print("        ID of 0xFF probably means a bad address, a BMP 180 or BMP 085\n");
    // Serial.print("   ID of 0x56-0x58 represents a BMP 280,\n");
    // Serial.print("        ID of 0x60 represents a BME 280.\n");
    // Serial.print("        ID of 0x61 represents a BME 680.\n");
    while (1) delay(10);
  }

  /* Default settings from datasheet. */
  bmp.setSampling(Adafruit_BMP280::MODE_NORMAL,     /* Operating Mode. */
                  Adafruit_BMP280::SAMPLING_X2,     /* Temp. oversampling */
                  Adafruit_BMP280::SAMPLING_X16,    /* Pressure oversampling */
                  Adafruit_BMP280::FILTER_X16,      /* Filtering. */
                  Adafruit_BMP280::STANDBY_MS_500); /* Standby time. */

  // MPU
  while(!mpu.begin(MPU6050_SCALE_2000DPS, MPU6050_RANGE_2G))
  {
    // Serial.println("Could not find a valid MPU6050 sensor, check wiring!");
    delay(500);
  }

  // Calibrate gyroscope. The calibration must be at rest.
  // If you don't want calibrate, comment this line.
  mpu.calibrateGyro();

  // Set threshold sensivty. Default 3.
  // If you don't want use threshold, comment this line or set 0.
  mpu.setThreshold(3);

}

int incrementPitch = 0;
int curAngle = 90;
int incrementPitchDown = 0;

void loop() {
    timer = millis();
    // Read normalized values
    Vector norm = mpu.readNormalizeGyro();

    // Calculate Pitch, Roll and Yaw
    pitch = pitch + norm.YAxis * timeStep;
    roll = roll + norm.XAxis * timeStep;
    yaw = yaw + norm.ZAxis * timeStep;

    float normalY = norm.YAxis;

    // Serial.print(F("Temperature = "));
    // Serial.print(bmp.readTemperature());
    // Serial.println(" *C");

    // Serial.print(F("Pressure = "));
    // Serial.print(bmp.readPressure());
    // Serial.println(" Pa");

    // Serial.print(F("Approx altitude = "));
    // Serial.print(bmp.readAltitude(1013.25)); /* Adjusted to local forecast! */
    // Serial.println(" m");

    // pitch_roll_yaw();

    //TODO: This works, but if pitch > 1 and the servo arm is already at max, it doesn't move. Fix.
    // TODO: If pitch < 1. move the servo in the opposite way by 5 degrees. Need to track current angle.
    if(pitch>1){
      // Serial.println("PITCH IS GREATER++++++THAN 1, MOVING Y SERVO");
      servoY.write(curAngle+incrementPitch);
      curAngle = curAngle+incrementPitch;
      // Serial.print("Pitch: ");Serial.println(pitch);
      if(curAngle>180){
        // This is just so we don't print the current angle if curAngle > 180. This can be antything.
        int something = 1;
      } else {
        // Serial.print("Current Angle of Y servo: ");Serial.println(curAngle);
      }
      incrementPitch+=6;
    } else if(pitch<-1){
      // TODO: If pitch is < -1, then we move the servo in 5 degree increments starting at the current angle. Right now it jumps some degrees, check the if(pitch>1) for errors? MUST FIX.
      // Serial.println("Pitch is LESS---------THAN 1, MOVING Y SERVO");
      servoY.write(curAngle-incrementPitchDown);
      curAngle = curAngle-incrementPitchDown;
      incrementPitchDown+=6;
    }

    // Serial.println();
    delay(200);
}

```

ALso, none of the other threads solve my problems.

# Answer
If are you powering the servo's via your Nano (and thus the USB port), this will cause problems. The Servo's need need 500/700 mA each (\>1 Amp total). My laptop USB is 500mA, so rotating two servo's will cause a power drop (voltage goes down due the draw of current).

in my experience using servo's when connected to a computer/laptop is not reliable. This will happen: the servo rotates, the power drops causing the Microcontroller to restart or cause problems (voltage) for the sensor.
> 0 votes

---
Tags: arduino-nano
---


# Question
Title: Simple FastLED sketch that crashes when led strip is long but not when its shorter
I have a pretty simple sketch that crashes, and crashes hard (Platform.io console says "Disconnected (read failed: \[Errno 6\] Device not configured)" and I need to power off/on the Arduino to continue.

The sketch does not crash and seems to work fine when I use a smaller number of LEDS but crashes after a few seconds when I use a longer number of LEDS. Seems like a strange hardware issue because the sketch looks simple! I have added a lot of Serial.print(ln)'s to verify it is doing what I think it is, and it does... until the crash!

This will run forever, but if I change cNumLeds from 60 to 160 it crashes (and my actual LED strip has 300 LEDs and I use all of them in other sketches).

```
#include <Arduino.h>
#include <FastLED.h>

const uint16_t cDataPin = 15;
const uint16_t cNumLeds = 60;

CRGB leds[cNumLeds];

void setup() {
   Serial.begin(9600);
   FastLED.addLeds<WS2812B, cDataPin, GRB>(leds, cNumLeds).setCorrection(TypicalLEDStrip).setDither(true);
   FastLED.setBrightness(127);
   FastLED.clear();
   FastLED.show();
   FastLED.delay(100);
}

uint16_t offset = 0;
CRGB colors[] = {CRGB::White, CRGB::Red, CRGB::White, CRGB::Green, CRGB::White, CRGB::Black};
byte numColors = sizeof(colors)/sizeof(colors[0]);
uint32_t cycle = 75;

void loop() {
  EVERY_N_MILLISECONDS(cycle) {
    for (uint16_t i = 0; i < cNumLeds; i++) {
        leds[i] = colors[(i + offset) % numColors];
    }
    offset = (1 + offset) % cNumLeds;
  }
  FastLED.show();
}

```

Any tips for debugging greatly appreciated ! (And apologies in advance for my C++ style, I am a confirmed C programmer trying not to do any damage in C++)

# Answer
> powering from the 5V Arduino pin.

You should not do this. You can fry the voltage regulator or the protection diode doing this (depending on how you supply the power).

When you draw more current from a power source than it can supply, first the voltage will drop. If the voltage drops enough the Arduino will brown out and reset as soon as the voltage is up again. If you keep drawing that much power, you can fry parts of the power source (in this case your Arduino). Sometimes this is reversible, when the power source has some kind of emergency shutdown (like the voltage regulator of a genuine Arduino Uno). Otherwise it will get destroyed.

When controlling power hungry devices like LED strips you should connect their power lines directly to your power supply (given it has the correct voltage). That way the current doesn't have to flow through the Arduino. Also you need a power supply, that can handle your peak current. The RGB strips with WS2812 drivers can draw up to 60mA per LED (on white in full brightness). So for a strip with 160 of them it would be a current of `60mA * 160 = 9.6A`. Add a little headroom and you would need a power supply, that can at least provide 10A of current.

> But i have run other sketches, much more complex, on the whole of the 300 led strip, so not sure I get why this sketch is having a power issue.

We haven't seen your previous sketches. But most likely you had a lower current, because you didn't light up all LEDs at once and/or only at lower brightness. The drawn current depends on how bright you set each LED (to be specific each color of each LED, since one RGB LED is actually 3 LEDs with the colors red, green and blue in one casing). So your current was low enough to not brown out the power from the Arduino.
> 1 votes

---
Tags: led, led-strip
---


# Question
Title: Arduino Nano Doesn't Upload Any Code After Connecting It In Reverse (Rotated 180°)!
I've Made A PCB Which Includes An Arduino Nano. I Soldered Some Female Pin Headers Instead Of Soldering The Arduino Itself, So That I Can Easily Plug/Unplug The Arduino Board.

It Was All Good, ***Until*** I Accidentally Plugged The Arduino Nano Rotated 180°, Which Made Arduino Pin(12) Connected To The Vin(11.1v) At The PCB, And Arduino (Tx) Pin Plugged Into Pin(13)'s Place At PCB, And So On ...

The PCB's Power Was On (11.1v @ VIN Place At The PCB).

Now,

* When I Power The Arduino Board It Looks Normal, 5v Pin And Vin Pin Works Good, No Power Issues, But The Arduino IDE doesn't Upload Any Sketches To It, It Gives Me This Error:

```
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 1 of 10: not in sync: resp=0x00

```
* I Tried Burning Bootloader With The IDE It Gave Me This:

```
avrdude: error: program enable: target doesn't answer. 1
avrdude: initialization failed, rc=-1
         Double check connections and try again, or use -F to override
         this check.

Error while burning bootloader.

```
* I Tried To Upload Code With The IDE But Used USBsp Programmer, It Gave Me This:

```
avrdude: error: program enable: target doesn't answer. 1
avrdude: initialization failed, rc=-1
         Double check connections and try again, or use -F to override
         this check.

the selected serial port
 does not exist or your board is not connected

```
* I Tried To Program The Board Using USBasp Programmer -with ICSP pins- and avrdude, It Gave Me This:

```
avrdude: error: program enable: target doesn't answer. 1
avrdude: initialization failed, rc=-1
         Double check connections and try again, or use -F to override
         this check.

```
* I Also Tried To Upload Code, Or Burn Bootloader Using Another Arduino, But Didn't Work!
* But When I Connect It To The Computer Using The Usb Cable, The IDE Detects It, And It Allows Me To Open The Serial Monitor!

***So, What's The Problem? Is It Completely Broken, Or It Can Be Repaired??***

I Suppose That The Atmega Is Burnt, As 11.1v Was On Pin(12), And Pin(11) Was Connected To Ground!!

# Answer
Apparently your Nano is dead.

Depending on the specific device and your skills, you can try to replace the AVR on it. Please be aware that you need to flash the bootloader on it.
> 0 votes

---
Tags: arduino-nano, power, bootloader, electronics, pcb-design
---


# Question
Title: How do I put a LiquidCrystal_I2C class in a Lcd class?
I want to make my main code cleaner so I was thinking of making a Lcd class which I can use every time I need to print on lcd. So my main code every time I try to print text I need to call :

```
lcd.clear();
lcd.setCursor(1,0);
lcd.print("Text 1st line");
lcd.setCursor(1,0);
lcd.print("Text 2nd line");

```

The problem is I need to create a class called Lcd which initialises the LCD display through LiquidCrystal\_I2C.h and calls it's functions in order to print as I want. Below I will post some code which is totally wrong but I guess it can give you the idea of what I am trying to do:

**LcdControl.hpp**

```
class LcdControl{
    public:
        LcdControl();
        void printOnLcd(int data,int column,int line);
        void printOnLcd(char data,int column,int line);
};

```

**LcdControl.cpp**

```
#include <LiquidCrystal_I2C.h>
#include <Arduino.h>
#include "LcdControl.hpp"

LcdControl::LcdControl(){
    LiquidCrystal_I2C lcd(0x27,20,4);
    lcd.init();
    lcd.init();
    lcd.backlight();
}

void LcdControl::printOnLcd(int data,int column,int line){
    lcd.clear();
    lcd.setCursor(column,line);
    lcd.print(data);
}

void LcdControl::printOnLcd(char data,int column,int line){
    lcd.clear();
    lcd.setCursor(column,line);
    lcd.print(data);
}

```

# Answer
You could also use an inheritance model where the the base class is the original library LiquidCrystal\_I2C and you simply create a new derived class, in this case LcdControl. In LcdControl, you simply pack in your additional methods. The only slight complexity is that you have to invoke the constructor of the base class LiquidCrystal\_I2C when the constructor of the derived class LcdControl is called.

Here it is in a simulation: https://wokwi.com/projects/349238619253244498

Code:

```
#include <LiquidCrystal_I2C.h>

class LcdControl : public LiquidCrystal_I2C {
  public:

    LcdControl( uint8_t lcd_Addr, uint8_t lcd_cols, uint8_t lcd_rows) :
      // base class constructor
      LiquidCrystal_I2C ( lcd_Addr, lcd_cols, lcd_rows ) {
    }

    void printOnLcd(const char * data, int column, int line) {
      LcdControl::clear();
      LcdControl::setCursor(column, line);
      LcdControl::print(data);
    }

} ;

LcdControl lcd(0x27, 20, 4);

void setup() {

  Wire.begin() ;
  lcd.init() ;
  lcd.backlight();

  lcd.printOnLcd( "hello world2", 0 , 0 ) ;
  delay(1000) ;

  lcd.printOnLcd( "hello world3", 1 , 2 ) ;

}

void loop() {

}

```
> 1 votes

# Answer
Potentially, your `lcd` local of the constructor becomes member instead:

```
class LcdControl{
    public:
        LcdControl();
    // ...
    private:
        LiquidCrystal_I2C lcd;

```

There it is accessible from all of your member functions and (without splitting hairs) exists for the lifetime of `LcdControl` variable. The way you have it currently the `lcd` instance is local to the constructor, so inaccessible elsewhere (e.g. inside `printOnLcd()`) and dies when the constructor returns.

The construction of the `lcd` member happens in the `LcdControl()` member initializer list:

```
LcdControl::LcdControl()
    : lcd(0x27,20,4)
{

```

Newer standards of C++ allow some forms of initialization to be done where it's declared as member. I'm not going to recheck the standards now. But the above way should work regardless of which Arduino core and version you have.

The call to the lcd's `init()` may need to be done in an counterpart `init()`/`begin()` in your own class. When you do something that can fail in the constructor you have little opportunity to detect/handle this when done in the constructor on an embedded device like an Arduino where your class may be to make a global and where exceptions aren't supported; some Arduino's support exceptions and some don't. For an Arduino fallible part of initialization/contruction of often separated out so you can control how and where/when that failure happen, often in `setup()` and without reliance on exceptions.

There are a lot of ways to achieve something similar. The above seems closest to what you're attempting in the question. It may not necessarily make the most sense in your particular usage. You can want to have the class have a member pointer or member reference instead of a member instance, but you need to be more careful about their respective lifetimes. It is often a mistake to do initialization in inner layers of your code without providing the user of it any control. E.g. not allowing the user of your `LcdControl` class to initialize it's own `LiquidCrystal_I2C` instance and pass that in or to allow passing in the parameters for the `LcdControl` class to use.
> 1 votes

---
Tags: arduino-uno
---


# Question
Title: Fubarino (microchip pic32mx), Second timer interrupt is not firing
```
volatile uint32_t counter_timer = 0;
void __USER_ISR myISR() {
  counter_timer++;
  clearIntFlag(_TIMER_3_IRQ);
}

void __USER_ISR myISR_timer_four() {
  clearIntFlag(_TIMER_4_IRQ);
  TMR4 = 0x16E3600;
  Serial.print("hi\n");
    if(PORTAbits.RA10 != 1){
      LATAbits.LATA10 = 1;
    }
    else{
      LATAbits.LATA10 = 0;
    }
}

void setup{

  T3CONbits.TCS = 0b0; // Timer Clock Source Select bit
  T3CONbits.TCKPS = 0b000; //0b111; // Timer Input Clock Prescale Select bits
  T3CONbits.ON = 0b1; //0;//0b1;
  asm("nop \n");

  T4CONbits.TCS = 0b0;
  T4CONbits.TCKPS = 0b000;
  T4CONbits.T32 = 0b1;
  TMR4 = 0x16E3600; // half of 48mHz.
  T4CONbits.ON = 0b1;

  setIntVector(_TIMER_3_VECTOR, myISR);
  setIntPriority(_TIMER_3_VECTOR, 4, 0);
  clearIntFlag(_TIMER_3_IRQ);
  setIntEnable(_TIMER_3_IRQ);

  setIntVector(_TIMER_4_VECTOR, myISR_timer_four);
  setIntPriority(_TIMER_4_VECTOR, 1, 0);
  clearIntFlag(_TIMER_4_IRQ);
  setIntEnable(_TIMER_4_IRQ);

 TRISAbits.TRISA10 = 0;  // Fubarino onboard yellow led
}

void loop() {
delay(500);
Serial.println(counter_timer);
Serial.println(TMR4, DEC);
}

```

Hi,

i wanna use multiple interrupts, i got the information from a document i got from: Majenko Technologies. the interrupt bound to Timer3 works, this was the example code in the pdf. now i "assembled" a second interrupt bound to timer4, copy, paste and adapt, but that isn't working.

i can print the "content" of the timer4 register and it's running.

have i done something wrong? search engine didn't yield a answer.

# Answer
The problem was that you need to combine the even and the next odd timer (see datasheet of the microchip pic you're using) to form a 32 bit timer.
> 0 votes

---
Tags: interrupt
---


title: Fading out a led with reed switch loop

text:
# Question
Title: Fading out a led with reed switch loop
I was hoping to get some help on the fading led which I am working on.

For my project I need to have a led, which when it is placed next to a magnet, continuously shines, but as soon as it is taken away it has to fade out in a certain amount of time. So far I managed to write the code which detects when the light is taken away from the magnet and fades out, but when the magnet is nearby again, the led lights up and keeps shining, no matter if I take it away from the magnet or not. So how I could solve this? I tried to exit the loop function, but then this process happens only once, which is not what I want. I am also using reed switch to detect the magnet, but if you have other sensor suggestions, let me know. I'm including the code down here.

Thank you for your help in advance:)

```
int ledPin = 9;
int brightness = 255;
int fadeAmount = 5;
const int reedPin = 2;

void setup() {
  Serial.begin(9600);
  pinMode(ledPin, OUTPUT);
  pinMode(reedPin, INPUT_PULLUP);
}

void loop() {
  int proximity = digitalRead(reedPin);
  if (proximity == HIGH) {
    Serial.println("Switch opened");
    while (brightness >= 0) {
      analogWrite(ledPin, brightness);
      brightness = brightness - fadeAmount;
      delay(30);
      Serial.println(brightness);
    }
  }
  else {
    Serial.println("Switch closed");
    analogWrite(ledPin, brightness);
    Serial.println(brightness);
  }
}

```

# Answer
> 0 votes
Your current problem probably comes from the fact, that you execute the fading loop, even if `brightness` is already zero, and that you don't reset it to zero after fading.

```
while(brightness >= 0){
   ...
   brightness = brightness - fadeAmount;
   ...
}

```

Imagine we are at the point, where `brightness` is 5. The while condition is true, since 5 \> 0. Then we execute the code in the loop, setting `brightness` to 0. We again check the while condition. It is still true, since `0>=0`. So after executing the code in the loop again, `brightness` is now -5. But `analogWrite()` only takes a 1 byte unsigned (!) integer, aka `uint8_t`, while `int` is a 2 byte signed (!) integer. So only the lower byte of that integer will be used and interpreted as unsigned. So -5 gets interpreted as 251, which you see as lighting up in full brightness.

Easy fix would be to set `brightness` to zero after the while loop:

```
brightness = 0;

```

---

That said, I would suggest a completely different route, which will make your code way more responsive, by using the non-blocking coding principle from the `BlinkWithoutDelay` example, that comes with the Arduino IDE.

As you did, I would use a global `brightness` and `fadeAmount` variable, but also one to hold a timestamp:

```
unsigned long timestamp=0;

```

Then in `loop()` we can first do the fading to zero by using the `millis()` function as a clock:

```
if(millis()-timestamp > 30){
    brightness = brightness - fadeAmount;
    if(brightness < 0) brightness = 0;
    timestamp = millis();
}

```

That will decrement the `brightness` variable to zero without blocking with a `delay()`. The speed can be changed by changing the number `30` to something different. This number has the unit milliseconds.

Then we can check for the reed switch and set `brightness` to 255, if it is activated:

```
if(!digitalRead(reedPin)){
    // reedPin is LOW
    brightness = 255;
}

```

So as long as the magnet is at the reed switch, this code will set `brightness` to 255.

And finally we need to write the value of `brightness` to the output pin:

```
analogWrite(ledPin, brightness);

```

So as a full code:

```
int ledPin = 9;
int reedPin = 2;

int brightness = 0;
int fadeAmount = 5;
unsigned long timestamp = 0;

void setup(){
    pinMode(ledPin, OUTPUT);
    pinMode(reedPin, INPUT_PULLUP);
}

void loop(){
    if(millis()-timestamp > 30){
        brightness = brightness - fadeAmount;
        if(brightness < 0) brightness = 0;
        timestamp = millis();
    }

    if(!digitalRead(reedPin)){
        // reedPin is LOW
        brightness = 255;
    }

    analogWrite(ledPin, brightness);
}

```

I've tested this with a normal button (currently no reed switch here). It should work as expected.

---
Tags: arduino-uno, sensors, led
---