# Question
Title: TX Pin Stays Lit After Removing Voltage Regulator
To save power, I removed the linear regulator from my Arduino Nano clone and powered it via the 5V pin from a regulated source (a rechargeable USB phone charger). However, I've noticed that removing the linear regulator causes the TX pin to stay on all the time, which results in my phone not being able to communicate with the HC05 bluetooth module although it connects fine. I checked that the TX pin is not caused by `Serial.print` and noticed the same behavior on all the Nano's I've removed linear regulators from. The Nano's I've tested with the linear regulator work fine, though they use more power than I'd like. I've tried resetting the device, but the problem persists.

I'm wondering what's causing this? Isn't powering via 5V pin suppose to bypass the regulator? So what could cause the missing regulator to affect the TX pin? Unfortunately, I'm not experienced enough to connect the dots using the schematic so I was hoping someone could help me.

Though I'm not sure if it'll help, I'ved included my sketch below. Basically, I'm making using a ultrasonic sensor to communicate distance with my phone via bluetooth. It also plays music when it detects movement (using PIR sensor). Since the application is outdoor use I'm powering via battery and trying to minimize energy use. I got it down to ~4 mA by removing linear regulator.

```
#include <avr/sleep.h>

#define bluetoothIntPin 2
#define pirInterruptPin 3
volatile int state = 0;

int bt_pin = 9;
int pirPin = 8;
int stateData = 0;
int ultraPin = 10;
int trigPin = 11;    // Trigger
int echoPin = 12;    // Echo
int piezoPin = 5;
long duration, cm;
unsigned char inches;
unsigned long timer;
volatile bool signalReceived = false;
volatile bool pirSignalReceived = false;
bool toggle_pir = false;
int incomingByte = 0;
bool song_in_progress = false;
int song_type = 69;

int nokia_melody[] = {

  // Nokia Ringtone
  // Score available at https://musescore.com/user/29944637/scores/5266155

  NOTE_E5, 8, NOTE_D5, 8, NOTE_FS4, 4, NOTE_GS4, 4,
  NOTE_CS5, 8, NOTE_B4, 8, NOTE_D4, 4, NOTE_E4, 4,
  NOTE_B4, 8, NOTE_A4, 8, NOTE_CS4, 4, NOTE_E4, 4,
  NOTE_A4, 2,
};

void setup() {
  pinMode(13, OUTPUT); //set pin 13 as output
  pinMode(ultraPin, OUTPUT);
  pinMode(trigPin, OUTPUT);
  pinMode(pirPin, OUTPUT);
  pinMode(echoPin, INPUT);
  pinMode(LED_BUILTIN, OUTPUT);
  digitalWrite(bt_pin, HIGH);
  digitalWrite(bluetoothIntPin, HIGH);
  digitalWrite(pirInterruptPin, HIGH);
  digitalWrite(ultraPin, LOW);
  digitalWrite(pirPin, LOW);
  Serial.begin(9600); // Default communication rate of the Bluetooth module
  attachInterrupt(digitalPinToInterrupt(bluetoothIntPin), bluetooth_interrupt, CHANGE);
  attachInterrupt(digitalPinToInterrupt(pirInterruptPin), pir_interrupt, CHANGE);
  set_sleep_mode(SLEEP_MODE_PWR_DOWN);
  sleep_enable();
  sleep_cpu();
}

void pir_interrupt(){
  // play sound effect
  digitalWrite(LED_BUILTIN, HIGH);
  delay(5000);
  digitalWrite(LED_BUILTIN, LOW);
  pirSignalReceived = true;
}

void bluetooth_interrupt(){
  state = !state;
  signalReceived = true;
}

void play_song(int melody[], int notes){
      // sizeof gives the number of bytes, each int value is composed of two bytes (16 bits)
    // there are two values per note (pitch and duration), so for each note there are four bytes

    // this calculates the duration of a whole note in ms
    song_in_progress = true;
    int wholenote = (60000 * 4) / tempo;

    int divider = 0, noteDuration = 0;
    for (int thisNote = 0; thisNote < notes * 2; thisNote = thisNote + 2) {

    // calculates the duration of each note
    divider = melody[thisNote + 1];
    if (divider > 0) {
      // regular note, just proceed
      noteDuration = (wholenote) / divider;
    } else if (divider < 0) {
      // dotted notes are represented with negative durations!!
      noteDuration = (wholenote) / abs(divider);
      noteDuration *= 1.5; // increases the duration in half for dotted notes
    }

    // we only play the note for 90% of the duration, leaving 10% as a pause
    tone(piezoPin, melody[thisNote], noteDuration * 0.9);

    // Wait for the specief duration before playing the next note.
    delay(noteDuration);

    // stop the waveform generation before the next note.
    noTone(piezoPin);
  }
  song_in_progress = false;
}

void play_tone_once(){
  if (!song_in_progress){
     if (song_type==69){
      int notes = sizeof(nokia_melody) / sizeof(nokia_melody[0]) / 2;
      play_song(nokia_melody, notes);
    }
    if (song_type==79){
      int notes = sizeof(starwars_melody) / sizeof(starwars_melody[0]) / 2;
      play_song(starwars_melody, notes);
    }
  }
}

void loop() {
  if (signalReceived){
    sleep_disable();
    Serial.write(50);
    delay(500);
    timer = millis();
    digitalWrite(ultraPin, HIGH);
    digitalWrite(pirPin, HIGH);
    while (true){
        digitalWrite(trigPin, LOW);
        delayMicroseconds(2);
        digitalWrite(trigPin, HIGH);
        delayMicroseconds(10);
        digitalWrite(trigPin, LOW);
        pinMode(echoPin, INPUT);
        duration = pulseIn(echoPin, HIGH);
        cm = (duration / 2) / 29.1;   // Divide by 29.1 or multiply by 0.0343
        inches = (duration / 2) / 74; // Divide by 74 or multiply by 0.0135
        Serial.write(inches);
        delay(50);
        incomingByte = Serial.read();
        if (pirSignalReceived){
          play_tone_once();
          pirSignalReceived = false;
        }
        else if (incomingByte == 69){ // automatic pir
          song_type = 69; //nokia
        }
        else if (incomingByte == 79){
          song_type = 79; // starwars
        }
        else if (incomingByte == 89){
          toggle_pir = !toggle_pir;
          if (toggle_pir){
            digitalWrite(pirPin, HIGH); // automate tone
          } else {
            digitalWrite(pirPin, LOW);
          }
        }
        else if (incomingByte == 99){
          digitalWrite(pirPin, LOW);
          play_tone_once();
        }
        if (incomingByte != 49 && incomingByte!=69 && incomingByte != 79 && incomingByte != 89 && incomingByte != 99){
          // receipt from android
          unsigned long timeElapse = millis() - timer;
          if (timeElapse > 7000) {
            break; // exit and SLEEP
          }
        }
        else {
            // reset the timer
            timer = millis();
          }
  }
  digitalWrite(pirPin, LOW);
  digitalWrite(ultraPin, LOW);
  digitalWrite(LED_BUILTIN, LOW);
  signalReceived = false;
  sleep_enable();
  sleep_cpu();
  }
}

```

# Answer
> 1 votes
My Nano clone appears to be the same make as yours. Certainly the underside of it looks identical. On my clone, and I believe yours, the TX LED is wired as follows

```
5V -- RESISTOR -- LED -- TXD/D1

```

The 5V node is just the 5V pin which is fed by USB bus voltage via a diode or by the output of the AMS1117 voltage regulator. The TTL level serial TX signal idles high and sinks current through the LED when transmitting the start bit and low data bits. Incidentally, the RX led is wired in the same manner. By contrast the official Nano uses an FTDI that has dedicated LED driving pins.

It seems likely that you have bridged something with the solder that was holding the AMS1117 on the board in the process of removing it. I would note that the regulator is mounted directly under the LEDs and their current limiting resistors and there are at least three vias in that part of the board.

---
Tags: arduino-nano, battery
---


# Question
Title: How to program Arduino manually via STK500?
I am trying to program an Arduino Nano (with an ATmega328P) from an ESP32 that is attached to its UART and the reset pin. I have to do this via the ESP, because the Arduino is supposed to run on its own, detached from a PC (where I could use an existing programmer for it). But its program should be changable, hence, it is attached to the ESP, which is accessible from a web server via Wifi, so that the Arduino can be reprogrammed on request. I almost got the whole setup figured out: The server is running, files can be sent to the ESP, and the ESP can talk with the Arduino Bootloader. The only problem is that I cannot get the Arduino to execute new programs.

The whole procedure goes like this: The server communicates with the ESP, sends the HEX file of the Arduino sketch (which is successfully verified by a checksum, so this part is working properly). Then, the ESP pulls the reset pin of the Arduino and waits for a while before it attempts to talk to its bootloader. Then, it basically does the same sequence of STK500 commands as avrdude.

I really just copied the commands from the avrdude log after executing

```
avrdude -c arduino -vvvvv -p m328p -b 57600 -P /dev/ttyUSB0 -U flash:w:sketch.hex:i

```

and skipping query commands like which firmware version it uses etc. So, basically: enter programming mode, erase chip, re-enter programming mode, write the hex file to flash, starting from address 0, moving in steps of 128 bytes (using 1's to pad the last message to the full size of 128 bytes). Then afterwards reading back the file from the Arduino and veryfing that all bytes match (which they do!) and leaving the programming mode (which is the very last thing that happens in the avrdude log). Afterwards, I trigger the reset. I am using exactly the same type of file which I gave to avrdude, and all the responses of the Arduino bootloader exactly match the values from the avrdude log.

But whereas the Arduino just starts executing the sketch after this procedure when using avrdude, in my own implementation it just blinks its LED in a regular interval (when the test sketch should make it blink short, long, short, long etc.). I don't get what's going wrong here. I thought that the blinking might represent an error code, but I couldn't find any documentation about that. I feel like I've searched the whole Internet (including arduino stackexchange), and I even looked at the avrdude source code to check if there's something else done after the last STK500 command, that is not listed in its log. I feel (hope) that I'm very close to having it work and this whole thing just needs like a one-line fix, but I don't know what else to try anymore and would greatly appreciate a second opinion from someone more experienced.

# Answer
> 1 votes
Okay, by comparing the data packets my implementation sends with those from the avrdude log for the same sketch, I finally found the cause of trouble. I was sending the hex file byte-by-byte exactly as it is read from storage. But of course, the metadata needs to be skipped (i.e. the addresses at the beginning of each line, the magic bytes at the end of each line, and the newline). I added this simple fix, and now it works fine.

EDIT: Here is the preprocessing code from my Python3 script:

```
import codecs

program = b''
for line in open('sketch.hex', 'rb'):
    program += codecs.decode(line[9:-4], 'hex')

```

---
Tags: arduino-nano, esp32, avrdude
---


# Question
Title: Assign an interrupt to any pin of the atmega328 microcontroller
I need to record the appearance of a signal from the sensor on the PD0 pin. This is the first time in my life that I want to use an interrupt for this. With your help, I configured the sketch for my pin PD0

```
#include <avr/interrupt.h>

volatile int value = 0;

void setup()
{
  cli();
  PCICR |= 0b00000100;    // turn on port d
  PCMSK2 |= 0b00000001;    // turn on pins PD0 (PCINT16)
  sei();

  Serial.begin(9600);
}

void loop()
{
  Serial.println(value);
}

ISR(PCINT2_vect)// Port D, PCINT16 - PCINT23
{
  value++;
}

```

I need to wait and take a certain action when a high signal comes from the sensor. For example, add one to the constant. I also did not understand when interruptions occur. When the signal changes from bottom to top, when from top to bottom, or no matter how? Can't see if these settings are here? Maybe it is set somehow by default?

# Answer
> 4 votes
Here is a link to a good tutorial on how to enable, respond to, and clear interrupts on the ATMega328P device:

Arduino Pin Change Interrupts

I'll repeat the overall steps here in case this URL disappears in the future:

First, you must enable pin change interrupts:

Note the use of 3 bits in the PCICR register \[0:2\]. These enable pin change interrupts on ports B, C, or D in general. You can choose any combination of these ports or all of the ports as you desire.

Next, you select which pin or pins on the enabled ports that you want to receive interrupts from. You have control here over each individual port bit:

Then you must write an ISR (Interrupt Service Routine) to handle the interrupt once it occurs. You have the option of up to THREE ISRs, one to handle each port or you can have a single ISR to handle any pin change interrupt. The way this works is that when an interrupt happens on an enabled port and pin, the AVR chip calls the ISR that you have configured for that event:

So when an interrupt happens, how do you know which pin(s) caused the ISR? Let's assume you used a single ISR to handle all 3 ports. At this point you know only that an interrupt happened somewhere. That's the purpose of the PCIFR register bits. From the AVR datasheet we see this:

By checking the status of these bits you can now tell which pin or pins caused the interrupt. Note that there CAN BE MORE THAN ONE, so it's up to you to decide the priority of each one and handle them accordingly. Note that you only get ONE chance to read these during any ISR function call since they get cleared when the ISR executes.

One last note. You MUST call the sei(); function to enable any interrupt to the CPU before any interrupt will happen.

In your example, however, you seem to be attempting to generate a pin change interrupt on an output. This is probably NOT what you want. Try simply using the existing LED output pin as an indicator and choose a different pin, setup as INPUT, to be your pin change interrupt source.

---
Tags: avr
---


# Question
Title: Will plugging in a 12v power supply in the wrong polarity to a CNC SHIELD fry my circuit or damage my power supply?
I'm currently in the process of making a DIY pen plotter using an Arduino CNC Shield and GRBL Code. Right now I'm connecting the power supply to the shield. I got a standard 12v supply and I cut off the barrel connector so I can connect the supply directly to the CNC Shield. I can't seem to figure out which wire is negative and which is positive. I don't have a multimeter on me so can't test it but I have attached a picture of the information on the power supply which I think should be able to give someone with more knowledge, insight onto the polarity. I think the left wire is negative but not one hundred percent sure. If I risk a test will this damage my circuits or power supply ? Sorry for such an easy question I just don't want to accidentally fry my circuits as have been working on this for a really long time !! Thank you so much, Arav

# Answer
If you wire the power into that shield wrongly you risk killing things - and with those big electrolytics reverse polarity could get *very* messy indeed.

You need to identify the polarity before you wire it in, and to do that you need something that is sensitive to polarity.

If you don't have a DMM you can do it with a simple resistor and LED in series - an LED will only work if the polarity is right.

Take a normal LED of the 5mm type (they're easier to identify) and look for the flat edge on the flange around the base. That indicates which is the "negative" or cathode of the LED. Alternatively look for which of the legs is the shorter of the two, which is also an indication of which is the cathode.

Connect a resistor to this identified negative leg. You want the resistor to be at least 1kΩ, but no more than 10kΩ. You don't need the LED to be bright...

Connect your wires, one to the LED and the other to the resistor.

If the LED lights up then the wire connected to the LED is positive and the wire connected to the resistor is negative. If it doesn't light up then the wires are reversed. In this case check it by swapping the wires over - the LED should now light up.
> 1 votes

---
Tags: power
---


# Question
Title: i was trying to rebuild my code for my bot but then there are errors coming up i am in the middle of my project so i need quick help
```
#include <AFMotor.h>
#include <NewPing.h>
#include <Servo.h>

#define TRIG_PIN A0
#define ECHO_PIN A1
#define MAX_DISTANCE 200
#define MAX_SPEED 190
#define MAX_SPEED_OFFSET 20

NewPing sonar (TRIG_PIN,ECHO_PIN,MAX_DISTANCE);

AF_DCMotor motor1(1, MOTOR12_1KHZ);
AF_DCMotor motor2(2, MOTOR12_1KHZ);
AF_DCMotor motor3(3, MOTOR34_1KHZ);
AF_DCMotor motor4(4, MOTOR34_1KHZ);

Servo myservo;
boolean goesForward=fclose;
int distance = 100;
int speedSet = 0;

void setup() {
  myservo.attach(10);
  myservo.write(115);
  delay(2000);
  distance = readPing();
  delay(100);
  distance = readPing();
  delay(100);
  distance = readPing();
  delay(100);
  distance = readPing();
  delay(100);
}

void loop() {
  int distanceR = 0;
  int distanceL = 0;
  delay (40);

  if (distance <= 15); {
    moveStop();
    delay(100);
    moveForward();
    delay(300);
    moveStop();
    delay(200);
    distanceR = lookRight();
    delay(200);
    distanceL = lookLeft();
    delay(200);

    if (distanceR>=distanceL) {
      turnRight();
      moveStop();
    } else {
      turnLeft();
      moveStop();
    }}else {
      moveForward();
    }
      distance=readPing();
  }

  int lookRight() {
    myservo.write(170);
    delay(500);
    int distance=readPing();
    delay(100);
    myservo.write(115);
    return distance;
    delay(100);
  }

  int readPing() {
    delay(70);
    int cm = sonar.ping_cm();
    if (cm ==) {
      cm=250;
    }
      return cm;
  }

  void moveStop() {
    motor1.run(RELEASE);
    motor2.run(RELEASE);
    motor3.run(RELEASE);
    motor4.run(RELEASE);
  }

  void moveForward() {
    if (!goesForward) {
      goesFORWARD=true;
      motor1.run(FORWARD);
      motor2.run(FORWARD);
      motor3.run(FORWARD);
      motor4.run(FORWARD);
      for (speedSet=0; speedSet<MAX_SPEED;speedSet+=2) {
        motor1.setSpeed(speed.Set};
        motor2.setSpeed(speed.Set};
        motor3.setSpeed(speed.Set};
        motor4.setSpeed(speed.Set};
        delay(5);
      }
    }
  }

  void moveBackward() {
    goesFORWARD=false;
    motor1.run(BACKWARD);
    motor2.run(BACKWARD);
    motor3.run(BACKWARD);
    motor4.run(BACKWARD);
    for (speedSet=0; speedSet<MAX_SPEED;speedSet+=2) {
      motor1.setSpeed(speed.Set};
      motor2.setSpeed(speed.Set};
      motor3.setSpeed(speed.Set};
      motor4.setSpeed(speed.Set};
      delay(5);
    }
  }

  void moveRight() {
    motor1.run(FORWARD);
    motor2.run(FORWARD);
    motor3.run(BACKWARD);
    motor4.run(BACKWARD);
    delay (500);
    motor1.run(FORWARD);
    motor2.run(FORWARD);
    motor3.run(FORWARD);
    motor4.run(FORWARD);
  }

  void moveRight() {
    motor1.run(BACKWARD);
    motor2.run(BACKWARD);
    motor3.run(FORWARD);
    motor4.run(FORWARD);
    delay (500);
    motor1.run(FORWARD);
    motor2.run(FORWARD);
    motor3.run(FORWARD);
    motor4.run(FORWARD);
  }

```

this is the error code

```
Arduino: 1.8.13 (Windows Store 1.8.42.0) (Windows 10), Board: "Arduino Uno"
C:\Users\amish\Documents\Arduino\sketch_nov27b\sketch_nov27b.ino: In function 'void loop()':

sketch_nov27b:53:13: error: 'lookLeft' was not declared in this scope
 distanceL = lookLeft();
             ^~~~~~~~

C:\Users\amish\Documents\Arduino\sketch_nov27b\sketch_nov27b.ino:53:13: note: suggested alternative: 'lookRight'

 distanceL = lookLeft();
             ^~~~~~~~
              lookRight

sketch_nov27b:58:1: error: 'turnRight' was not declared in this scope
 turnRight();
 ^~~~~~~~~

C:\Users\amish\Documents\Arduino\sketch_nov27b\sketch_nov27b.ino:58:1: note: suggested alternative: 'lookRight'

 turnRight();
 ^~~~~~~~~
 lookRight

sketch_nov27b:62:1: error: 'turnLeft' was not declared in this scope
 turnLeft();
 ^~~~~~~~

Sketch_nov27b:65:4: error: 'else' without a previous 'if'

   }else

    ^~~~

C:\Users\amish\Documents\Arduino\sketch_nov27b\sketch_nov27b.ino: In function 'int readPing()':

sketch_nov27b:86:10: error: expected primary-expression before ')' token

   if(cm==)

          ^

C:\Users\amish\Documents\Arduino\sketch_nov27b\sketch_nov27b.ino: In function 'void moveForward()':

sketch_nov27b:104:1: error: 'goesFORWARD' was not declared in this scope

 goesFORWARD=true;

 ^~~~~~~~~~~

C:\Users\amish\Documents\Arduino\sketch_nov27b\sketch_nov27b.ino:104:1: note: suggested alternative: 'FORWARD'

 goesFORWARD=true;

 ^~~~~~~~~~~

 FORWARD

sketch_nov27b:111:17: error: 'speed' was not declared in this scope

 motor1.setSpeed(speed.Set};

                 ^~~~~

C:\Users\amish\Documents\Arduino\sketch_nov27b\sketch_nov27b.ino:111:17: note: suggested alternative: 'speedSet'

 motor1.setSpeed(speed.Set};

                 ^~~~~

                 speedSet

sketch_nov27b:112:17: error: 'speed' was not declared in this scope

 motor2.setSpeed(speed.Set};

                 ^~~~~

C:\Users\amish\Documents\Arduino\sketch_nov27b\sketch_nov27b.ino:112:17: note: suggested alternative: 'speedSet'

 motor2.setSpeed(speed.Set};

                 ^~~~~

                 speedSet

sketch_nov27b:113:17: error: 'speed' was not declared in this scope

 motor3.setSpeed(speed.Set};

                 ^~~~~

C:\Users\amish\Documents\Arduino\sketch_nov27b\sketch_nov27b.ino:113:17: note: suggested alternative: 'speedSet'

 motor3.setSpeed(speed.Set};

                 ^~~~~

                 speedSet

C:\Users\amish\Documents\Arduino\sketch_nov27b\sketch_nov27b.ino: At global scope:

sketch_nov27b:114:1: error: 'motor4' does not name a type

 motor4.setSpeed(speed.Set};

 ^~~~~~

sketch_nov27b:114:26: error: expected declaration before '}' token

 motor4.setSpeed(speed.Set};

                          ^

Multiple libraries were found for "Servo.h"

 Used: C:\Users\amish\Documents\Arduino\libraries\Servo

 Not used: C:\Program Files\WindowsApps\ArduinoLLC.ArduinoIDE_1.8.42.0_x86__mdqgnx93n4wtt\libraries\Servo

exit status 1

'lookLeft' was not declared in this scope

This report would have more information with
"Show verbose output during compilation"
option enabled in File -> Preferences.

```

# Answer
Your code is riddled with typographical and basic syntax errors. Such things as using brackets instead of parentheses, semicolons after an `if` meaning it will do nothing, etc.

Sort out your basic syntax errors (hint: autoformat can help you with the indenting to highlight your problems) and you will see where you have gone wrong.

For instance, after autoformatting your code with `astyle` the `moveForward()` function has turned into this mess:

```
 99     if (!goesForward) {
100         goesFORWARD = true;
101         motor1.run(FORWARD);
102         motor2.run(FORWARD);
103         motor3.run(FORWARD);
104         motor4.run(FORWARD);
105
106         for (speedSet = 0; speedSet < MAX_SPEED; speedSet += 2) {
107             motor1.setSpeed(speed.Set
108         };
109
110         motor2.setSpeed(speed.Set
111     };
112
113     motor3.setSpeed(speed.Set
114 };
115 motor4.setSpeed(speed.Set
116 };
117 delay(5);
118 }
119 }
120 }

```

Also, you have no `lookLeft` function - instead you have two `lookRight` functions. You really should *read* what you've written.
> 3 votes

---
Tags: arduino-uno, c++
---


title: Port manipulation

text:
# Question
Title: Port manipulation
My UNO having some stability issues because of heavy memory use, I'm now optimizing the code now looking to reduce the digital read memory use with the help of port manipulation. I got the code for 'digitial write' but no idea for the digital read pinMode(powerStatus, INPUT);digitalRead(powerStatus) Thanks

# Answer
To read a pin you simply read the port the pin is part of then mask out which pin within that port you want to read.

For example to read pin D11 you need to read bit 3 of port B.

```
if (PINB & (1 << 3)) {
    // HIGH
} else {
    // LOW
}

```

However this doesn't address the underlying problems you're having with your sketch. Saving on flash memory by optimizing your code will not fix instabilities (if anything it will introduce new instabilities from new untested code).

Instabilities related to memory are due to a lack of (or fragmentation of) SRAM not flash. Optimizing code like this will save flash, but won't directly affect your SRAM usage at all.

Instead you need to optimize your SRAM usage by:

* Make sure all string literals are kept in PROGMEM by using the `F()` macro where appropriate
* Avoid use of `String` and instead stick to `char *` with pre-allocated buffers.
* Don't use `new` and `delete` or `malloc` and `free` as this will fragment your heap and cause instability (this is the underlying problem with `String`).
> 2 votes

---
Tags: arduino-uno, code-optimization, port-mapping
---


title: share enum between python and arduino

text:
# Question
Title: share enum between python and arduino
I have created a gui in python that allows an arduino controlled mecanum wheel cart to move around.

The cart allows for 8 different move directions and can rotate left and right. Commands are sent over a serial connection between the laptop(w10, python) and the arduino.

I have an Enum class in python representing the different move directions.

I have a corresponding enum in the arduino to interprete the commands from the python task.

What is an easy way to share a single common enum definition for both coding environments?

# Answer
> 3 votes
One approach that I have used for similar purposes is to generate the appropriate header files (or module or whatever) from a simple text file for all the required uses.

Since you already know python this should be pretty easy. Quick "proof of concept" follows. (Warning: I barely know any python.)

One downside to this is that you have to remember to regenerate the header/module each time you update the enum (keys or values) - don't forget to recompile for the C++ part. If you have a build system, it is best to integrate that code generation step into it.

A variation of this is to parse one of the language's source code to extract the definition and output it in a format suitable for the other. That is generally much harder to do though if you want to make it robust.

---

### robot.enum

```
UP    1
DOWN  2
LEFT  3
RIGHT 4
JUMP  5

```

### enum\_generator.py

```
def python_enum(filename):
    with open(filename, 'w') as w:
        w.write('class Robot(Enum):\n')
        with open('robot.enum') as r:
            for line in r:
                parts = line.split()
                w.write(f'    {parts[0]} = {parts[1]}\n')

def cplusplus_enum(filename):
    with open(filename, 'w') as w:
        w.write('#pragma once\n')
        w.write('enum Robot: int {\n')
        with open('robot.enum') as f:
            for line in f:
                parts = line.split()
                w.write(f'  {parts[0]} = {parts[1]},\n')
        w.write('};');

python_enum('robot_enum.py')
cplusplus_enum('robot_enum.h')

```

---
Tags: python
---


# Question
Title: L298N Dual Motor Controller Enable Pin has power but motors not working
I am trying to get the L298N to work with a simple DC motor.

For now, I have simplified the setup and the code to the basics to try to get it to work. I am using the following wiring setup with no button or pot:

Only 1 motor, I am using a 2S lipo which I measured the voltage to be 7.8V which should be enough. The DC motor works when directly powered from the battery and when power with ~5V from an Arduino so I know it is not the issue.

My code, simplified from this tutorial: https://howtomechatronics.com/tutorials/arduino/arduino-dc-motor-control-tutorial-l298n-pwm-h-bridge/

```
#define enA 9
#define in1 6
#define in2 7

void setup() {
  pinMode(enA, OUTPUT);
  pinMode(in1, OUTPUT);
  pinMode(in2, OUTPUT);
  // Set initial rotation direction
  digitalWrite(in1, LOW);
  digitalWrite(in2, HIGH);
}
void loop() {
  analogWrite(enA, 255); // Send PWM signal to L298N Enable pin
}

```

I can measure the voltage at the input, it is good 7.8V. No voltage on motor output pins. In1 has voltage of 3.0V and In2 has 0V which corresponds to the code. However, Enable1 has 0V which doesn't make sense. So I attached the jumper for Enable 1 to give it the 5V, measured to confirm and still the motor is not working. I also tried a 2nd L298N with the exact same setup it and does not work. So I suspect it is something in my code or setup.

I feel like I am doing something stupid but I do not know what else to check. I checked continuity on the back of the board and it seems okay.

# Answer
Give have to apply 5V to the 5V pin. The L298N's needs power supply for its logic circuitry, so you have: \- voltage for the motor \- voltage for the L298N \- signal lines
> 0 votes

# Answer
I found this thread for a similar problem, I realized that my scratch (taken from here) wasn't able to works.. After many and many tries, I found that: the scratch works only using Serial Plotter, and not using Serial monitor.

In my case it was not necessary to connect 5vout of L298N with arduino, (clearly you need to connect ground to battery supply and to arduino ground too).

I don't know why the scratch works properly (make motors turn) only by Serial Plotter and it doesn't work by Serial monitor. I really would like to understand it!! (if someone could explain this oddity I would be very grateful).

Hope this could help.

**UPDATE:** I found why it doesn't work on Serial monitor.. In the serial monitor, by using:

```
int inByte = Serial.read();

```

you must select "no line ending".

:)

it's always human error!

**NOTE**: the 5V pin let to power Raspberry and this is it use. I don't know if that solution should be risky.. In the Datasheet it's said:

> A non-inductive 100nF capacitor must be connected between this pin and ground

I searched about this solution on Raspberry but, after many readings, I just don't know if this could be a safe solution to power it. I can't suggest it as a secure way.
> 2 votes

---
Tags: arduino-uno, motor, l298n, h-bridge
---


# Question
Title: Are the GND pins of an Arduino identical to GND of its power supply?
What would happen if I connected a fan as shown in the following picture:

* +12V is supplied by the power supply that also powers the Arduino.
* GND, however, is connected to a GND pin of the Arduino instead of the power supply.

I guess that would not work? Or are GND from the Arduino and GND from the power supply identical in this case?

---

If you read the accepted answer, please also note the comments below. The power consumption of the consumer (fan) is important.

# Answer
> 2 votes
"Ground" is just a lump of metal and each ground "pin" is connected to it. That includes the ground connection in the barrel jack. It's all one thing.

Wherever you connect your fan's ground to it's all ground. That is, as long as all grounds external to the Arduino are connected, ultimately, to the Arudino.

---
Tags: power, electronics
---


# Question
Title: Serial communication between nodemcu and Arduino Uno
For the last days, I am trying to establish serial communication between nodemcu and Arduino Uno but I failed to do this. Currently, I am working on a Home Automation project. I receive data from nodemcu and send it to Arduino Uno, but some dummy data also receive with original data. Please help.

Nodemcu code:

```
#include <ESP8266WiFi.h>
#include "Adafruit_MQTT.h"
#include "Adafruit_MQTT_Client.h"

#define Automated   D0
#define Led         D1
#define Fan         D2

#define WLAN_SSID       "JioFi2_1EAFF8"
#define WLAN_PASS       "Ode9c@,1S%31ja$1xANkeL"

#define AIO_SERVER      "io.adafruit.com"
#define AIO_SERVERPORT  1883
#define AIO_USERNAME    "_inishu"
#define AIO_KEY        "aio_HZUG00TupkcsC2dvraQM7HLHrCd4"

WiFiClient client;
Adafruit_MQTT_Client mqtt(&client, AIO_SERVER, AIO_SERVERPORT, AIO_USERNAME, AIO_KEY);

Adafruit_MQTT_Subscribe speed = Adafruit_MQTT_Subscribe(&mqtt, AIO_USERNAME"/feeds/Fan");
Adafruit_MQTT_Subscribe inten = Adafruit_MQTT_Subscribe(&mqtt, AIO_USERNAME "/feeds/Led");
Adafruit_MQTT_Subscribe autom = Adafruit_MQTT_Subscribe(&mqtt, AIO_USERNAME "/feeds/Automate");

void MQTT_connect();
void datatransfer(int);

int on_off;
int sliderval1;
int sliderval2;
void setup(){
    Serial.begin(9600);
    pinMode(Automated, OUTPUT);
    pinMode(Led, OUTPUT);
    pinMode(Fan, OUTPUT);

    WiFi.begin(WLAN_SSID, WLAN_PASS);
    while (WiFi.status() != WL_CONNECTED) {
        delay(500);
    }

    mqtt.subscribe(&autom);
    mqtt.subscribe(&speed);
    mqtt.subscribe(&inten);
}

void loop (){
    MQTT_connect();

    Adafruit_MQTT_Subscribe *subscription;
    while ((subscription = mqtt.readSubscription(5000))){
        if (subscription == &autom){
            on_off = atoi((char *)autom.lastread);
            if (on_off == 1)   digitalWrite(Automated,HIGH);
            if (on_off == 0)   digitalWrite(Automated,LOW);
        }

        if (subscription == &speed){
            sliderval1 = atoi((char *)speed.lastread);
            analogWrite(Fan, sliderval1);
        }

        if (subscription == &inten){
            sliderval2 = atoi((char *)inten.lastread);
            analogWrite(Led, sliderval2);
        }
    }
    datatransfer(on_off);
    datatransfer(sliderval1);
    datatransfer(sliderval2);
}

void MQTT_connect() {
    if (mqtt.connected()) {
         return;
    }

    while (mqtt.connect() != 0) {
        mqtt.disconnect();
        delay(2000);
    }
}

void datatransfer(int value){
    Serial.println(value);
    delay(500);
}

```

Arduino Uno code:

```
int x = A0, y = A1, z = 1;
int fan = 11, led = 10;
float temp, lux;
int autom = 1;
int inten = 0;
int speed = 0;
int fanspeed, light;

int datareceive(){
    int receiver = 0;
    while(Serial.available()==0 );
    String s = Serial.readStringUntil('\r');
    receiver = s.toInt();
    Serial.println(receiver);
    delay(1000);
    return receiver;
}

void setup(){
    Serial.begin(9600);
    pinMode(fan,OUTPUT);
    pinMode(led,OUTPUT);
    pinMode(x,INPUT);
    pinMode(y,INPUT);
    pinMode(z,INPUT);
}

void loop(){
    autom = datareceive();
    speed = datareceive();
    inten = datareceive();
    if(autom == 1){
        fanspeed = 255 - speed;
        light = 255 - inten;
        analogWrite(fan,fanspeed);
        analogWrite(led,light);
    }
    else {
        temp = analogRead(x);
        if (temp >= 52 && temp <= 104){
            int fanspeed = -4.90384615*temp + 510;
            analogWrite(fan, fanspeed);
        }
        else if(temp > 104)  digitalWrite(fan,LOW);
        else digitalWrite(fan,HIGH);
        lux = analogRead(y);
        if (lux >= 430 && lux <= 594){
            int light = 1.342657*lux-577.342657;
            analogWrite(led,light);
        }
        else if (lux < 430) digitalWrite(led, LOW);
        else digitalWrite(led,HIGH);
    }
}

```

# Answer
> 1 votes
Arduino UNO is 5v logic and esp8266 is 3.3v logic. You need a level shifter for them to be able to have bidirectional serial link. Alternatively you can just use a voltage divider between Arduino Tx and ESP Rx pin to protect the rx pin of the esp.

---
Tags: arduino-uno, nodemcu, softwareserial, communication, uart
---


title: Uploading a simple sketch takes forever

text:
# Question
Title: Uploading a simple sketch takes forever
I am trying to upload this simple sketch into my arduino with a shield I made. It takes forever (note I have the right COM port on)

```
  int sensorValue = 0;

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

  void loop(){
     sensorValue = analogRead(A4);
     delay(10000000);
     Serial.println(sensorValue);
     delay(10000000);
  }

```

# Answer
> 9 votes
Are you sure the problem is in the upload time? delay() takes the number of milliseconds you want to wait. In your code, it should take about 3 hours before the Arduino sends some data through the serial port.

# Answer
> 4 votes
I had the same problem. I noticed that the RX & TX LEDs we're not flashing as they normally do when I upload a file. I'm using an older knock off nano.

My solution: Under Tools\> processor.... I switched from the defaulted "ATmega328P" to the "ATmega328P(Old Bootloader)" option. The next upload attempt was quick and successful. Normal flashing RX &TX LEDs during the upload as well. Hope this helps someone.

# Answer
> 1 votes
If the problem does indeed lie in the upload (see DoubtBearer's answer), then you should turn on verbose output, to see exactly what part of the upload is giving issues.

In your IDE, click File -\> preferences; look for the section "Show verbose output during:" and tick both Compilation and Upload.

Re-run your upload, and see what is taking up all the time. If you can't figure it out from that, please post the log (it will appear in the black area at the bottom of the IDE, you should be able to cut & paste).

# Answer
> 1 votes
Check the end of this thread for the reply by 'Toshibass', Unbelievable slow compilation of simple sketches

> I was having same same problem compile took \> 3 minutes for small sketch using serial or OTA however I found solution The program that was slowing down compile was IBM's Trusteer .. Rapport which is a fraud prevention program distributed by my bank once I de-installed it, same compile took 10 seconds, now all I need to do is find an alternative or hope IBM produce a fix after I filled in a issue report to them.

It worked for me, the culprit was some software called 'Trusteer'.

# Answer
> 1 votes
If you are taking too much time for uploading means there is communication between another device is happening, please remove all TX and RX pins.

# Answer
> 0 votes
Try downloading CH340 drivers. You must not have drivers for uploading the code to arduino board and to identify the right COM port. Download and install the drivers, find the COM port number from device manager and update Tools-\>Port in your Arduino IDE.

---
Tags: arduino-uno
---


# Question
Title: Arduino with interrupts enters in a locking state
I am quite noobish with using the interrupts on Arduino and I am facing a strange problem. I am using an Arduino Pro Mini, a light sensor and an RTC module(DS3231) which has set 2 alarms, one at sunrise and one at the sunset. Each time the DST triggers the alarm, the interrupt routine (here onAlarm()) blocks the state of Arduino and nothing happens form there. Is there anything wrong with the code I write?

The code bellow is a little bit simplified, I just let the method calls, not the whole declarations of them.

```
#include <avr/sleep.h>//this AVR library contains the methods that controls the sleep modes
#include <avr/power.h>
#include <DS3232RTC.h>  //RTC Library https://github.com/JChristensen/DS3232RTC

#define ldrInterruptPin  2
#define DS2331interruptPin 3

void setup() {

  Serial.begin(9600);//Start Serial Comunication
  Wire.begin();

  //_____________________setup DS3231 interrupts_________
  pinMode(DS2331interruptPin, INPUT_PULLUP);
  digitalWrite(DS2331interruptPin, HIGH);
  attachInterrupt(digitalPinToInterrupt(DS2331interruptPin), onAlarm, FALLING);

  //_____________________setup LD235R interrupts_________
  pinMode(ldrInterruptPin, INPUT);
  digitalWrite(ldrInterruptPin, HIGH);
  attachInterrupt(digitalPinToInterrupt(ldrInterruptPin), irq1, RISING);

  resetDS3231Alarms();

  time_t t = RTC.get();
  setUpAlarms();
}

void loop() {
 //read the light sensor vlaues
}

```

Adn this is the onAlarm function:

```
  void onAlarm() {
  Serial.println("ALARM");
  formatTime(timestamp, RTC.get());
  if (RTC.alarm(ALARM_1))
  {
    Serial << F("SLEEP alarm at ") << timestamp << endl;
    goToSleep();
  }
  else if (RTC.alarm(ALARM_2))
  {
    Serial << F("WakeUP Alarm at ") << timestamp << endl;

    Serial.println("Time to Wake up......!");
    sleep_disable();
    Serial.println("I woke up!!!");
    attachInterrupt(digitalPinToInterrupt(ldrInterruptPin), irq1, RISING);
  }
  //update the sleep and wakeup times based on curreent day
  setUpAlarms();
};

```

resetAlarms()

```
void resetDS3231Alarms() {
  // initialize the alarms to known values, clear the alarm flags, clear the alarm interrupt flags
  RTC.setAlarm(ALM1_MATCH_DATE, 0, 0, 0, 1);
  RTC.setAlarm(ALM2_MATCH_DATE, 0, 0, 0, 1);
  RTC.alarm(ALARM_1);
  RTC.alarm(ALARM_2);
  RTC.alarmInterrupt(ALARM_1, false);
  RTC.alarmInterrupt(ALARM_2, false);
  RTC.squareWave(SQWAVE_NONE);
}

```

Every time an alarm occurs, the code blocks and outputs exactly what is in the serial monitor capture bellow: It just prints "AL" form the Serial.println("ALARM"); and nothing happens from there

Does anyone know what causes this issue and how can it be solved?

# Answer
When the AVR processor goes to sleep, the *only* way it can wake up is by an interrupt. If it goes to sleep with interrupts disabled, then it will never wake up.

Interrupt routines are by default non-interruptible: the first thing the processor does when servicing an interrupt is to disable further interrupts. Your `onAlarm()` function is thus running with interrupts disabled. If it goes to sleep, it will lock the processor.

A quick and dirty fix would be to call `interrupts()` right before going to sleep. I would not recommend that though, as you will end up piling interrupt contexts one over another. The proper fix would be to trim down your interrupt service routines to the bare minimum that must be done immediately, and handle everything else in regular code, within `loop()`. In this particular case, setting a `volatile bool` might well be the only thing you really need to do. Your `loop()` would test that `bool` and take care of everything else.
> 2 votes

---
Tags: interrupt, arduino-pro-mini, rtc, ds3231-alarms
---


# Question
Title: Comparing a String after reading it from Serial fails
I have bought an Arduino starter kit online. Everything seem to work, but when I try for example to use `if`s (and other conditional statements), the LEDs do not turn on. Here is the code for a little project I am currently working on:

```
int redpin = 3;
int greenpin = 2;
int bluepin = 4;
String color;
String msg = "Insert color: ";

void setup() {
  // put your setup code here, to run once:
  pinMode(redpin,OUTPUT);
  pinMode(greenpin,OUTPUT);
  pinMode(bluepin,OUTPUT);
  Serial.begin(9600);
}

void loop() {
  // put your main code here, to run repeatedly:
  Serial.println(msg);
  while (Serial.available() == 0) {}
  color = Serial.readString();

  if (color == "red") {
    digitalWrite(redpin, HIGH);
    digitalWrite(greenpin, LOW);
    digitalWrite(bluepin, LOW);
  }
  if (color == "green") {
    digitalWrite(greenpin, HIGH);
    digitalWrite(redpin, LOW);
    digitalWrite(bluepin, LOW);
  }
  if (color == "blue") {
    digitalWrite(greenpin, LOW);
    digitalWrite(redpin, LOW);
    digitalWrite(bluepin, HIGH);
  }

  if (color == "off") {
    digitalWrite(greenpin, LOW);
    digitalWrite(redpin, LOW);
    digitalWrite(bluepin, LOW);
  }
}

```

I tried turning on the RGB LED with single `digitalWrite()` functions and it works. I think that the `if` statements in the code are the problem.

I\`m using an Arduino Mega 2560 BTW.

# Answer
> 3 votes
After `color = Serial.readString();` `color` also contains a newline character.

You can remove that by adding the line `color.trim();`, or even better, avoid the newline altogether by using `Serial.readStringUntil('\n');` which discards the terminating newline character.

Also, you could, and maybe should, avoid using the `String` class and use:

```
char color[10]; // char array as buffer for reading from Serial

```

```
int number = Serial.readBytesUntil('\n', color, 10); //Read input and length
color[number] = '\0'; //Terminate the string by adding '\0' at its end

```

```
if (strcmp(color, "red") == 0) //Use strcmp(), not ==

```

respectively.

---
Tags: c++, string
---


# Question
Title: Multiplexing a piano keyboard with arduino nano
I'm trying to use a cheap keyboard with 37 keys as a MIDI controller by reading the multiplexed keys with an Arduino nano. The keys are grouped in six groups with a max of 8 keys per group. Which results in my setup of 8 digital INPUTS which are pulled HIGH, and 6 OUTPUTS, which are pulled LOW, when reading that group of keys. This works great when I only have 3 groups in my loop. However whenever I add another group it does not work anymore. It doesn't matter which groups are activated.

One group reading looks like this:

```
digitalWrite(A0, LOW);
for (byte j = 12; j > 4; j--)
{
  uint8_t note = offset + 20 + (12-j);
  uint8_t key_state = digitalRead(j);

  if ( (key_state == 0) && (notes_pressed[note] == 1) )
  {
    notes_pressed[note] = 0;
    Serial.write(note + 100);
  } else if ( (key_state == 1) && (notes_pressed[note] == 0) )
  {
    notes_pressed[note] = 1;
    Serial.write(note);
  }
}
digitalWrite(A0, HIGH);

```

With A0 being the group pin.

I think this has to do with the pins not being able to be pulled low as quickly because of weak output drivers or something similar. Unfortunately I don't have an oscilloscope to check the levels. I have added delays to ensure the levels have settled when the reading occurs but to no avail.

Edit: Schematic is pretty much just this. The diodes in the keyboard I left out, but they are there as necessary:

```
#include "HardwareSerial.h"

#define offset 48

void midi_note_off(byte channel, byte key, byte velocity);
void midi_note_on(byte channel, byte key, byte velocity);
void midi_command(byte command, byte channel, byte param1, byte param2);

byte notes_pressed[37];
void setup() {
  Serial.begin(115200);
  pinMode(12, INPUT_PULLUP);
  pinMode(11, INPUT_PULLUP);
  pinMode(10, INPUT_PULLUP);
  pinMode(9, INPUT_PULLUP);
  pinMode(8, INPUT_PULLUP);
  pinMode(7, INPUT_PULLUP);
  pinMode(6, INPUT_PULLUP);
  pinMode(5, INPUT_PULLUP);
  pinMode(4, OUTPUT);
  pinMode(3, OUTPUT);
  pinMode(2, OUTPUT);
  pinMode(A2, OUTPUT);
  pinMode(A1, OUTPUT);
  pinMode(A0, OUTPUT);

  digitalWrite(4, HIGH);
  digitalWrite(3, HIGH);
  digitalWrite(2, HIGH);
  digitalWrite(A0, HIGH);
  digitalWrite(A1, HIGH);
  digitalWrite(A2, HIGH);
}

void loop() {
  digitalWrite(4, LOW);
  for (byte j = 8; j > 4; j--)
  {
    uint8_t note = offset + (8-j);
    uint8_t key_state = digitalRead(j);

    if ( (key_state == 0) && (notes_pressed[note] == 1) )
    {
      notes_pressed[note] = 0;
      Serial.write(note + 100);
    } else if ( (key_state == 1) && (notes_pressed[note] == 0) )
    {
      notes_pressed[note] = 1;
      Serial.write(note);
    }
  }
  digitalWrite(4, HIGH);

  digitalWrite(3, LOW);
  for (byte j = 12; j > 4; j--)
  {
    uint8_t note = offset + 4 + (12 - j);
    uint8_t key_state = digitalRead(j);

    if ( (key_state == 0) && (notes_pressed[note] == 1) )
    {
      notes_pressed[note] = 0;
      Serial.write(note + 100);
    } else if ( (key_state == 1) && (notes_pressed[note] == 0) )
    {
      notes_pressed[note] = 1;
      Serial.write(note);
    }
  }
  digitalWrite(3, HIGH);

  digitalWrite(2, LOW);
  for (byte j = 12; j > 4; j--)
  {
    uint8_t note = offset + 12 + (12-j);
    uint8_t key_state = digitalRead(j);

    if ( (key_state == 0) && (notes_pressed[note] == 1) )
    {
      notes_pressed[note] = 0;
      Serial.write(note + 100);
    } else if ( (key_state == 1) && (notes_pressed[note] == 0) )
    {
      notes_pressed[note] = 1;
      Serial.write(note);
    }
  }
  digitalWrite(2, HIGH);

  digitalWrite(A0, LOW);
  for (byte j = 12; j > 4; j--)
  {
    uint8_t note = offset + 20 + (12-j);
    uint8_t key_state = digitalRead(j);

    if ( (key_state == 0) && (notes_pressed[note] == 1) )
    {
      notes_pressed[note] = 0;
      Serial.write(note + 100);
    } else if ( (key_state == 1) && (notes_pressed[note] == 0) )
    {
      notes_pressed[note] = 1;
      Serial.write(note);
    }
  }
  digitalWrite(A0, HIGH);

  digitalWrite(A1, LOW);
  for (byte j = 12; j > 4; j--)
  {
    uint8_t note = offset + 28 + (12-j);
    uint8_t key_state = digitalRead(j);

    if ( (key_state == 0) && (notes_pressed[note] == 1) )
    {
      notes_pressed[note] = 0;
      Serial.write(note + 100);
    } else if ( (key_state == 1) && (notes_pressed[note] == 0) )
    {
      notes_pressed[note] = 1;
      Serial.write(note);
    }
  }
  digitalWrite(A1, HIGH);

  digitalWrite(A2, LOW);
  for (byte j = 5; j > 4; j--)
  {
    uint8_t note = offset + 36 + (5-j);
    uint8_t key_state = digitalRead(j);

    if ( (key_state == 0) && (notes_pressed[note] == 1) )
    {
      notes_pressed[note] = 0;
      Serial.write(note + 100);
    } else if ( (key_state == 1) && (notes_pressed[note] == 0) )
    {
      notes_pressed[note] = 1;
      Serial.write(note);
    }
  }
  digitalWrite(A2, HIGH);
}

```

I know the last part looping over a single value is unnessecary but it should still work.

# Answer
> 1 votes
A few excerpts from the program:

```
#define offset 48
//...
byte notes_pressed[37];  // valid indices: 0 – 36
//...
uint8_t note = offset + (8-j);  // j ≤ 8, thus note ≥ 48
//...
notes_pressed[note] = 0;

```

That last line writes past the end of the `notes_pressed` array, and overwrites who knows what in memory. This could be the source of the issue you are facing.

# Answer
> 0 votes
There are several issues to be considered when designing a switch matrix for an embedded processor regardless if it is a musical or computer keyboard:

1. Contact bounce: This is more important for a computer keyboard then a musical keyboard. However if the switch are particularly bad, it may audible. Software may be used to mitigate the problem but will also add delay between the key press and the beginning of the note's sound.
2. Pull Ups: Any logic input should not be left unconnected or floating. This can lead to unexpected results. Use Pull Up resistors (or Pull Down depending on your design) to mitigate this problem. The Arduino Uno's embedded processor (the ATmega328P) comes with built in Pull Up resistors. The Arduino IDE abstracts this feature by including a parameter it the pinMode() function call to invoke this feature.
3. Rollover: In a switch matrix 1 or 2 simultaneous switch closure can be uniquely detected. However, if 3 switch closures connect 2 rows and 2 columns together, they can not be uniquely detected. This is because current can flow through the 3 closed switches activating both rows and both columns nullifying the ability for the embedded processor to scan individual rows or columns. To mitigate this problem a diode is added to all switches in the switch matrix such that there is no current path between rows or columns.

From the Rollover wikipedia page:

> Most music keyboards use isolation diodes in their keyboard matrix to implement full n-key rollover, making them immune to both key ghosting and key jamming

This image if from this stack exchange question:

---
Tags: arduino-nano
---


title: Merging two 2-d arrays in order of axes

text:
# Question
Title: Merging two 2-d arrays in order of axes
Looking to merge two different 2D arrays of different row sizes into one long array:

```
 int 2dArray1[][] = {
   {1, 2, 3},
   {4, 5, 6}};
 int 2dArray2[][] = {
   {10, 20},
   {30, 40}};
 int 1dLongArray[10];

```

This is where I need help in order to have the values of 1dLongarray be arranged as follows:

```
1, 2, 3, 10, 20, 4, 5, 6, 30, 40

```

How would I achieve this? Thanks in advance.

# Answer
> 0 votes
Consider using loops of length specific to the desired number of transactions. For example, using this pseudo code create a sketch which follows this pattern:

```
initialize i to zero
loop 2 times for each row using the variable x
  loop 3 times for each element in first array using the variable y
    long array [i] = first array[x][y]
    increment i
  loop 2 times for each element in a second array using the variable z
    long array [i] = second array[x][z]
    increment i

```

---
Tags: array
---


# Question
Title: Sending minimal data between two Arduinos far away from each other
**Problem:** I need to send small integer numbers (single-digit numbers suffices) between two arduinos located approximately 50-60m away from each other.

The connection must be made through cables. I have read that the mentioned distance is too long for using serial communication. I do not care if the method is not fast, delays up to one or two seconds are ok for this. If it helps: the devices (Arduino UNO or similar) will run not yet written codes for a simple alarm system (with no cameras/images).

---

**Question:** What is a good way to this?

---

**My efforts:** I thought a couple of alternatives to solve this problem. Both involve the use of PWM signals sent from a device *A* to another *B*.

* One of them requires some DAC in *A* and read the analog input in *B*. The values read are then mapped to the small integer lists. I found some disadvantages with this approach:
    + Increment of hardware complexity and cost. Although I have read that the digital to analog conversion can be made with cheap capacitors I would have many problems to acquire them because of the lock-down of my country.
    + Probably I will need to do many test to set up the mapping procedure due to voltage drop.
* The second is just read the *digital* input in *B* many times during a fixed period (e.g. 0.1 or 1 second) and average the values that were read in that period. My bet is that the devices are not synchronized and then the average (times 1023) in such longs periods would be close to the *value* sent by analogWrite(somepin, *value*). Finally, the accepted value would be the closest value in alist of acceptable values. ***Example***: For passing one of the numbers 0,1,2 or 3 the *A* device will output 0, 341, 682 or 1023, respectively. Eg. for passing "1" *A* will do **analogWrite(somepinA, 341)**. *B* will read **int lecture = digitalRead(somepinB)** and get the time average of *lecture* for some time period. After multiplication by 1023 it could return something like "312". Then, it must find the value in \[0, 341, 682,1023\] closest to 280 (341) and map to 1.
    + Even if they were synchronized some way, I think that I could send 0 or 1 using random numbers or digitalWrite(somepinA) (Is it possible? Advantages? Disadvantages?)

---

I'm a novice in this field so I do not known if there is something wrong with my approach. I would also appreciate if a better alternative is proposed.

Thanks in advance.

# Answer
> 3 votes
**RS-485 is best (you can buy some modules for this from Adafruit, Amazon, eBay, etc)**, but you can use the built-in hardware RS-232 serial UARTs from each on pins 0 and 1 so long as the baud rate is really really low. The lower the baud rate, the longer the range can be because lower baud rates reject noise better (and the longer the cable, the worse the noise, since the longer the cable the more it acts like an antenna and an inductor and a capacitor). Here are some rough estimates of how far you can transfer regular-logic-level unbalanced RS-232 signals:

Source:
https://www.tldp.org/HOWTO/Remote-Serial-Console-HOWTO/serial-distance.html

If this trend continues, you should be able to get like 120m at 1200 bps (baud), 240m at 600 bps, 480m at 300 bps, etc. maybe even up to \> 1000m at 50 bps. I don't think the trend will continue like that, and we are using 5V TTL logic (signal voltage) levels here instead of RS-232's +/- 12V or so, so our logic levels are much worse and will have less range, so just use `50` baud and give it a shot:

```
// do on each Arduino
Serial.begin(50); // 50 baud = 10 bytes/sec throughput rate; see below

```

Note that for 8-N-1 serial communication baud rate, which is the default on Arduino, there are **10 bits** per byte sent over the wire. This is because there is "one start bit, the eight data bits, and the one stop bit" for every 8-bit byte sent. That's an effective throughput data rate of 80%. This means a baud rate of 50 bps (bits per second) only can transmit 50/10 = *5 bytes per second*. That's it! That's suuuuuper slow, but if it's fast enough for your application, it's fast enough!

I hypothesize 5V TTL twisted quad RS-232 communication between two Arduinos would have a maximum range at `50` baud of about 1000m/(24V span for regular RS-232 / 5V span for 5V TTL logic RS-232) = **208m**. Just a crude guestimate. Please report back any findings you get from your experiments. I'd like to hear about it.

Assuming that this all *does* work, it would also be useful to start increasing the baud rate on each device until the data starts getting corrupted. Back off on the baud rate a little, and that's your maximum baud rate. Take that maximum baud rate and divide by 2 or 3, and that's your maximum "safe" baud rate perhaps. If you need throughput that is as high as possible, then that's what I'd do. Ex: maybe in your case `50` baud works just fine, so you increase it. At `1000` baud you start seeing corrupted data, so you back off to `800`. At that point you no longer see corrupted data. So, divide that by 2 or 3 and you get a maximum "safe" baud for your setup of perhaps 800/3 = `267` to 800/2 = `400`.

Try using a *twisted quad* cable (wires are twisted together in groups of 4) to reduce noise and increase range, and set the baud rates on each Arduino to like `50`. You will need 3 wires connected between the Arduinos:

1. GND to GND
2. Tx to Rx
3. Rx to Tx

Power them each separately with ungrounded power supplies.

Communicate via `Serial.write()` and `Serial.read()` (so long as `Serial.available()` shows some data is available in the read buffer).

# More on balanced vs unbalanced lines, and why I recommend "twisted quad" wire:

Normally, RS-232 is considered to be an unbalanced line transimission system. This means the impedance in the transmission wire is not equal to the impedance in the return wire, which would be a common ground between the sender and receiver, in conjunction with (in parallel with) an Earth ground through the building wiring and/or actually through the Earth...literally, the dirt you walk on. By powering each Arduino with an *ungrounded* power supply, such as a 2-prong power supply, however, which is common, there is no Earth ground connected to the Arduino. Furthermore, by only having a single transmission line active at any moment between two Arduinos, you have just balanced the transmission between them. Now, the out path is a single Tx signal from one Arduino to the other, and the return path has matching impedance, as it is your single, common GND wire between the two Arduinos. You now have balanced line RS-232 TTL logic level transmission between the two Arduinos. Balanced line transmission can have improved noise rejection and range by using a twisted pair between the two lines. In this case, however, there are 3 lines: Tx --\> Rx, Rx --\> Tx, and Gnd --\> Gnd. So, you should use **twisted quad** wire, which means 4 wires at once are twisted together. Connect all 3 lines to the same twisted quad bundle. Again, remember, this assumes only one Arduino is transmitting at a time on one single wire in one single direction at a time (so as to not negate your return current through the GND line when transmitting on two lines, one in each direction, or double your return current through the GND line when transmitting on two lines each in the same direction \[assuming you had multiple UARTS on each device\]), thereby this usage creates a balanced line system since they also aren't truly grounded through a 3-prong grounded power supply. If these 2 requirements are met (1 Arduino transmits at a time, and at least one of them is not grounded to the building wiring), use twisted quad wire, as the system is balanced line communication. If it is not the case, because you are transmitting from each Arduino to the other at exactly the same time, or because *both* (not one) Arduinos are grounded to the building, thereby offering an alternative return path through the building ground wiring, then twisted quad cable will not benefit you, and you should use regular untwisted wiring.

Having said all that, experimentation is the real boss here. Try it out. if I didn't have twisted quad wire I'd try twisted pair, and if I didn't have twisted pair, I'd try untwisted wire.

# Regarding your approach about using PWM to produce an analog output to be read by the receiving end:

Using PWM to produce an analog voltage to be read by the receiving end is an interesting approach. Without filtering, I think what you'd be doing is producing tremendous noise, however, literally producing electromagnetic radiation (think like low frequency radio or TV waves or something), where this huge 60m wire is your broadcasting antenna. If you put a 20k~50k resistor right at the sending end, however, and a 1uF capacitor right at the receiving end, however, to filter this PWM into an analog output immediately at the sending end, I think it would then eliminate your antenna effect where you are broadcasting something, and work much better, but still be highly susceptible to external noise influencing it. Give it a shot, but I suspect a simple set of digital pins to set HIGH or LOW on different pins to match different states would be much much much better than any analog signal at those lengths, with a 50 baud serial signal being the next best for signal-to-noise thereafter.

**So, in order of best to worst signal-to-noise ratio (SNR):**

1. differential pair (referenced to each other) digital HIGH/LOW values to represent states, which you update *very slowly*
2. RS-485 differential pair serial transmission
3. *Note: for all of the following really low-speed digital signal sending scenarios, you might try it with the low-pass filter **shown in the schematic below** too, as it may help reject noise.*
4. single-ended (referenced to GND) digital HIGH/LOW values to represent states, which you update *very slowly*
5. super low-speed SPI (including bit-banging it); ie: declare any digital pin a `CLOCK_PIN`, and any other digital pin a `DATA_PIN`. Set a clock pin LOW, set a data pin HIGH, set the clock pin HIGH. The clock transition tells the receiver (you have to code this up) to read the data pin, so you just read a `1` bit. Set the data pin LOW, set the clock pin LOW. The clock transition tells the receiver to read the data pin, so you just read a `0` bit. Leave the data pin low, set the clock pin HIGH again. You just sent another `0` bit, etc etc. Send data like this really slowly. It will work at great lengths--even better than asynchronous serial since it's synchronous.
6. asynchronous serial (+/- 12V true RS-232) at 100 baud
7. asynchronous serial (+/- 12V true RS-232) at 50 baud
8. asynchronous serial (5V TTL RS-232) at 50 baud
9. asynchronous serial (3V TTL RS-232) at 50 baud
10. analog value filtered with resistor and capacitor low-pass RC filter; update: I'd try this filtering layout for sending analog values via PWM (**see schematic below**, but use the higher resistor value I describe in my bullets underneath the schematic, rather than the lower value I show in the schematic); the filter may also be beneficial to help filter noise when doing low-speed *digital* communication too, so give it a shot in your 50-baud rate serial setup above too:
    1. Send with `analogWrite()` (PWM); receive with `analogRead()`.
    2. Report back on this too please. I'm very curious if it would work.
11. unfiltered PWM---square wave antenna broadcasting who knows what--could result in an interesting broadcasting system for you. Add a transistor and you could really amp up the power and broadcast some interesting signals out! Get some good high power going here (1W~10W+) and maybe even get the government to find out who's jamming GPS and cellular? I don't know: could be interesting!

**Schematic of low-pass RC filter to reduce noise between the two Arduinos when sending really low-speed digital signals (better), or slowly-changing analog signals (worse) between the two sides:**

simulate this circuit – Schematic created using CircuitLab

1. **For filtering the digital signals (ex: 5V TTL pseudo-RS232 serial at 50 to 100 baud)**:
    1. Use 470 Ohms for each resistor, as shown above.
    2. This results in a **cutoff freq** of 847 Hz, so stay below ~169 baud (`cutoff_freq/5 = 847Hz/5 = 169` or so) for digital signal sending through this filter.
2. **For filtering analog signals sent via `analogWrite()`**:
    1. Since most Arduino pins have a PWM Frequency of 490 Hz, we need a cutoff frequency of ~490Hz/10 = 49Hz *or lower* to cleanly filter out the PWM frequency and result in a true analog output.
    2. Using the calculator linked-to below, that means you should use R values of at least **10k each**, which results in a **cutoff freq.** of 40 Hz. You can use **20k** resistors each too, for a cutoff freq. of about 20 Hz.
3. To *increase* cutoff frequency to allow *higher* baud rates, *decrease* either R or C or both.
4. For a cutoff frequency calculator, see: https://electronicbase.net/low-pass-filter-calculator/#rc-low-pass-calculator --\> "RC Low Pass Filter Calculator" --\> enter, for example, 940 Ohms (470 x 2) as the resistor value and 0.2uF (0.1uF x 2) as the capacitor value to see that the resulting cutoff frequency for this low-pass filter is 846.57 Hz.

I'm no filter expert, but this is what I'd try. If someone sees some glaring errors in this filter or ways to improve it, please comment below the answer.

# Extras:

Here's the Bode plot for the above series filter I show except with a 1k resistor and 0.1uF (100nF) capacitor followed by the same thing again. The purple line is the voltage we care about. Source: godfreyl, here.

The cutoff frequency here is 398Hz, which is where the -3db drop occurs, which corresponds to the half power and 70.7% voltage attenuation point. (`sqrt(0.50) = 0.707`, so `0.707^2 = 0.5`)). You can read more about cutoff frequency here.

# Additional reading:

1. https://www.tldp.org/HOWTO/Remote-Serial-Console-HOWTO/serial-distance.html
2. Google search for "is rs232 balanced?"
3. https://www.idc-online.com/technical\_references/pdfs/data\_communications/tutorial\_2.pdf
4. http://www.iec-usa.com/Browse05/DTBALUN.html
5. https://en.wikipedia.org/wiki/Signal-to-noise\_ratio

# Answer
> 2 votes
It appears the easiest would be to use a simple CAN transceiver on each end, one set to transmit and the other to receive. You did not mention bidirectional communications although both Physical layers suggested below will support that quite easily. The electrical characteristics of the CAN bus cable restrict the cable length according to the selected bit rate. You can use cabling up to 250 meters with the baud rate of 250 kbit/s. The maximum bus length with a bit rate of 10 kbit/s is 1 km, and the shortest with 1 Mbit/s is 40 meters. Another approach would be to used RS485. RS485 is popular for inexpensive local networks, multidrop communication links and long haul data transfer over distances of up to 4,000 feet. The use of a balanced line means RS485 has excellent noise rejection and is ideal for industrial and commercial applications. Note these typically are driven with Async signals from a uart or similar device. Software serial would work great and leave the onboard serial port for debugging. the Async communications does the syncing automatically, nothing for you to do, just keep the baud rates the same.

---
Tags: communication, wires
---


title: How to move a servo with a function

text:
# Question
Title: How to move a servo with a function
Im currently moving a servo from one side to another by using the typical for loop like this:

```
int lightON = 180;
int lightOFF = 90;

if (buttonState == HIGH) {

  digitalWrite(LED, HIGH);
  for (pos1 = lightOFF; pos1 <= lightON; pos1 += 1) {
    servo1.write(pos1);
    delay(15);
  }
  digitalWrite(LED, LOW);

}

```

That would be moving the servo one way and if I push the button again the servo would move another way.

```
if (buttonState == LOW) {

  digitalWrite(LED, HIGH);
  for (pos1 = lightON; pos1 >= lightOFF; pos1 -= 1) {
    servo1.write(pos1);
    delay(15);
  }
  digitalWrite(LED, LOW);

}

```

The thing is, I have this very same code in 3 other servos and I don't want to be repeating the same code with 2 different variables (pos and servo) over and over again, so I tried

```
void runServoLight(int pos, int light1, int light2, Servo servo, int state) {

  if (state == 1) {

  digitalWrite(LED, HIGH);

  for (pos = light1; pos <= light2; pos += 1) {
     servo.write(pos);
     delay(15);
  }

  digitalWrite(LED, LOW);

  } else if (state == 0) {

  digitalWrite(LED, HIGH);

  for (pos = light2; pos >= light1; pos -= 1) {
    servo.write(pos);
    delay(15);
  }

  digitalWrite(LED, LOW);

  }

}

```

Now instead of running the whole for loop code I only run:

```
runServoLight(pos1, lightON, lightOFF, servo1, 1);

```

The problem is that it doesn't seem to work and I can understand why, I may be writing the function wrong but im nor really sure. I would really appreciate some help. Thank you!

# Answer
> 1 votes
You wrote:

> ```
> void runServoLight(
>         int pos, int light1, int light2, Servo servo, int state)
>
> ```

Here you are giving the list of parameters used by the function. In C++, parameters are by default passed *by value*. This means that, when the function is called, the arguments passed in the call are *copied* into the parameters listed here, which are local variables of the function. Changes to those parameters will not propagate to the arguments provided by the caller.

This can be an issue for the `Servo` object. This object keeps some internal state, which has the memory of the current configuration of the timers. Since you are working on a copy of the provided object, the original object is not updated when you act on the copy. I do not know whether this is making your program misbehave, but it would be safer to pass the `Servo` object *by reference*:

```
void runServoLight(
        int pos, int light1, int light2, Servo &servo, int state)

```

This way the object will not be copied: the function will instead work on the original object provided by the caller.

The same may apply to the *pos* parameter. The very first thing the function does with this parameter is to overwrite it. Then there is no point in receiving that value from the caller. You can instead remove the parameter and create a local variable with the same name:

```
void runServoLight(int light1, int light2, Servo &servo, int state) {
    int pos;  // local variable
    ...
}

```

If you want the caller's version of this variable to be updated, you could pass it by reference, just like the `Servo` object. It is, however, more efficient to keep the variable local and have the function return the final position. The call would then look like:

```
pos1 = runServoLight(lightON, lightOFF, servo1, 1);

```

One final point that is not visible in the snippets you showed: are you doing *edge detection* on the buttons? Edge detection means that you act on the *changes* of state of the buttons, not on the states themselves. For example, you move from `lightOFF`  to `lightON` not when the button state *is* `HIGH` but rather when it *turns* `HIGH`.

# Answer
> 0 votes
This is not a solution, however, by rafactoring it makes your sketch more maintainable as duplicated code is removed:

```
void runServoLight(int pos, int light1, int light2, Servo servo, int state)
{
  if (state == 1) {
    process(light1, light2, +1, servo);
  }
  else if (state == 0) {
    process(light2, light1, -1, servo);
  }
}

def process(int this_light, int other_light, int delta, Servo servo)
{
  digitalWrite(LED, HIGH);
  for (pos = this_light; pos >= other_light; pos += delta) {
    servo.write(pos);
    delay(15);
  }
  digitalWrite(LED, LOW);
}

```

Instead of the state integer, it's more clear to use an enumeration and use a `switch` statement.

```
#include "Servo.h"

const int LED = 13;

enum EServoState { LEFT, RIGHT };

void runServoLight(int light1, int light2, Servo servo, EServoState state);

void setup()
{
}

void loop()
{
  int light1 = 1;
  int light2 = 2;
  EServoState state;
  Servo servo;
  runServoLight(light1, light2, servo, state);
}

void runServoLight(int light1, int light2, Servo servo, EServoState state)
{
  switch (state)
  {
  case LEFT:
    process(light1, light2, +1, servo);
    break;

  case RIGHT:
    process(light2, light1, -1, servo);
    break;

  //default:
   // Handle program error
  }
}

void process(int this_light, int other_light, int delta, Servo servo)
{
  digitalWrite(LED, HIGH);
  for (int pos = this_light; pos >= other_light; pos += delta)
  {
    servo.write(pos);
    delay(15);
  }
  digitalWrite(LED, LOW);
}

```

---
Tags: servo, code-review, code-optimization, functions
---


# Question
Title: 74HC595 to 4 Digit 7 Segment using SevSegShift Library
I have a question regarding the use of SevSegShift library. I followed the example properly and tested it to see if it works. It was able to power up the seven segments and light up the whole LEDs (even the decimal) but it's not showing the output I want to show.

Based on the code below, I want to show the number 500 but it does not. Even tried `sevsegshift.setChars("abcd")`, no change.

This is my code:

```
#include <SevSegShift.h>

#define SHIFT_PIN_SHCP 6
#define SHIFT_PIN_STCP 5
#define SHIFT_PIN_DS   4

SevSegShift sevseg(SHIFT_PIN_DS, SHIFT_PIN_SHCP, SHIFT_PIN_STCP, 1, true);

void setup() {
  byte numDigits = 4;
  byte digitPins[] = {9, 10, 11, 12}; // These are the PINS of the ** Arduino **
  byte segmentPins[] = {0, 1, 2, 3, 4, 5, 6, 7}; // these are the PINs of the ** Shift register **
  bool resistorsOnSegments = false; // 'false' means resistors are on digit pins
  byte hardwareConfig = COMMON_CATHODE; // See README.md for options
  bool updateWithDelays = false; // Default 'false' is Recommended
  bool leadingZeros = false; // Use 'true' if you'd like to keep the leading zeros
  bool disableDecPoint = true; // Use 'true' if your decimal point doesn't exist or isn't connected

  sevseg.begin(hardwareConfig, numDigits, digitPins, segmentPins, resistorsOnSegments, updateWithDelays, leadingZeros, disableDecPoint);
  sevseg.setBrightness(10);
}

void loop() {
  sevseg.setNumber(500);
  //delay(1000);
  sevseg.refreshDisplay(); // Must run repeatedly; don't use blocking code (ex: delay()) in the loop() function or this won't work right
}

```

This is my breadboard schematic down below.

(220 ohm resistors on the digit pins and the segment pins are connected to the shift register)

# Answer
Finally able to fix it with the help of @PeterPaulKiefer, I was able to find the problem. The problem is in the code itself (schematic is alright. No changes there) and this is the updated code.

```
#include <SevSegShift.h>

#define SHIFT_PIN_SHCP 6
#define SHIFT_PIN_STCP 5
#define SHIFT_PIN_DS   4

SevSegShift sevseg(SHIFT_PIN_DS, SHIFT_PIN_SHCP, SHIFT_PIN_STCP, 1, true);

void setup() {
  byte numDigits = 4;
  byte digitPins[] = {12, 11, 10, 9}; // These are the PINS of the ** Arduino **
  byte segmentPins[] = {0, 1, 2, 3, 4, 5, 6, 7}; // these are the PINs of the ** Shift register **
  bool resistorsOnSegments = false; // 'false' means resistors are on digit pins
  byte hardwareConfig = COMMON_ANODE; // See README.md for options
  bool updateWithDelays = false; // Default 'false' is Recommended
  bool leadingZeros = false; // Use 'true' if you'd like to keep the leading zeros
  bool disableDecPoint = false; // Use 'true' if your decimal point doesn't exist or isn't connected

  sevseg.begin(hardwareConfig, numDigits, digitPins, segmentPins, resistorsOnSegments, updateWithDelays, leadingZeros, disableDecPoint);
  sevseg.setBrightness(100);
}

void loop() {
  sevseg.setNumber(500);
  sevseg.refreshDisplay(); // Must run repeatedly; don't use blocking code (ex: delay()) in the loop() function or this won't work right
}

```

**What changed:**

1. Turns out my 7-segment is `COMMON_ANODE` so I changed my `hardwareConfig`
2. Set brightness to 100 (At this point, it shows the number in reverse but with a decimal point in each digit)
3. Set `disableDecPoint` to `false` (At this point, the display is showing but in reverse but no more decimal point)
4. To fix this, I set the `digitPins[]` in reverse and it now shows the proper format

Thank you so much Peter for helping me figure out what's wrong!

Also the LED Bar I use is 4-Digit 0.36" LED, 7-segments display, common-anode. (The link is to the shop I got it from)
> 4 votes

---
Tags: arduino-uno, shift-register, 7-segment
---


# Question
Title: ESP32 with Lolin 2.4 inch TFT Shield Power control
I am running out of intelligence trying to control a Lolin 2.4 Inch TFT shield. I connected the shield via the official TFT connector to a Lolin D32 Pro. I am using the ILI9341 libary from Adafruit. With the libary it is no porblem controlling the display. Unfortunately, as soon as I put the esp32 into Deep Sleep, the display goes white but the background illumination stays on. Does someone know, how I can trun off the background illumination? As far as I understood, the background light is not controlled via the ILI9341. Instead I tried putting the GPIO32 on Low, since accoring to the schema of the Lolin TFT cable it is responsible for the TFT\_Led  Unfortunately that does not work either

# Answer
> 1 votes
The backlight of this shield is ON as long as there's power on the 3.3V pin, unless you make GPIO 32 an output and pull it low.

In deep sleep, however, GPIO 32 will stop acting as a pulled down output pin but the esp32 keeps its 3.3V output pin powered, so the backlight will switch ON.

You could power the display over a mosfet, controlled by a GPIO.

---
Tags: esp32, tft
---


# Question
Title: Is it necessary to set a function with always_inline attribution when the function would work maybe once?
I'm going through a library for the ILI9488 running by SPI and want to copy this library in my version.

In the beginning of the source file, there's a guard for the `SPI_HAS_TRANSACTION` that if the library would run in Arduino compiler then it would use the SPI functions, otherwise it should run from another platform SPI libraries.

Library link: jaretburkett / ILI9488

This is the part of code I have questions about:

```
// If the SPI library has transaction support, these functions
// establish settings and protect from interference from other
// libraries.  Otherwise, they simply do nothing.
#ifdef SPI_HAS_TRANSACTION
static inline void spi_begin(void) __attribute__((always_inline));
static inline void spi_begin(void) {
#if defined (ARDUINO_ARCH_ARC32)
  // max speed!
  SPI.beginTransaction(SPISettings(16000000, MSBFIRST, SPI_MODE0));
#else
    // max speed!
  SPI.beginTransaction(SPISettings(24000000, MSBFIRST, SPI_MODE0));
#endif
}
static inline void spi_end(void) __attribute__((always_inline));
static inline void spi_end(void) {
  SPI.endTransaction();
}
#else
#define spi_begin()
#define spi_end()
#endif

```

My questions:

1. why the programmer first declare the function in source file not in header file ?
2. why to use `always_inline` attribution for a function that's is most the time used once in program file and it's not likely to be used many times during operating time ?
3. what does this define means `ARDUINO_ARCH_ARC32` and where to find it ? I searched in all files in arduino folders and didn't find it. Is it dedicated for fast boards or the usual 16MHz arduino boards ?

---

Edit:

I want to add another question for the same library.

This function content:

```
void ILI9488::spiwrite(uint8_t c) {

  //Serial.print("0x"); Serial.print(c, HEX); Serial.print(", ");

  if (hwSPI) {
#if defined (__AVR__)
  #ifndef SPI_HAS_TRANSACTION
    uint8_t backupSPCR = SPCR;
    SPCR = mySPCR;
  #endif
    SPDR = c;
    while(!(SPSR & _BV(SPIF)));
  #ifndef SPI_HAS_TRANSACTION
    SPCR = backupSPCR;
  #endif
#else
    SPI.transfer(c);
#endif
  } else {
#if defined(ESP8266) || defined (ARDUINO_ARCH_ARC32)
    for(uint8_t bit = 0x80; bit; bit >>= 1) {
      if(c & bit) {
    digitalWrite(_mosi, HIGH);
      } else {
    digitalWrite(_mosi, LOW);
      }
      digitalWrite(_sclk, HIGH);
      digitalWrite(_sclk, LOW);
    }
#else
    // Fast SPI bitbang swiped from LPD8806 library
    for(uint8_t bit = 0x80; bit; bit >>= 1) {
      if(c & bit) {
    //digitalWrite(_mosi, HIGH);
    *mosiport |=  mosipinmask;
      } else {
    //digitalWrite(_mosi, LOW);
    *mosiport &= ~mosipinmask;
      }
      //digitalWrite(_sclk, HIGH);
      *clkport |=  clkpinmask;
      //digitalWrite(_sclk, LOW);
      *clkport &= ~clkpinmask;
    }
#endif
  }
}

```

what I understood from this is that the programmer wants the library to be more versatile to support AVR chips programmer by another IDE than Arduino, also supports ESP8266 and anything else should be handled by softSPI, actually pretty smart coding I guess.

My question here, is does `#if defined (__AVR__)` checks for either AVR/Arduino in general and when specifies `SPI_HAS_TRANSACTION` means Arduino SPI library specifically ? right ?

# Answer
> 1. why the programmer first declare the function in source file not in header file ?

the declarion is for the inline attribute. the function should be used only in this cpp.

> 2. why to use always\_inline attribution for a function that's is most the time used once in program file and it's not likely to be used many times during operating time ?

there are 14 occurrences of transaction start and it is called before every SPI communication commands set in the library. see my answer about beginTransaction

> 3. what does this define means ARDUINO\_ARCH\_ARC32 and where to find it ? I searched in all files in arduino folders and didn't find it. Is it dedicated for fast boards or the usual 16MHz arduino boards ?

the architecture define is generated by the builder from selected board's boards package folder name. ARC32 architecture is the Intel Arduino 101 boards package.

EDIT (answer to edited part of the question):

> My question here, is does `#if defined (__AVR__)` checks for either AVR/Arduino in general and when specifies SPI\_HAS\_TRANSACTION means Arduino SPI library specifically ? right ?

`__AVR__` is defined in avrlibc, the toolchain for AVR microcontrolers. Arduino uses avrlibc for AVR MCUs. It is not recommended to check `__AVR__`. The AVR family of MCU is now large with different peripherals so checking `__AVR__` should be really restricted to CPU matters.

Every Arduino 'architecture' has its own SPI library. The transactions support was added later so not all implementations of the SPI library support transactions. To declare transactions availability in SPI library Arduino defined the SPI\_HAS\_TRANSACTION define.
> 1 votes

# Answer
1. The function is only used in the library, and not part of the "API" of that library. Kind of like a private function.
2. Both functions are both being called 14 times inside the source code of this library. But in the larger scheme of things, it doesn't add a lot. But why not add it and maybe save a few bytes, and a few clock cycles.
3. The `ARDUINO_ARCH_ARC32` is for the Arduino 101 board (Intel Curie processor).
> 1 votes

# Answer
Here I am only addressing question number 2. The others have already complete answers.

The choice to whether a function should be inlined or not is a speed/size trade-off. There is a cost to calling a function. On AVR, for example, the `call` instruction takes 4 CPU cycles, and `ret` takes another 4. Inlining the function removes this cost. On the other hand, you end up with as many copies of the function as places where it is inlined, and this in turn costs flash memory.

The compiler is usually smart enough to make wise decision regarding function inlining. In this case, it is not obvious what decision it would make on its own. On the one hand, the function is used multiple times in the code, which makes a good case *against* inlining it. On the other hand, the body of the function is tiny: only setting up some registers (the two parameters of `SPIClass::beginTransaction()`, including the implicit `this`) and jumping to another function, so the cost of inlining is small.

For this library, the programmer happened to have a strong opinion on this matter, and he though inlining was really the best option. Also, he did not thrust the compiler to make the good decision. This is the reason why he used the gcc extension:

```
__attribute__((always_inline))

```

And no, it is not necessary, it is just an optimization choice.
> 1 votes

---
Tags: c++, spi, inline
---


title: Sketch skipping the OPEN Arduino inputs

text:
# Question
Title: Sketch skipping the OPEN Arduino inputs
Folks, I am a beginner to Arduino. I have a sketch that tests a set of INPUTS for HIGH or LOW by using a 'for' loop. When the for loop reaches an INPUT which is kept OPEN (no wires connected to it), the for loop apparently 'skips' that INPUT and move on to the next. However, if I have +5V connected to any INPUTS within the range of the for loop, it works correctly. Any thoughts what's is happening here?

# Answer
You should always connect something to an input to pull it high or low when no signal is present. The simplest thing is to activate the built-in pullup resistor, which will result in the input returning HIGH when there is nothing connected. If that's not compatible with your particular use, add a resistor from the input to ground (10k-100k is fine) so that it will return LOW when nothing else is connected. If the input is just floating, it is susceptible to noise causing random state changes. The input impedance is very high (100 Meg) so it can pick up static and other mischief.
> 2 votes

---
Tags: arduino-mega
---


title: When is SPI.beginTransaction required?

text:
# Question
Title: When is SPI.beginTransaction required?
I have been gradually converting many devices from i2c to spi for various reasons. I noticed in tutorials like this from arduino.cc that `SPI.beginTransaction` is explicitly called out. Then they link to examples such as this and this where they don't use `SPI.beginTransaction`. In working through my own devices I found that I could often (almost always) forgo the use of `SPI.beginTransaction`. The only case where I found problems was when I had 2 devices that used different SPI settings.

I went to Google and other searches for a simple reason for `SPI.beginTransactions` and found discussions of interrupts and locks and settings. There was much discussions about users applications wrapping all calls with `SPI.beginTransaction` and `SPI.endTransaction`. There were bugs when libraries didn't wrap everywhere.

This leads me to the conclusion that making calls to `SPI.beginTransaction` are only needed when the SPI settings need to change, but in practice you should always do it. Is there documentation or examples that definitely state the purpose and proper (best practice) usage of it?

# Answer
> 4 votes
Although this question has an accepted answer, I'd like to provide some background and historical reasons to OP's question.

Transactional SPI using `SPI.beginTransaction()` was introduced in 2014, it was not available in the early version of the Arduinos or example codes published before that. As the results, there are still many codes out there on the Internet show the old way of setting up the SPI configuration, and this include the exampes provided by Arduino.cc on its library reference page even up to today, the authors of the library did not make any changes in those examples to show the usage of new API.

What the `SPI.beginTransaction()` does is to allow you to set unique SPI settings(through `SPISettings` object) for your application, even if other devices use different settings. `SPI.beginTransaction()` behave like a locking mechanism to gain the exclusive use of the SPI bus, and therefore requires `SPI.endTransaction()` to release the bus for others to access it. `SPI.beginTransaction()` provides better cross-device compatibility and solve software conflicts and allowing multiple SPI devices to properly share the SPI bus. You should therefore use the `SPI.beginTransaction()` in your SPI sketch. You should also using `SPISettings` object to configure your SPI communication interface, and not use the deprecated methods such as `SPI.setBitOrder()`, `SPI.setClockDivider()` and `SPI.setDataMode()` for setting up the SPI configuration.

Although rarely need today, there is a pre-defined macro `SPI_HAS_TRANSACTION` in SPI library for checking whether the firmware of the Arduino board supports `SPI.beginTransaction()`. It is useful for providing backward compatibility if you are writing an Arduino library.

```
#ifdef SPI_HAS_TRANSACTION
  SPI.beginTransaction(SPISettings(4000000, MSBFIRST, SPI_MODE0));
#elseif
  // use old Arduino SPI library syntax
#endif

```

# Answer
> 3 votes
It appears calling the method beginTransaction() prevents additional SPI transactions from interrupting the current transaction. Calling endTransaction() allows access to the SPI hardware again. This added complexity may sound odd. Especially in the simple Arduino sketch-writing paradigm. But as programs grow in complexity, more SPI devices are added and interrupts are used to quickly access SPI devices - the likely hood of SPI contention increases.

In the SPIClass source code, there is this comment immediately before the beginTransaction() method:

```
  // Before using SPI.transfer() or asserting chip select pins,
  // this function is used to gain exclusive access to the SPI bus
  // and configure the correct settings.

```

So, it may be, that if the sketch-code is particularly well behaved and does not need protection from accidentally using the SPI hardware from multiple concurrent transactions, that these two methods need not be used. But why take the chance.

# Answer
> 2 votes
Every modern Arduino library for a SPI device should use SPI library with beginTransaction to be able to coexists with libraries for SPI devices using different modes and speed.

Recently we had here a question about two libraries for SPI not working together. The devices required different modes. The libraries didn't use beginTransaction, they only used SPI.begin() in initialization. It is not possible to use these libraries together.

The STM32 core supports switching CS pin with enhanced beginTransaction and endTransaction but this is not so useful as it looks. Many devices use CS as 'commit' and the CS must be switched several times inside one 'transaction'.

If you write a library you don't know with what other SPI devices on bus it will be used so call `beginTransaction` as the library gets control and `endTransaction` as the public library function returns control out of the library.

---
Tags: spi
---


title: Arduino does not work

text:
# Question
Title: Arduino does not work
When I try to upload a sketch to my Arduino Uno R3 then sometimes I get the following issue:

At the beginning the RX LED flashes three times and then I get errors:

```
    avrdude: stk500_recv(): programmer is not responding
    avrdude: stk500_getsync() attempt 1 of 10: not in sync: resp=0xd1
    avrdude: stk500_recv(): programmer is not responding
    avrdude: stk500_getsync() attempt 2 of 10: not in sync: resp=0xd1
    avrdude: stk500_recv(): programmer is not responding
    avrdude: stk500_getsync() attempt 3 of 10: not in sync: resp=0xd1
    avrdude: stk500_recv(): programmer is not responding
    avrdude: stk500_getsync() attempt 4 of 10: not in sync: resp=0xd1
    avrdude: stk500_recv(): programmer is not responding
    avrdude: stk500_getsync() attempt 5 of 10: not in sync: resp=0xd1
    avrdude: stk500_recv(): programmer is not responding
    avrdude: stk500_getsync() attempt 6 of 10: not in sync: resp=0xd1
    avrdude: stk500_recv(): programmer is not responding
    avrdude: stk500_getsync() attempt 7 of 10: not in sync: resp=0xd1
    avrdude: stk500_recv(): programmer is not responding
    avrdude: stk500_getsync() attempt 8 of 10: not in sync: resp=0xd1
    avrdude: stk500_recv(): programmer is not responding
    avrdude: stk500_getsync() attempt 9 of 10: not in sync: resp=0xd1
    avrdude: stk500_recv(): programmer is not responding
    avrdude: stk500_getsync() attempt 10 of 10: not in sync: resp=0xd1

```

Sometimes I get this:

```
    avrdude: ser_open(): can't open device "\\.\COM3": Odmowa dostępu.

```

And sometimes Windows does not see the Arduino.

At this site Have I bricked my Arduino Uno? Problems with uploading to board I read that to check the programmer I must to connect RX with TX and GND with RESET pins and then plug Arduino to my computer, open Serial Monitor and write anything and if you receive the same characters from the Arduino, then the programmer and USB cable are OK. It worked for me.

And I have got one more info. When I plug Arduino with USB to my laptop the L led lights. When I press Reset on Arduino nothing happens, it still lights.

I recently bought a new USB cable, and it worked one day and then I could not upload sketches again. I uninstalled and installed drivers, but nothing changed.

This is a short video with my Arduino https://drive.google.com/file/d/0ByeWvrEgy2gRbWdHQ3d5RWU3Mmc/view?usp=sharing

---

I will buy USBasp programator is it a good idea?

# Answer
It's normal that the `L-LED` is steady `on` after the USB connection is established. However, after pressing and releasing `Reset` it should flicker for a second, then go back to `on` again.

Check https://www.arduino.cc/en/Guide/Troubleshooting#toc1 for reasons why you can't upload.

On http://www.arduino.org/products/boards/4-arduino-boards/arduino-uno I've found:

> The Arduino Uno has a resettable polyfuse that protects your computer's USB ports from shorts and overcurrent. Although most computers provide their own internal protection, the fuse provides an extra layer of protection. If more than 500 mA is applied to the USB port, the fuse will automatically break the connection until the short or overload is removed.

I haven't found out so far, how to read the current values of the fuses.
> 1 votes

# Answer
1. Serial could be flooded if you were spamming it in ur last program you uploaded.
2. Ur arduino is broken
3. Try reflashing ur bootloader which is a common problem when you see data sync errors.
> 1 votes

# Answer
> I will buy USBasp programator is it a good idea?

Yes, buy the USBasp programmer, reflash the bootloader with it, and try uploading code again. A corrupted bootloader very well may be the problem.
> 0 votes

---
Tags: c++, c, programmer
---


# Question
Title: How to power board plus module with one battery pack
I'm someone who's very new to robotics and the physical side of computers (software guy) so apologies if this is a stupid question. I'm purchasing an Arduino Nano 33 IoT that I'll be using in conjunction with an Adafruit FONA 3G Cellular Breakout (https://www.adafruit.com/product/2687). I'd like to be able to power the entire unit off of one battery pack but my problem is that both the Arduino and the Adafruit 3G unit have separate power inputs. Adafruit's website says that a Lipoly battery is required to run the unit. Is there any way to "pass through" or "split" power between the two units? This way I was thinking I could run everything off of one external battery pack. Optimally I don't have to use a Lipoly battery and I could use a large external battery pack connected to jumpers or a barrel jack.

# Answer
you can use a breadboard and jumper cable. connect the VCC and GND of battery to a breadboard, do this for your Arduino and sim card module too. just remember they should be in a one row. GND with GND row, and VCC with VCC row note: this way is okay just for debugging
> 1 votes

---
Tags: power, battery
---


# Question
Title: Arduino Ethernet Shield on Arduino Mega Pin Usage!
I currently have an Arduino Ethernet Shield which is Mega Compatible. I've found on the Arduino Ethernet Library https://www.arduino.cc/en/Reference/Ethernet that the Shield uses different Pins on the Arduino Uno and Arduino Mega. How is this possible? The Ethernet shield isn't connected to those pins mentioned.

Arduino Uno: Pin: 13 - SCK Pin: 12 - MISO Pin: 11 - MOSI Pin: 10 - SS for Ethernet Controller

Pin: 4 - SS for SD Card

Arduino Mega: Pin: 52 - SCK Pin: 50 - MISO Pin: 51 - MOSI Pin: 53 - SS for Ethernet Controller

Pin: 4 - SS for SD Card

# Answer
Those 4 pins D50 to D53 are the ICSP pins which appear twice on the MEGA; the Ethernet Shield uses the second set of connections located in the middle of the Mega board.

The header files gets told (by the Arduino IDE) that the board is a MEGA so the compiler uses those pin numbers to connect.
> 1 votes

# Answer
Firstly, I am assuming you are using an Ethernet Shield similar to the Arduino Ethernet Shield.

Secondly, I assume that you are referring to the following quote on the Ethernet Library page:

> The Arduino board communicates with the shield using the SPI bus. This is on digital pins 11, 12, and 13 on the Uno and pins 50, 51, and 52 on the Mega. On both boards, pin 10 is used as SS. On the Mega, the hardware SS pin, 53, is not used to select the Ethernet controller chip, but it must be kept as an output or the SPI interface won't work.

This communication interface is called SPI.

The Ethernet Shield connects to the SPI interface (ie MISO, MOSI, SCK) using the in-circuit Serial Programming (ICSP) pins which are also connected to the SPI interface pins (ie. pins 50, 51, and 52)

As noted in the above quote, pin 53 is not used as the SS pin (but needs to be kept as an output pin and not used). Pin 10 is used instead for the ethernet SS pin on both the Uno and Mega.
> 0 votes

---
Tags: arduino-mega, shields, ethernet
---