# Question
Title: Does the compiler generate intermediate assembler?
My source files are \*.ino, but after compilation there aren't any other files placed in the folder. Does the compiler generate intermediate assembler, and if so, where does it leave them? Or is the machine code available somewhere?

# Answer
> 6 votes
> My source files are \*.ino, but after compilation there aren't any other files placed in the folder.

Correct. The Arduino IDE performs compilation in a separate temporary directory, whose location you can see if you enable verbose compilation in the IDE options.

> Does the compiler generate intermediate assembler, and if so, where does it leave them?

By default GCC (which the Arduino IDE uses) does not leave intermediate assembly language files on disk. You must pass the `--save-temps` argument to have it leave them in the current directory, or `--save-temps=obj` to save them in the output directory.

> Or is the machine code available somewhere?

The machine code is available in the .elf and .hex files generated in the temprary directory.

# Answer
> 1 votes
Yes.

Arduino compilation is set up with link-time optimization (LTO), and the assembly files created during C compilation don't contain any assembly code - just the intermediate representation used later in the LTO stage to generate actual assembly code. We want the latter.

It so happens, rather nicely, that the very last time assembler is invoked in the entire compilation process, is to take the output from the LTO stage, and turn it into a whole-application object file.

To get at this assembly file, do the following (on Windows):

1. Open `%LOCALAPPDATA%\Arduino15\packages\arduino\hardware\avr\1.8.3\platform.local.txt` (create it if it doesn't exist). Add the following line

```
compiler.c.elf.extra_flags=-save-temps=obj -fverbose-asm

```

If there already is such a line there, just add the above options (to the right of `=`).

**Note:** If you can't find the folder, look for the following files: `boards.txt`, `platform.txt`, `programmers.txt`. If you find these files in multiple locations, the one you want should be *inside your home directory* (i.e. not in `Program Files` or `/Applications` or `/usr`), and should be correlated at least partially to the version of Arduino you're using (should you have multiple versions installed).
2. Build the sketch again.
3. Look for a file named `%TEMP%\cc*.ltrans.s`. Each build will create a new such file. If you sort them by timestamp, the newest one is for the most recent build.

**Note:** The environment variables, enclosed by `%` signs, are valid in the Windows dialog boxes. You can directly paste such a path into e.g. an Open or Save As... dialog box, and it'll work. Paths with globs (`*`) will act as filters (IIRC).

To know which exact `cc*.s` file was generated, add the verbose option to the final binary generator pass:

```
compiler.c.elf.extra_flags=-save-temps=obj -fverbose-asm -v

```

Rebuild, and copy-paste all the output from the compilation status window in Arduino to e.g. Notepad++, and search for `ar.exe`. The sole line that contains `ar.exe` ends with the name of this `cc` file:

```
 c:/users/[...omitted...]/avr/bin/as.exe -mmcu=avr6 -mno-skip-bug
    -o C:\Users\[...]\AppData\Local\Temp\cc3XhU2F.ltrans0.ltrans.o
    C:\Users\[...]\AppData\Local\Temp\cc3XhU2F.ltrans0.ltrans.s

```

How does the file look? This is a short extract, just to show that both the C source and the assembly are intermingled - and this represents exactly the binary embedded in the `.hex` file and sent to the target.

```
.LBE33:
.LBE32:
.LBB34:
.LBB35:
 ;  C:\Users\[...]\Documents\Arduino\sketch_jul01a\sketch_jul01a.ino:29:   pinMode(ledPin, OUTPUT);
    .file 4 "C:\\Users\\[...]\\Documents\\Arduino\\sketch_jul01a\\sketch_jul01a.ino"
    .loc 4 29 0
    ldi r22,lo8(1)   ; ,
    ldi r24,lo8(13)  ; ,
    call pinMode     ;
.LVL55:
 ;  C:\Users\[...]\Documents\Arduino\sketch_jul01a\sketch_jul01a.ino:30:   pinMode(relayPin, OUTPUT);
    .loc 4 30 0
    ldi r22,lo8(1)   ; ,
    ldi r24,lo8(12)  ; ,
    call pinMode     ;
.LVL56:
 ;  C:\Users\[...]\Documents\Arduino\sketch_jul01a\sketch_jul01a.ino:31:   pinMode(ldrPin, INPUT);
    .loc 4 31 0
    ldi r22,0    ;
    ldi r24,lo8(54)  ; ,
    call pinMode     ;
.LVL57:
.LBE35:
.LBE34:
.LBB36:
.LBB37:

```

This approach also works on Linux and MacOS, except that the paths are slightly different, and path expansion uses different syntax. The two files of concern still are `platform.local.txt` \- a file you must create, since it doesn't exist at first, and the `${TEMP}/cc*.ltrans.s` files.

---
Tags: compile
---


# Question
Title: How do I control a servo with python through an Arduino
I'm trying to make it so I can control 2 servos with data that I get from a python script that tracks my face.

I have found 2 libraries that do this:pySerial and pyfirmata.

Is one superior to the other one, are there more libraries, or should approach things differently.

# Answer
> 1 votes
I'd say pyFirmata can work but controling servos ... NOPE! use pyserial and add the code

---
Tags: serial, python
---


# Question
Title: 5v pin not outputting any voltage in Arduino Nano ble 33
I bought an Arduino Nano ble 33 but when I try to power my MQ-4 and MQ-8 sensors, these don't turn on at all, they do turn on if I switch to the 3.3V tho.

Is there anything special that I need to do to be able to use the 5V pin, or my board is faulty?

P.S: When I say 5V I mean the pin next to the green rectangle.

# Answer
i think you solder the two pads but i'll tell you something: use the 3.3v pin
> 1 votes

---
Tags: arduino-nano, arduino-nano-ble
---


# Question
Title: Trying to use I2C accelerometer and SPI OLED
I'm trying to stream the data coming from my I2C MMA8452Q accelerometer to an Adafruit-based SSD1351 OLED RGB display that uses SPI via an Arduino UNO.

When I run example code for the accelerometer I can see it outputting data to the serial monitor, and when I run my code for the screen using a joystick as test input it graphs the values nicely.

When I try and build in the I2C example code into my code for the display, the moment I include to the code to read the values from the accelerometer, the program runs setup and then goes blank after that. When I block out the sensor read and swap in the joystick reads it works fine again.

I've been staring at all kinds of forum posts about using SPI and I2C simultaneously but I haven't really found any with a straightforward solution or they use a very different board.

```
#include <Adafruit_SSD1351.h>
#include <SparkFun_MMA8452Q.h>
#include <SPI.h>
#include <Wire.h>

#define SCREEN_WIDTH  128
#define SCREEN_HEIGHT 128 // Change this to 96 for 1.27" OLED.

// You can use any (4 or) 5 pins
#define SCLK_PIN 2  // not using this as I've got it setup
#define MOSI_PIN 3  // on the hardware SPI pins as per the text below
#define DC_PIN   4
#define CS_PIN   5
#define RST_PIN  6  // not in use

#define joy_XPin A1
#define joy_YPin A0

// Color definitions
#define BLACK           0x0000
#define BLUE            0x001F
#define RED             0xF800
#define GREEN           0x07E0
#define CYAN            0x07FF
#define MAGENTA         0xF81F
#define YELLOW          0xFFE0
#define WHITE           0xFFFF

// Option 1: use any pins but a little slower
// Adafruit_SSD1351 tft = Adafruit_SSD1351(SCREEN_WIDTH, SCREEN_HEIGHT, CS_PIN, DC_PIN, MOSI_PIN, SCLK_PIN, RST_PIN);

// Option 2: must use the hardware SPI pins
// (for UNO thats sclk = 13 and sid(which is SDA on my display) = 11) and pin 10 must be
// an output. This is much faster - also required if you want
// to use the microSD card (see the image drawing example)
Adafruit_SSD1351 tft = Adafruit_SSD1351(SCREEN_WIDTH, SCREEN_HEIGHT, &SPI, CS_PIN, DC_PIN, RST_PIN);

MMA8452Q accel; // intialise sensor - SDA/SCL connected to A4/A5 pins as per example code

#define graphLength 32

int joy_X, joy_Y;
int tilt_X, tilt_Y;

int graphY[graphLength] = {0};
int graphX[graphLength] = {0};

void setup() {
  Serial.begin(9600);
  tft.begin();
  Wire.begin();

  tft.fillScreen(BLACK);

  tft.setCursor(10,64);
  tft.setTextColor(WHITE);
  tft.println("Welcome, have fun");

  delay(2000);
  tft.fillScreen(BLACK);
}

void loop() {

  // scaled inputs to be smaller and offset to be in the middle of the screen
  joy_X = (analogRead(joy_XPin) / 32)+48;
  joy_Y = (analogRead(joy_YPin) / 32)+48;

  // when this block is included everything breaks
  // this is the code to read the accelerometer input so I'm pretty sure the issue is here.
  /*
  if(accel.available()){
    tilt_X = accel.getCalculatedX() * 10;
    tilt_Y = accel.getCalculatedY()* 10;
  }
  */

  graphY[graphLength - 1] = tilt_X; // swap tilt_X/Y with joy_X/Y to graph joystick inputs
  graphX[graphLength - 1] = tilt_Y;
  for(int i = 0; i <= (graphLength - 1); i++){  // invokes undefined behaviour but it works for now
    tft.drawPixel(i,graphY[i],RED);
    tft.drawPixel(i,graphX[i],BLUE);
  }

  delay(5);
  graphShiftAlong();
}

// Just functions to clear the things I've drawn on the display rather than trying to wipe the whole display each time.

void clearPixel(uint16_t x, uint16_t y){
  tft.drawPixel(x, y, BLACK);
}

void drawRect(uint16_t x, uint16_t y, uint16_t w, uint16_t h, uint16_t color){
  int x1,y1,x2,y2;
  w = w/2;
  h = h/2;

  x1 = x - w;
  y1 = y - h;
  x2 = x + w;
  y2 = y + h;

  tft.drawLine(x1,y1,x1,y2,color); // top left to bottom left
  tft.drawLine(x1,y1,x2,y1,color); // top left to top right
  tft.drawLine(x2,y1,x2,y2,color); // top right to bottom right
  tft.drawLine(x2,y2,x1,y2,color); // bottom right to bottom left
}

void clearRect(uint16_t x, uint16_t y, uint16_t w, uint16_t h){
  drawRect(x,y,w,h,BLACK);
}

// Sets the 'old' data to be drawn as black and redraws it one pixel offset
// Compiler gives me red text but not errors so I'm running with it for now
void graphShiftAlong(){
  for(int i = 0; i <= (graphLength - 1); i++){
    tft.drawPixel(i,graphY[i],BLACK);
    tft.drawPixel(i,graphX[i],BLACK);
    graphX[i] = graphX[i+1];
    graphY[i] = graphY[i+1];
  }
}

```

The example code I'm using for the sensor is here:

```
  Library for the MMA8452Q
  By: Jim Lindblom and Andrea DeVore
  SparkFun Electronics

  Do you like this library? Help support SparkFun. Buy a board!
  https://www.sparkfun.com/products/14587

  This sketch uses the SparkFun_MMA8452Q library to initialize
  the accelerometer and stream calcuated x, y, z, acceleration
  values from it (in g units).

  Hardware hookup:
  Arduino --------------- MMA8452Q Breakout
    3.3V  ---------------     3.3V
    GND   ---------------     GND
  SDA (A4) --\/330 Ohm\/--    SDA
  SCL (A5) --\/330 Ohm\/--    SCL

  The MMA8452Q is a 3.3V max sensor, so you'll need to do some
  level-shifting between the Arduino and the breakout. Series
  resistors on the SDA and SCL lines should do the trick.

  License: This code is public domain, but if you see me
  (or any other SparkFun employee) at the local, and you've
  found our code helpful, please buy us a round (Beerware
  license).

  Distributed as is; no warrenty given.
*/

#include <Wire.h>                 // Must include Wire library for I2C
#include "SparkFun_MMA8452Q.h"    // Click here to get the library: http://librarymanager/All#SparkFun_MMA8452Q

MMA8452Q accel;                   // create instance of the MMA8452 class

void setup() {
  Serial.begin(9600);
  Serial.println("MMA8452Q Basic Reading Code!");
  Wire.begin();

  if (accel.begin() == false) {
    Serial.println("Not Connected. Please check connections and read the hookup guide.");
    while (1);
  }
}

void loop() {
  if (accel.available()) {      // Wait for new data from accelerometer
    // Acceleration of x, y, and z directions in g units
    Serial.print(accel.getCalculatedX(), 3);
    Serial.print("\t");
    Serial.print(accel.getCalculatedY(), 3);
    Serial.print("\t");
    Serial.print(accel.getCalculatedZ(), 3);
    Serial.println();
  }
}

```

# Answer
Your SPI is not setup for the Arduino UNO. Check another example for SPI and you will be using pins 11 and 13, this is mandatory and 8,9,10 or any three and there is a definition statement for these 3 pins - look at the example for your display. For I2C do you have pullup resistors on both I2C lines 4.7k up to 10k? These are required. Good luck
> 1 votes

---
Tags: arduino-uno, i2c, spi, accelerometer, oled
---


title: Audrino mkr1500 keeps going offline

text:
# Question
Title: Audrino mkr1500 keeps going offline
I am using a MKR1500 with an Arduino SIM. I am able to upload the code on the device using the web editor. But when once I am done uploading the code, the device shows status offline and I am unable to check if the data is changing in the dashboard. I am running the below code to test. Also if i check when was the last time it was active, it generally shows before flashing. Also found that when I detach the device from the web UI and select it again, it shows up the last active timing as when it was detached. But during that time I saw it was inactive. Is there something that i am missing? Can someone please help me with it. Thanks!

```
int readSensor;
void setup() {
  // Initialize serial and wait for port to open:
  Serial.begin(9600);
  // This delay gives the chance to wait for a Serial Monitor without blocking if none is found
  delay(1500);
  Serial.println("Hello world");
  // Defined in thingProperties.h
  initProperties();
  // Connect to Arduino IoT Cloud
  ArduinoCloud.begin(ArduinoIoTPreferredConnection);
  setDebugMessageLevel(2);
  ArduinoCloud.printDebugInfo();
}
void loop() {
  ArduinoCloud.update();
  // Your code here
  int sensor1 = analogRead(A1);
  int carbonMonoxide = analogRead(A2);
  int methaneSensor = analogRead(A3);
  Serial.println(sensor1);
  Serial.println(carbonMonoxide);
  Serial.println(methaneSensor);
  delay(1000);
 }
void onADCvalueChange() {
  // Do something
}

```

# Answer
The mkr1500 is not compatible with the sim right only the mkr1400 is working with the sim SORRY! Check The Page store.arduino.cc/digital/sim
> 1 votes

---
Tags: iot
---


# Question
Title: BLE library for Beetle Bluno BLE with AVR architecture (ATmega328)
When I try to `#include <ArduinoBLE.h>` in my Arduino program, I get the error:

> WARNING: library ArduinoBLE claims to run on samd, megaavr, mbed, apollo3, mbed\_nano, mbed\_portenta architecture(s) and may be incompatible with your current board which runs on avr architecture(s).

Apart from potentially trying to import an incompatible library, am I doing something wrong? If not, are there any Arduino libraries for AVR architectures that will allow me to transfer data through Bluetooth via dealing with Services, Characteristics, Descriptors, etc.?

The Beetle Bluno BLE board is based on:

* ICSP1: ATmega 328P
* ICSP2: CC2540

# Answer
> 0 votes
The device is not an Arduino device (Uno, Mega, Nano, Mkr, etc) and ArduinoBLE was made only for Arduino devices with built-in Bluetooth.

---
Tags: bluetooth, ble, bluno
---


title: Problem with DC motor

text:
# Question
Title: Problem with DC motor
I've got a circuit with Arduino UNO Rev3, DC motor, button to switch direction of rotation and potentiometer to regulate revs. The problem is that usually when I increase voltage using potentiometer, motor doesn't want to start rotating by itself and it does only when I move its shaft with finger or when I press the button again. I would undrestand that it can be due to friction and that's why moving shaft with finger helps, but why does motor start rotating when I press the button changing direction?

Here is my circuit:

And here is my code:

# Answer
> 1 votes
Firstly, you need a motor driver to drive a motor from an Arduino. You cannot drive it directly from IO pins.

Secondly by using a potentiometer like that for controlling the speed you are massively starving the motor of power (not that the Arduino *can* provide such power, and if it could then the potentiometer would smoke).

Your design should be:

* Potentiometer into an analog input to control the speed using PWM
* Outputs from the Arduino to control the direction (GPIO x 2) and speed (PWM) to a motor driver (L293 is commonly available)
* Motor connected to the motor driver
* Power supply suitable for your motor connected to the motor driver

There are many many examples on the web that show you this kind of circuit. Follow one.

# Answer
> 0 votes
First of all, disconnect your Motor which is directly connected to your UNO if you want your Board to be safe and sound.

Arduino or any other microcontroller ICs are not made for directly running High powered loads.

The work of a microcontroller is to produce signals which must be run through a transistor or an IC amplification method to drive high loads.

You are running the Motor directly from UNO pins. What wrong may it go?

1. If your motor consumes current more than 20mA then the pin where you connected the arduino is to heat up and will burn if you continue further.
2. Let's suppose your motor consumes current less than 20mA, still it has a high risk that a motor sometimes creates very high voltage and current surge in a specific condition.

If you continue to do so, you will end up burning those pin completely.

So what befits your project seems to be a motor driver IC like L293D or L298N

Instead of a motor, connect Motor Driver IC logic level input to digital output pin 3 and 4 of Arduino then connect a motor to the output of the Motor Driver IC

More about these ICs can be found in Datasheets

---
Tags: motor, button
---


# Question
Title: Esp8266 firmware update with uno "chip sync error"
I have an ESP8266-01. I followed the instructions on this

http://yaab-arduino.blogspot.com/2015/12/flashing-esp8266-firmware-arduino.html?m=1

exactly. When I start the firmware update the TX and RX pins blink rapidly along with the blue light on the ESP.

Then the terminal spits out "chip sync error" and disconnects.

I would like this to work because buying a ftdi cable isn't an option right now.

# Answer
I run the same problem too and took me countless hours to figure this error out. The problem seems the Baud rate starts at 115200 while the COM port is set to 9600. What I did is I checked the Device Manager and find the COM port, right clicked to properties and to the Port Settings Tab, I changed the Baud Rate to 115200 and flash the firmware again. And it works!
> 3 votes

# Answer
just after compilaion starts in the arduino ide , press and hold the flash button and then press the reset button , now release the reset button and finally release the flash button, this is how the esp goes into flash mode.this will work
> 3 votes

---
Tags: esp8266
---


# Question
Title: Question regarding using Arduino and MIDI
I'm using an Arduino Leonardo for sending MIDI In and Out messages to Ableton Live.

Components include a Potentiometer, a Capacitive Touch Sensor, and a DC Motor, which I'm powering with a L298N Motor Driver.

Right now I have it set up so that I can record automation in by moving the potentiometer, send a MIDI note in when I'm touching the fader, and follow automation using the DC Motor.

The problem that I'm having is that when I go to play my tracks, the automation that I recorded with the potentiometer is deactivated, and therefore my motor doesn't respond. I believe this is because I'm sending MIDI Input and Output at the same time. Here's the current version of the code:

```
#include <Control_Surface.h>
#include <CapacitiveSensor.h>

int minimumCp = 200;
int lastfaderPosition = 0;     // previous state of the button

const byte touchSend = 7;
const byte touchReceive = 8;

CapacitiveSensor touchSensor = CapacitiveSensor(touchReceive, touchSend);
USBMIDI_Interface midi;
CCPotentiometer faderPosition { A0, MIDI_CC::General_Purpose_Controller_1 };

int incomingChannel;
int incomingNote;
int incomingVelocity;
const byte mainFaderPin = 0;
const byte motorUp      = 4;
const byte motorDown    = 5;
const byte motorPWM     = 6;
byte motorSpeed = 150;
byte tolerance  = 40;
double faderMax = 0;
double faderMin = 0;

struct MyMIDI_Callbacks : FineGrainedMIDI_Callbacks<MyMIDI_Callbacks> {

  void onControlChange(Channel channel, uint8_t controller, uint8_t value, Cable cable) {
    incomingNote = controller;
    incomingVelocity = value;
  }
  void onProgramChange(Channel channel, uint8_t program, Cable cable) {
    Serial << "Program Change: " << channel << ", program " << program << ", "
           << cable << endl;
  }
  void onAfterTouchChannel(Channel channel, uint8_t pressure, Cable cable) {
    Serial << "Channel Pressure: " << channel << ", pressure " << pressure
           << ", " << cable << endl;
  }
  void onPitchBend(Channel channel, uint16_t bend, Cable cable) {
    Serial << "Pitch Bend: " << channel << ", bend " << bend << ", " << cable
           << endl;
  }
  void onSystemExclusive(SysExMessage se) {
    Serial << F("System Exclusive: [") << se.length << "] "
           << AH::HexDump(se.data, se.length) << ", " << se.cable << endl;
  }
  void onTimeCodeQuarterFrame(uint8_t data, Cable cable) {
    Serial << "MTC Quarter Frame: " << data << ", " << cable << endl;
  }
  void onSongPosition(uint16_t beats, Cable cable) {
    Serial << "Song Position Pointer: " << beats << ", " << cable << endl;
  }
  void onSongSelect(uint8_t songnumber, Cable cable) {
    Serial << "Song Select: " << songnumber << ", " << cable << endl;
  }
  void onTuneRequest(Cable cable) {
    Serial << "Tune Request: " << cable << endl;
  }
  void onClock(Cable cable) { Serial << "Timing Clock: " << cable << endl; }
  void onStart(Cable cable) { Serial << "Start: " << cable << endl; }
  void onContinue(Cable cable) { Serial << "Continue: " << cable << endl; }
  void onStop(Cable cable) { Serial << "Stop: " << cable << endl; }
  void onActiveSensing(Cable cable) {
    Serial << "Active Sensing: " << cable << endl;
  }
  void onSystemReset(Cable cable) {
    Serial << "System Reset: " << cable << endl;
  }

} callback;

void setup() {
  touchSensor.set_CS_AutocaL_Millis(0xFFFFFFFF);
  midi.setCallbacks(callback);
  Control_Surface.begin();
  pinMode(motorDown, OUTPUT);
  pinMode(motorUp, OUTPUT);
  pinMode(motorPWM, OUTPUT);
  Serial.begin(250000);
  calibrateFader();
}

void calibrateFader() {
  digitalWrite(motorUp, HIGH);
  analogWrite(motorPWM, motorSpeed);
  delay(300);
  digitalWrite(motorUp, LOW);
  faderMax = analogRead(mainFaderPin) - tolerance;
  digitalWrite(motorDown, HIGH);
  analogWrite(motorPWM, motorSpeed);
  delay(300);
  digitalWrite(motorDown, LOW);
  faderMin = analogRead(mainFaderPin) + tolerance;
}

void loop() {
  int faderPos = analogRead(mainFaderPin);
  int totalCp =  touchSensor.capacitiveSensor(9);
  Control_Surface.loop();

  if ((faderPos == lastfaderPosition) && (totalCp <= minimumCp) && (incomingNote == 16)) {
    updateFader(incomingVelocity * 8);
    }

  if ((faderPos == lastfaderPosition) && (totalCp > minimumCp)) {
    midi.sendNoteOn({37, CHANNEL_2}, 127);
    digitalWrite(motorUp, LOW);
    digitalWrite(motorDown, LOW);
  }

  if (((faderPos < lastfaderPosition - 1) || (faderPos > lastfaderPosition + 1)) && (totalCp > minimumCp)) {
    digitalWrite(motorUp, LOW);
    digitalWrite(motorDown, LOW);
  }
  if (((faderPos < lastfaderPosition - 1) || (faderPos > lastfaderPosition + 1)) && (totalCp <=minimumCp)) {
// Stop Sending MIDI, and receive it only
  }
  lastfaderPosition = faderPos;
}

void updateFader(int position) {     //Function to move fader to a specific position between 0-1023 if it's not already there
  if (position < analogRead(mainFaderPin) - tolerance && position > faderMin) {
    digitalWrite(motorDown, HIGH);
    while (position < analogRead(mainFaderPin) - tolerance) {}; //Loops until motor is done moving
    digitalWrite(motorDown, LOW);
  }
  else if (position > analogRead(mainFaderPin) + tolerance && position < faderMax) {
    digitalWrite(motorUp, HIGH);
    while (position > analogRead(mainFaderPin) + tolerance) {}; //Loops until motor is done moving
    digitalWrite(motorUp, LOW);
  }
}

```

Note that when I use this version with an Arduino UNO, the whole thing works. I've tried discussing this with a few who are far more experienced than I, but surprisingly they were unable to provide insight as to why.

```
#include <SoftwareSerial.h> // MIDI Input
#include <MIDI.h> // MIDI Output
#include <CapacitiveSensor.h>

#define rxPin 0 // Input  (Grey)
#define txPin 1 // Output (Yellow)

SoftwareSerial midiSerial (rxPin, txPin);

const byte wiper        = 0; //Position of fader relative to GND (Analog 0)
const byte motorUp      = 4;
const byte motorDown    = 5;
const byte motorPWM     = 6;
const byte touchSend    = 7;//Send pin for Capacitance Sensing Circuit (Digital 7)
const byte touchReceive = 8; //Receive pin for Capacitance Sensing Circuit (Digital 8)
unsigned int incomingCommand;
unsigned int incomingNote;
unsigned int incomingVelocity;
byte motorSpeed = 150;  // Raise if the fader is too slow (0-255)
byte minimumCp  = 200; // Raise if the fader is too sensitive (0-16383)
byte tolerance  = 10;  // Raise if the fader is too shaky (0-1023)
double faderMax = 1023; //Value read by fader's maximum position (0-1023)
double faderMin = 0; //Value read by fader's minimum position (0-1023)
long lastDebounceTime = 0;  // the last time the output pin was toggled
long debounceDelay    = 15; // the debounce time; increase if the output flickers
int lastfaderValue    = 0;
int targetPosition;
byte ch1Vol = 176;
byte fullVel = 127;
byte ch_1 = 1;
byte Db_1 = 1;

CapacitiveSensor touch = CapacitiveSensor(touchReceive, touchSend);
MIDI_CREATE_DEFAULT_INSTANCE();

void setup() {
  touch.set_CS_AutocaL_Millis(0xFFFFFFFF);
  midiSerial.begin(31250);
  MIDI.begin();
  pinMode(motorDown, OUTPUT);
  pinMode(motorUp, OUTPUT);
  pinMode(motorPWM, OUTPUT);
  calibrateFader(); }

void calibrateFader() {
  digitalWrite(motorUp, HIGH);
  analogWrite(motorPWM, motorSpeed);
  delay(300);
  digitalWrite(motorUp, LOW);
  faderMax = analogRead(wiper) - tolerance;
  digitalWrite(motorDown, HIGH);
  analogWrite(motorPWM, motorSpeed);
  delay(300);
  digitalWrite(motorDown, LOW);
  faderMin = analogRead(wiper) + tolerance; }

void loop() {
  int faderPos = analogRead(wiper);
  int faderHiResMIDI = ((faderPos *16.0146627566) - 8191.5);

  while ( midiSerial.available()) {
    incomingCommand = midiSerial.read();
    incomingNote = midiSerial.read();
    incomingVelocity = midiSerial.read()*8.05511811024;
  if ((incomingVelocity  <=1023) && (incomingCommand >127) && (incomingNote <128)) {
    midiSerial.write(incomingCommand);
    midiSerial.write(incomingNote);
    midiSerial.write(incomingVelocity); } }

 { int totalCp =  touch.capacitiveSensor(30);
 if ( (millis() - lastDebounceTime) > debounceDelay) {
    if (totalCp <= minimumCp) {
      //if (incomingCommand == ch1Vol) {
        updateFader(incomingVelocity); }// }    // Not Touching fader
    if ((faderPos == lastfaderValue) && (totalCp > minimumCp)) {
      MIDI.sendNoteOn(Db_1, fullVel, ch_1); // Touching Fader
      digitalWrite(motorDown, LOW);
      digitalWrite(motorUp, LOW); }
    if (((faderPos > lastfaderValue+1) or (faderPos < lastfaderValue-1)) && (totalCp > minimumCp)) {   // Moving Fader
      MIDI.sendPitchBend(faderHiResMIDI, ch_1);
      digitalWrite(motorDown, LOW);
      digitalWrite(motorUp, LOW); }
    lastfaderValue = faderPos;
    lastDebounceTime = millis(); } } }

void updateFader(int position) {     //Function to move fader to a specific position between 0-1023 if it's not already there
  if (position < analogRead(wiper) - tolerance && position > faderMin) {
    digitalWrite(motorDown, HIGH);
    while (position < analogRead(wiper) - tolerance) {}; //Loops until motor is done moving
    digitalWrite(motorDown, LOW); }
  else if (position > analogRead(wiper) + tolerance && position < faderMax) {
    digitalWrite(motorUp, HIGH);
    while (position > analogRead(wiper) + tolerance) {}; //Loops until motor is done moving
    digitalWrite(motorUp, LOW); } }

```

# Answer
> 1 votes
**Firstly,** you need a robust way to synchronise to and parse MIDI messages which can be 1 byte, 2 bytes or 3 bytes or more... See this Summary of MIDI 1.0 Messages by the MIDI Association.

A good way to achieve this is by using a state machine. I've written a simple one below that parses 3-byte MIDI messages. It could be expanded to parse different types of commands.

```
typedef enum State
{
    Idle,
    Command,
    Data1
};

State state = State::Idle;

const float INCOMING_VELOCITY_SCALE = 1023.0 / 127.0;

byte incomingCommand;
byte incomingNote;
byte incomingVelocity;

int targetPosition;

void loop()
{
    if (midiSerial.available())  // Use the `if` statement to get the next available byte.
    {
        byte incoming = midiSerial.read();

        // Synchronise to and parse the 3-byte MIDI message packet, i.e. 1nnnnnnn 0nnnnnnn 0nnnnnnn
        switch (state)
        {
        case State::Idle:
            if (IsMidiCommand(incoming))
            {
                Serial.println("Received command byte.");
                incomingCommand = incoming;
                state = State::Command;
            }
            else if (IsMidiData(incoming))
            {
                Serial.println("Received data byte.");
            }
            break;
        case State::Command:
            if (IsMidiCommand(incoming))  // Double check for an out of sync command.
            {
                Serial.println("Received command byte.");
                incomingCommand = incoming;
                state = State::Command;
            }
            else if (IsMidiData(incoming))
            {
                Serial.println("Received data1 byte.");
                incomingNote = incoming;
                state = State::Data1;
            }
            break;
        case State::Data1:
            if (IsMidiCommand(incoming))  // Triple check for an out of sync command.
            {
                Serial.println("Received command byte.");
                incomingCommand = incoming;
                state = State::Command;
            }
            else if (IsMidiData(incoming))
            {
                Serial.println("Received data2 byte.");
                incomingVelocity = incoming;
                midiSerial.write(incomingCommand);
                midiSerial.write(incomingNote);
                midiSerial.write(incomingVelocity);
                Serial.write(incomingCommand);
                Serial.write(incomingNote);
                Serial.write(incomingVelocity);
                Serial.println();
                targetPosition = incomingVelocity * INCOMING_VELOCITY_SCALE;
                if (targetPosition > faderMax)      // Clip if out of bounds.
                {
                    targetPosition = faderMax;
                }
                else if (targetPosition < faderMin)
                {
                    targetPosition = faderMin;
                }
                state = State::Idle;
            }
            break;
        default:
            state = State::Idle;
            break;
        }
    }
    . . .
    updateFader(targetPosition);
    . . .
}

bool IsMidiCommand(const byte b)
{
    return b >= 128;  // For MIDI command bytes, MSB is 1.
}

bool IsMidiData(const byte b)
{
    return b <= 127;  // For MIDI data bytes, MSB is 0.
}

```

**Secondly,** there is an issue with the `updateFader()` function regarding the `tolerance`. It's `40` in your first version and `10` in your second version. Consider the following values for the variables:

```
// In setup()
digitalWrite(motorDown, HIGH);
analogWrite(motorPWM, motorSpeed);
delay(300);
faderMin = analogRead(wiper) + tolerance;
faderMin = 0                 + 40;         // Bottom of range.
faderMin = 40;

// In loop()
incomingVelocity = midiSerial.read() * 8.05511811024;
incomingVelocity = 1                 * 8.05511811024;  // A quiet note, e.g. between 0 and 5, will a give a value of 0 to 40.
incomingVelocity = 8;

// In updateFader()
if (position < analogRead(wiper) - tolerance && position > faderMin)
if (8        < 512               - 40        && 8        > 40      )
if (8        < 472                           && 8        > 40      )
if (true                                     && false              )
if (false                                                          )

```

Result: the fader will not budge if a quiet note is received that puts `position` below `faderMin` and will leave the fader jamming somewhere in the middle of its scale rather than boogieing on down to `faderMin`. This effect would be exaggerated if `faderMin` were higher than 40 when `analogRead(wiper)` reads greater than zero in `setup()`.

Similarly, this also happens with very loud notes and `faderMax` at the other end of the scale:

```
// In updateFader()
else if (position > analogRead(wiper) + tolerance && position < faderMax)

```

A better way would be to clip the `targetPosition` to the valid range before calling `updateFader()` and remove the second condition from the `if` statements in `updateFader()`:

```
targetPosition = incomingVelocity * INCOMING_VELOCITY_SCALE;
if (targetPosition > faderMax)      // Clip if out of bounds.
{
    targetPosition = faderMax;
}
else if (targetPosition < faderMin)
{
    targetPosition = faderMin;
}
. . .
updateFader(targetPosition);
. . .
if (position < analogRead(wiper) - tolerance)
. . .
else if (position > analogRead(wiper) + tolerance)
. . .

```

**Thirdly,** `updateFader()` blocks until the fader motor has finished moving. If notes are being received faster than the fader can move, the tempo will rallentando, so consider using a non-blocking style like Blink Without Delay.

**Fourthly,** `faderMin` and `faderMax` should be just that – the minimum and maximum extent of fader travel. But by adding/substracting `tolerance` from min/max it is unnecessarily reducing the range. The tolerance is effectively being doubled by adjusting for it in *both* `setup()` *and* `adjustFader()`. The extent of fader travel can be obtained by taking an average of several values in `calibrateFader()`. Then the tolerance can be adjusted for only once in `adjustFader()` as described above.

```
void calibrateFader()
{
    const byte NUM_SAMPLES = 10;
    digitalWrite(motorUp, HIGH);
    analogWrite(motorPWM, motorSpeed);
    delay(300);
    digitalWrite(motorUp, LOW);
    faderMax = AnalogueAverage(wiper, NUM_SAMPLES);
    Serial.println(faderMax);
    digitalWrite(motorDown, HIGH);
    analogWrite(motorPWM, motorSpeed);
    delay(300);
    digitalWrite(motorDown, LOW);
    faderMin = AnalogueAverage(wiper, NUM_SAMPLES);
    Serial.println(faderMin);
}

unsigned int AnalogueAverage(const byte pin, const byte num_samples)
{
    const byte ROUND_OFF = num_samples / 2;
    unsigned long total = 0;
    for (byte i = 0; i < num_samples; i++)
    {
        total += analogRead(pin);
    }
    return (total + ROUND_OFF) / num_samples;
}

```

# On a different note...

...I've been reading through the documentation and source code for the libraries you referenced in your code, which I think are these ones:

1. Control Surface
2. Arduino MIDI Library

These already implement the MIDI message parsing using callbacks, e.g.:

That example stresses the importance of swift non-blocking code. This means that `updateFader()` should also be non-blocking. You have the option to write your own custom state machine parser or use the libraries' parsers.

Here is how your code could be re-written to use the MIDI library's parser with non-blocking callbacks and non-blocking `updateFader()`. You may want to double-check which pins you are using for `midiSerial` because pins 0 and 1 are used for the default Serial monitor or you could use `MIDI.sendNoteOn()` and `MIDI.sendNoteOff()`.

```
#include <MIDI.h>

MIDI_CREATE_DEFAULT_INSTANCE();

unsigned int faderMax = 0;
unsigned int faderMin = 0;
unsigned int faderTargetPosition = 0;

void doNoteOn(byte channel, byte note, byte velocity)
{
    midiSerial.write(channel);
    midiSerial.write(note);
    midiSerial.write(velocity);
    faderTargetPosition = velocity * INCOMING_VELOCITY_SCALE;

    // Clip if out of bounds.
    if (faderTargetPosition > faderMax)
    {
        faderTargetPosition = faderMax;
    }
    else if (faderTargetPosition < faderMin)
    {
        faderTargetPosition = faderMin;
    }
}

void doNoteOff(byte channel, byte note, byte velocity)
{
    midiSerial.write(channel);
    midiSerial.write(note);
    midiSerial.write(velocity);
}

void setup()
{
    MIDI.setHandleNoteOn(doNoteOn);
    MIDI.setHandleNoteOff(doNoteOff);
    MIDI.begin(MIDI_CHANNEL_OMNI);
    . . .
}

void loop()
{
    // Parse the MIDI messages and call the callbacks.
    MIDI.read();

    if ((millis() - lastDebounceTime) > debounceDelay)
    {
        int totalCp = touch.capacitiveSensor(30);
        int faderPos = analogRead(FADER_PIN);
        int faderHiResMIDI = faderPos * 16.0146627566 - 8191.5;

        if (totalCp <= minimumCp)
        {
            // Not touching fader.
            //if (incomingCommand == ch1Vol)
            //{
            updateFader(faderTargetPosition);
            //}
        }
        else
        {
            if (faderPos == lastfaderValue)
            {
                // Touching fader.
                MIDI.sendNoteOn(Db_1, fullVel, ch_1);
                digitalWrite(MOTOR_DOWN_PIN, LOW);
                digitalWrite(MOTOR_UP_PIN, LOW);
            }
            else if ((faderPos > lastfaderValue + 1) or (faderPos < lastfaderValue - 1))
            {
                // Moving fader.
                MIDI.sendPitchBend(faderHiResMIDI, ch_1);
                digitalWrite(MOTOR_DOWN_PIN, LOW);
                digitalWrite(MOTOR_UP_PIN, LOW);
            }
        }
        lastfaderValue = faderPos;
        lastDebounceTime += debounceDelay;  // Constant interval.
    }
}

void updateFader(const unsigned int& faderTargetPosition)
{
    const unsigned int currentPosition = analogRead(FADER_PIN);
    if (faderTargetPosition < currentPosition - tolerance)      // Below the tolerance band.
    {
        digitalWrite(MOTOR_UP_PIN, LOW);                        // Switch the up control off before switching the down control on.
        digitalWrite(MOTOR_DOWN_PIN, HIGH);
    }
    else if (faderTargetPosition > currentPosition + tolerance) // Above the tolerance band.
    {
        digitalWrite(MOTOR_DOWN_PIN, LOW);                      // Switch the down control off before switching the up control on.
        digitalWrite(MOTOR_UP_PIN, HIGH);
    }
    else                                                        // Within the tolerance band.
    {
        digitalWrite(MOTOR_DOWN_PIN, LOW);
        digitalWrite(MOTOR_UP_PIN, LOW);
    }
}

```

---
Tags: motor, arduino-leonardo, potentiometer, midi
---


title: Proteus - How to Debug Invalid Opcode?

text:
# Question
Title: Proteus - How to Debug Invalid Opcode?
While running a program compiled in the Arduino IDE 1.8.5 and then using the `.ELF` file inside *LabCenter Proteus 8.0*, for an *Arduino Nano* *ATMEL Mega 328P*, for a code involving the use of the `SoftwareSerial.h` Library, hence involving several loops, without user interaction, I am getting the following error:

```
Invalid opcode 0x0024 at PC=0x0096

```

Now I am completely lost. According the AVR Instruction Set Manual such opcode should (not sure about this?) be *RETI - Return From Interrupt* at the Program Line (?) no.150 = 0x096. The full code has 779 lines plus several library calls, and the line 150 happens to fall just before the `loop()` function (?), which should never repeat, being just a declaration.

So, how should I debug this error? Evidently I am not asking to solve the problem for me but, how should I proceed for debugging it and find the real error?

I have been unable to find in Proteus a tool for "Debug Stop if Error"

I have been unable to isolate the error in a simple way to share. It should be related someway with interruptions used by the library `SoftwareSerial.h`, because at some modifications of the program, the code freezes at an interruption return. I am working on that, but advancing really slowly actually.

Related question No.1.

# Answer
> 2 votes
First: Use the ino.hex file instead of the .ELF file Second: this error is showing because you are compiling your code with a different board. Make sure you are using the correct board over at the Arduino IDE. My advice is: switch your board to Arduino Uno both in proteus and over at the Arduino IDE and see if it works. Later on, you can try different boards.

# Answer
> 2 votes
Guys if you are facing the error of invalid opcode 0xffff at pc = 0x3e402 in proteus using Arduino, the GO to Arduino IDE software, and from the top menu, click on 'tool' and change the board type, e.g., Arduino UNO to Arduino Mega 2560.

---
Tags: arduino-nano, debugging
---


# Question
Title: Arduino Serial Monitor Input 3DES Encryption
I am trying to 3DES encryption using Serial Read, Found this 3DES Sample code in Github,

```
#include <DES.h>
DES des;
void setup() {
  Serial.begin(9600);
  Serial.println("Hello!");
}
void loop() {
  desTest();
  tdesTest();
  delay(2000);
}
void desTest()
{
  byte out[8];
  byte in[] = { 1, 2, 3, 4, 5, 6, 7, 8 };
  byte key[] = { 0x3b, 0x38, 0x98, 0x37, 0x15, 0x20, 0xf7, 0x5e };

  Serial.println();
  Serial.println("========= DES test ==========");

  //encrypt
  Serial.print("Encrypt...");
  unsigned long time = micros();
  des.encrypt(out, in, key);
  time = micros() - time;
  Serial.print("done. (");
  Serial.print(time);
  Serial.println(" micros)");
  printArray(out);

  //decrypt
  for (int i = 0; i < 8; i++)
  {
    in[i] = out[i];
  }
  Serial.print("Decrypt...");
  time = micros();
  des.decrypt(out, in, key);
  time = micros() - time;
  Serial.print("done. (");
  Serial.print(time);
  Serial.println(" micros)");
  printArray(out);
}
void tdesTest()
{
  byte out[8];
  byte in[] = { 1, 2, 3, 4, 5, 6, 7, 8 };
  byte key[] = {
                  0x3b, 0x38, 0x98, 0x37, 0x15, 0x20, 0xf7, 0x5e, // key A
                  0x92, 0x2f, 0xb5, 0x10, 0xc7, 0x1f, 0x43, 0x6e, // key B
                  0x3b, 0x38, 0x98, 0x37, 0x15, 0x20, 0xf7, 0x5e, // key C (in this case A)
                };

  Serial.println();
  Serial.println("====== Triple-DES test ======");

  //encrypt
  Serial.print("Encrypt...");
  unsigned long time = micros();
  des.tripleEncrypt(out, in, key);
  time = micros() - time;
  Serial.print("done. (");
  Serial.print(time);
  Serial.println(" micros)");
  printArray(out);

  //decrypt
  for (int i = 0; i < 8; i++)
  {
    in[i] = out[i];
  }
  Serial.print("Decrypt...");
  time = micros();
  des.tripleDecrypt(out, in, key);
  time = micros() - time;
  Serial.print("done. (");
  Serial.print(time);
  Serial.println(" micros)");
  printArray(out);
}
void printArray(byte output[])
{
  for (int i = 0; i < 8; i++)
  {
    if (output[i] < 0x10)
    {
      Serial.print("0");
    }
    Serial.print(output[i], HEX);
    Serial.print(" ");
  }
  Serial.println();
}

```

I want to get user serial input from Serial Monitor to feed `byte in[]`. Which will encrypt user input, I will pad user input to 8 Bytes or restrict input to 8.

Library: https://github.com/Octoate/ArduinoDES

Could any one help me to get data from user input.

**Edit 1: I was able to read the String to char and feed to `byte in[]` changed the code,**

```
#include <DES.h>
DES des;

String  input;

char buf[30];
void setup() {
  Serial.begin(9600);
  Serial.println("Hello!");

}

void printArray(byte output[])
{
  for (int i = 0; i < 8; i++)
  {
    if (output[i] < 0x10)
    {
      Serial.print("0");
    }
    Serial.print(output[i], HEX);
    Serial.print(" ");
  }
  Serial.println();
}
void loop() {

  while (Serial.available() > 0) {

    String  input = Serial.readString(); // read the incoming data as string
    char buf[30];
/*
    input.toCharArray(buf, 9);
    Serial.println(buf);
*/
    input.toCharArray(buf, input.length() + 1);
    Serial.println(buf);

    byte out[8];
    byte in[] = {buf};
    Serial.println(buf);
    byte key[] = {
      0x3b, 0x38, 0x98, 0x37, 0x15, 0x20, 0xf7, 0x5e, // key A
      0x92, 0x2f, 0xb5, 0x10, 0xc7, 0x1f, 0x43, 0x6e, // key B
      0x3b, 0x38, 0x98, 0x37, 0x15, 0x20, 0xf7, 0x5e, // key C (in this case A)
    };

    Serial.println();
    Serial.println("====== Triple-DES test ======");

    //encrypt
    Serial.print("Encrypt...");
    unsigned long time = micros();
    des.tripleEncrypt(out, in, key);
    time = micros() - time;
    Serial.print("done. (");
    Serial.print(time);
    Serial.println(" micros)");
    printArray(out);

    //decrypt
    for (int i = 0; i < 8; i++)
    {
      in[i] = out[i];
    }
    Serial.print("Decrypt...");
    time = micros();
    des.tripleDecrypt(out, in, key);
    time = micros() - time;
    Serial.print("done. (");
    Serial.print(time);
    Serial.println(" micros)");
    printArray(out);
    delay(2000);
  }

}

```

But I don't think getting the correct, Please find the below,

But when I feed manually like below,

```
...
input.toCharArray(buf, input.length() + 1);
    Serial.println(buf);

    //tdesTest();
    byte out[8];
    byte in[] = {"12345678"}; //Manually feeding hardcoding the value need to get the value from serial read to here
    Serial.println(buf);
    byte key[] = {
      0x3b, 0x38, 0x98, 0x37, 0x15, 0x20, 0xf7, 0x5e, // key A
      0x92, 0x2f, 0xb5, 0x10, 0xc7, 0x1f, 0x43, 0x6e, // key B
      0x3b, 0x38, 0x98, 0x37, 0x15, 0x20, 0xf7, 0x5e, // key C (in this case A)
    };

    Serial.println();
    Serial.println("====== Triple-DES test ======");
...

```

I get the expected output,

# Answer
From your comments I *think* I understand what you are after. So, assuming you have read some string into a `String` object called `input` and you have an array `in[8]` to populate you can:

1. Clear the `in[]` array to a preset state
2. Copy the string content into `in[]`

As code:

```
memset(in, 0, 8); // Erase the contents of in[]
input.toCharArray((char *)in, 8); // Copy up to 8 bytes from the string

```
> 1 votes

# Answer
```
#include <DES.h>
DES des;
byte in[8];
String  input;

char buf[30];
void setup() {
  Serial.begin(9600);
  Serial.println("Hello!");

}

void tdesTest() {
  byte out[8];

  byte key[] = {
    0x3b, 0x38, 0x98, 0x37, 0x15, 0x20, 0xf7, 0x5e, // key A
    0x92, 0x2f, 0xb5, 0x10, 0xc7, 0x1f, 0x43, 0x6e, // key B
    0x3b, 0x38, 0x98, 0x37, 0x15, 0x20, 0xf7, 0x5e, // key C (in this case A)
  };

  Serial.println();
  Serial.println("====== Triple-DES test ======");

  //encrypt
  Serial.print("Encrypt...");
  unsigned long time = micros();
  des.tripleEncrypt(out, in, key);
  time = micros() - time;
  Serial.print("done. (");
  Serial.print(time);
  Serial.println(" micros)");
  printArray(out);

  //decrypt
  for (int i = 0; i < 8; i++)
  {
    in[i] = out[i];
  }
  Serial.print("Decrypt...");
  time = micros();
  des.tripleDecrypt(out, in, key);
  time = micros() - time;
  Serial.print("done. (");
  Serial.print(time);
  Serial.println(" micros)");
  printArray(out);
  delay(2000);
}

void printArray(byte output[])
{
  for (int i = 0; i < 8; i++)
  {
    if (output[i] < 0x10)
    {
      Serial.print("0");
    }
    Serial.print(output[i], HEX);
    Serial.print(" ");
  }
  Serial.println();
}

void loop() {

  while (Serial.available() > 0) {

    String  input = Serial.readString(); // read the incoming data as string
    memset(in, 0, 9); // Erase the contents of in[]
    input.toCharArray((char *)in, 9); // Copy up to 8 bytes from the string
    tdesTest();

  }
}

```
> 1 votes

---
Tags: serial, arduino-nano, array, bytes
---


title: DHT11 humidity and temperature sensor

text:
# Question
Title: DHT11 humidity and temperature sensor
**Hello. I've got a question about DHT11 sensor. Why should pullup resistor be connected as on the image below:**

**while as far as I know, pullup resistor should be placed between Arduino 5V pin and Vcc of sensor as shown here:**

**PS: I know that there is a wrong icon of DHT11, but I couldn't find a correct one.**

# Answer
> 8 votes
You require a pullup resistor between the data wire and VCC because the DHT11 uses a bidirectional communication system on a single wire. When neither end is communicating both ends of the link will be in "high impedance" mode - i.e., input mode. In that case the signal will be "floating" and needs the pullup to keep it in a known state.

When actively communicating the outputs switch to "open drain" mode to allow then to pull the signal low against the pull of the pullup resistor.

A resistor in series with the Arduino's 5V and the VCC of the DHT11 is *not* a pullup resistor. It is not an arrangement that you would ever want, since it would make the voltage to the DHT11 unstable.

---
Tags: dht11
---


# Question
Title: Pass Byte Array to Char and Send to a Separate Arduino
I am trying to send data between Arduino Nano and D1 Mini (ESP 8266 Module)

*My Code as below in Nano which will be the transmeting ,*

```
#include <DES.h>
#include <SoftwareSerial.h>
SoftwareSerial link(2, 3); // Rx, Tx
DES des;
byte in[8];
String  input;
char text[20];
char charVal[6];

char buf[30];
void setup() {
  link.begin(9600);
  Serial.begin(9600);
  Serial.println("Hello! Pleace Enter Your Data to Encrypt");

}

void tdesTest() {
  byte out[8];
  byte key[] = {
    0x3b, 0x38, 0x98, 0x37, 0x15, 0x20, 0xf7, 0x5e, // key A
    0x92, 0x2f, 0xb5, 0x10, 0xc7, 0x1f, 0x43, 0x6e, // key B
    0x3b, 0x38, 0x98, 0x37, 0x15, 0x20, 0xf7, 0x5e, // key C (in this case A)
  };

  Serial.println();
  Serial.println("====== Triple-DES test ======");

  //encrypt
  Serial.print("Encrypt...");
  unsigned long time = micros();
  des.tripleEncrypt(out, in, key);
  time = micros() - time;
  Serial.print("done. (");
  Serial.print(time);
  Serial.println(" micros)");
  printArray(out);
  /*
    //decrypt
    for (int i = 0; i < 8; i++)
    {
      in[i] = out[i];
    }
    Serial.print("Decrypt...");
    time = micros();
    des.tripleDecrypt(out, in, key);
    time = micros() - time;
    Serial.print("done. (");
    Serial.print(time);
    Serial.println(" micros)");
    printArray(out);
    delay(2000);
  */
}

//printing output
void printArray(byte output[])
{
  for (int i = 0; i < 8; i++)
  {
    if (output[i] < 0x10)
    {
      Serial.print("0");
    }
    Serial.print(output[i], HEX);
    Serial.print(" ");
    delay(100);

  }
  Serial.println();

}

void loop() {

  while (Serial.available() > 0) {

    String  input = Serial.readString(); // read the incoming data as string
    memset(in, 0, 9); // Erase the contents of in[]
    input.toCharArray((char *)in, 9); // Copy up to 8 bytes from the string
    tdesTest();

  }
}

```

In `printArray(byte output[])`I am getting Output as `HEX` Byte as below

**I am trying to send the this encrypted data to from Arduino nano to D1 Mini,**

I have wrote a small Receiver Application in D1 Mini and It works , *Receiver Code:*

```
//Receiver code
#include <SoftwareSerial.h>
SoftwareSerial link(4, 0); // Rx, Tx

byte greenLED = 13;
char cString[2000];
byte chPos = 0;
byte ch = 0;
char dataStr[6];

void setup()
{
  link.begin(9600); //setup software serial
  Serial.begin(9600);    //setup serial monitor
  pinMode(greenLED, OUTPUT);
}

void loop()
{

  while (link.available())
  {
    ESP.wdtDisable();

    //read incoming char by char:
    ch = link.read();
    cString[chPos] = ch;
    chPos++;

    digitalWrite(greenLED, HIGH); //flash led to show data is arriving
    delay(20);
    digitalWrite(greenLED, LOW);

  }

  cString[chPos] = 0; //terminate cString
  chPos = 0;

  Serial.print(cString);
  ESP.wdtEnable(1);
  Serial.flush();

}

```

**I want to pass this HEX data Generated to D1 Mini from Arduino Nano,**

I have wrote test code in Arduino Nano for *Transmitter*(Nano) and between *Receiver* (D1 Mini) it works,

```
//Transmitter Code for Testing Connections
#include <SoftwareSerial.h>
SoftwareSerial link(2, 3); // Rx, Tx
byte greenLED = 12;
char text[20] ;
char charVal[6];

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

}

void loop()
{
  strcat(text, "Message"); //append to empty string
  Serial.println(text); //print to local screen for debug*
  link.println(text);

  delay(10000);
}

```

Please help me to send this **`HEX`** data in single shot to D1 Mini.

# Answer
You can change your `printArray` function to work on provided `Print` instance:

```
void printArray(byte output[], Print& serial)
{
  for (int i = 0; i < 8; i++)
  {
    if (output[i] < 0x10)
    {
      serial.print("0");
    }
    serial.print(output[i], HEX);
    serial.print(" ");
  }
  serial.println();

}

```

then you can use it as `printArray(out, Serial);` or `printArray(out, link);`.
> 1 votes

---
Tags: esp8266, arduino-nano, softwareserial, bytes
---


# Question
Title: Artefacts on display when adding seemingly unrelated code
I have this simple program, where I am implementing a menu structure on an OLED display and a rotary encoder.

The code works functionally as intended, however when I add more menu items, then I get some artefacts on the display, in the lower right corner (see screenshots). The code that I am referring to is inside the block comment in `initMenu()`. When I uncomment that block, the artefacts start appearing, every other time I turn the knob on the encoder. Sometimes it temporarily disappears, or slightly changes its shape.

As I said, other than that, the code behaves as expected.
Could anyone maybe shed some light on why this happens?

```
#define DEBUG 1

// Display
#include "Adafruit_GFX.h"
#include "Adafruit_SSD1306.h"
#define OLED_RESET -1
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
Adafruit_SSD1306 display;

// Rotary encoder
#include "RotaryEncoder.h"
#include "YetAnotherPcInt.h"
#define RTRY_ENC_SW A1
#define RTRY_ENC_CLK A2
#define RTRY_ENC_DT A3
RotaryEncoder encoder(RTRY_ENC_CLK, RTRY_ENC_DT);
void onSwitch();
void onRotate();

typedef struct MenuItem {
  String name;
  byte id = 0;
  boolean active = false;
  MenuItem* prevSibling;
  MenuItem* nextSibling;
  MenuItem* currentChild;
};

MenuItem autoModes;
MenuItem manualModes;
MenuItem settings;
MenuItem peakAverage;
MenuItem peakToPeak;
MenuItem rms;

MenuItem* currentItem;
MenuItem* activeMode;

void setup() {
#ifdef DEBUG
  Serial.begin(115200);
#endif
  initEncoder();
  initMenu();
  initDisplay();
}

boolean hasInputs = false;
boolean switchPressed = false;

void loop() {
  if (hasInputs == true) {
    hasInputs = false;
    handleButtonInputs();
  }
}

void initEncoder() {
  pinMode(RTRY_ENC_SW, INPUT_PULLUP);
  PcInt::attachInterrupt(RTRY_ENC_SW, onSwitch, FALLING);
  PcInt::attachInterrupt(RTRY_ENC_CLK, onRotate, CHANGE);
  PcInt::attachInterrupt(RTRY_ENC_DT, onRotate, CHANGE);
}

void initMenu() {
  autoModes.name = "Auto";
  autoModes.id = 1;
  autoModes.active = true;
  autoModes.prevSibling = &settings;
  autoModes.nextSibling = &manualModes;
  autoModes.currentChild = &peakAverage;

  manualModes.name = "Manual";
  manualModes.id = 2;
  manualModes.prevSibling = &autoModes;
  manualModes.nextSibling = &settings;

  settings.name = "Config";
  settings.id = 3;
  settings.prevSibling = &manualModes;
  settings.nextSibling = &autoModes;
/*
  peakAverage.name = "PAvg";
  peakAverage.id = 4;
  peakAverage.active = true;
  peakAverage.prevSibling = &rms;
  peakAverage.nextSibling = &peakToPeak;

  peakToPeak.name = "P2P";
  peakToPeak.id = 5;
  peakToPeak.prevSibling = &peakAverage;
  peakToPeak.nextSibling = &rms;

  rms.name = "RMS";
  rms.id = 6;
  rms.prevSibling = &peakToPeak;
  rms.nextSibling = &peakAverage;

  activeMode = &peakAverage;
*/
  currentItem = &autoModes;
}

void initDisplay() {
  display = Adafruit_SSD1306(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
  display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
  display.clearDisplay();
  display.setCursor(36, 24);
  display.setTextSize(2);
  display.setTextColor(1);
  display.print("Hello");
  display.display();
}

void handleButtonInputs() {
  if (switchPressed) {
    switchPressed = false;
    if (currentItem->id <= 3) {
      currentItem = currentItem->currentChild;
      printMenu();
    } else if (4 <= currentItem->id && currentItem->id <= 6) {
      if (activeMode->id != currentItem->id) {
        activeMode->active = false;
        currentItem->active = true;
        activeMode = currentItem;
      }
      currentItem = &autoModes;
      printMenu();
    }
  }

  RotaryEncoder::Direction direction = encoder.getDirection();
  if (direction == RotaryEncoder::Direction::CLOCKWISE) {
#ifdef DEBUG
    Serial.println("clockwise");
#endif
    currentItem = currentItem->nextSibling;
    printMenu();
  } else if (direction == RotaryEncoder::Direction::COUNTERCLOCKWISE) {
#ifdef DEBUG
    Serial.println("counterclockwise");
#endif
    currentItem = currentItem->prevSibling;
    printMenu();
  } else if (direction == RotaryEncoder::Direction::NOROTATION ) {
#ifdef DEBUG
    Serial.println("no rotation");
#endif
    // ?
  }
}

void printMenu() {
#ifdef DEBUG
  Serial.println(currentItem->prevSibling->name);
#endif
  display.clearDisplay();
  display.setTextSize(2);
  Serial.println(currentItem->prevSibling->name);
  int x1 = 64 - currentItem->prevSibling->name.length() * 6;
  if (currentItem->prevSibling->active) {
    display.setTextColor(0, 1);
    display.fillRect(x1 - 2, 0, 2, 16, 1);
  } else {
    display.setTextColor(1, 0);
  }
  display.setCursor(x1, 0);
  display.print(currentItem->prevSibling->name);
#ifdef DEBUG
  Serial.println(currentItem->name);
#endif
  int x2 = 64 - currentItem->name.length() * 6;
  int width = currentItem->name.length() * 12 + 10;
  if (currentItem->active) {
    display.setTextColor(0, 1);
    display.fillRect(x2 - 6, 19, width, 24, 1);
  } else {
    display.setTextColor(1, 0);
    display.drawRect(x2 - 6, 19, width, 24, 1);
  }
  display.setCursor(x2, 23);
  display.print(currentItem->name);
#ifdef DEBUG
  Serial.println(currentItem->nextSibling->name);
#endif
  int x3 = 64 - currentItem->nextSibling->name.length() * 6;
  if (currentItem->nextSibling->active) {
    display.setTextColor(0, 1);
    display.fillRect(x3 - 2, 47, 2, 16, 1);
  } else {
    display.setTextColor(1, 0);
  }
  display.setCursor(x3, 47);
  display.print(currentItem->nextSibling->name);
  display.display();
}

void onSwitch() {
  hasInputs = true;
  switchPressed = true;
}

void onRotate() {
  hasInputs = true;
  encoder.tick();
}

```

This is the output of the compilation process regarding program size:

```
Sketch uses 18198 bytes (59%) of program storage space. Maximum is 30720 bytes.
Global variables use 827 bytes (40%) of dynamic memory, leaving 1221 bytes for local variables. Maximum is 2048 bytes.

```

# Answer
> 0 votes
Thanks for the comments about memory usage, I was able to solve this specific problem.

I have updated my program, and optimized it by splitting up the menu rendering, using smaller variable sizes where possible, and putting all Strings to PROGMEM using the `F()` macro. I also had a look at this page https://learn.adafruit.com/memories-of-an-arduino/measuring-free-memory and copied `freeMemory()` from there:

```
#define DEBUG 1
#define DEBUG_MEMORY 1

// Display
#include "Adafruit_GFX.h"
#include "Adafruit_SSD1306.h"
#define OLED_RESET -1
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
Adafruit_SSD1306 display;

// Rotary encoder
#include "RotaryEncoder.h"
#include "YetAnotherPcInt.h"
#define RTRY_ENC_SW A1
#define RTRY_ENC_CLK A2
#define RTRY_ENC_DT A3
RotaryEncoder encoder(RTRY_ENC_CLK, RTRY_ENC_DT);
void onSwitch();
void onRotate();

typedef struct MenuItem {
  String name;
  byte id = 0;
  boolean active = false;
  MenuItem* prevSibling;
  MenuItem* nextSibling;
  MenuItem* currentChild;
};

MenuItem autoModes;
MenuItem manualModes;
MenuItem settings;
MenuItem peakAverage;
MenuItem peakToPeak;
MenuItem rms;

MenuItem* currentItem;
MenuItem* activeMode;

#ifdef DEBUG_MEMORY
#ifdef __arm__
// should use uinstd.h to define sbrk but Due causes a conflict
extern "C" char* sbrk(int incr);
#else  // __ARM__
extern char *__brkval;
#endif  // __arm__

int freeMemory() {
  char top;
#ifdef __arm__
  return &top - reinterpret_cast<char*>(sbrk(0));
#elif defined(CORE_TEENSY) || (ARDUINO > 103 && ARDUINO != 151)
  return &top - __brkval;
#else  // __arm__
  return __brkval ? &top - __brkval : &top - __malloc_heap_start;
#endif  // __arm__
}
#endif

void setup() {
#ifdef DEBUG
  Serial.begin(115200);
#endif
  initEncoder();
  initMenu();
  initDisplay();
}

boolean hasInputs = false;
boolean switchPressed = false;

void loop() {
  if (hasInputs == true) {
    hasInputs = false;
    handleButtonInputs();
  }
}

void initEncoder() {
  pinMode(RTRY_ENC_SW, INPUT_PULLUP);
  PcInt::attachInterrupt(RTRY_ENC_SW, onSwitch, FALLING);
  PcInt::attachInterrupt(RTRY_ENC_CLK, onRotate, CHANGE);
  PcInt::attachInterrupt(RTRY_ENC_DT, onRotate, CHANGE);
}

void initMenu() {
  autoModes.name = F("Auto");
  autoModes.id = 1;
  autoModes.active = true;
  autoModes.prevSibling = &settings;
  autoModes.nextSibling = &manualModes;
  autoModes.currentChild = &peakAverage;

  manualModes.name = F("Manual");
  manualModes.id = 2;
  manualModes.prevSibling = &autoModes;
  manualModes.nextSibling = &settings;

  settings.name = F("Config");
  settings.id = 3;
  settings.prevSibling = &manualModes;
  settings.nextSibling = &autoModes;

  peakAverage.name = F("PAvg");
  peakAverage.id = 4;
  peakAverage.active = true;
  peakAverage.prevSibling = &rms;
  peakAverage.nextSibling = &peakToPeak;

  peakToPeak.name = F("P2P");
  peakToPeak.id = 5;
  peakToPeak.prevSibling = &peakAverage;
  peakToPeak.nextSibling = &rms;

  rms.name = F("RMS");
  rms.id = 6;
  rms.prevSibling = &peakToPeak;
  rms.nextSibling = &peakAverage;

  activeMode = &peakAverage;
  currentItem = &autoModes;
}

void initDisplay() {
  display = Adafruit_SSD1306(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
  display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
  display.clearDisplay();
  display.setCursor(36, 24);
  display.setTextSize(2);
  display.setTextColor(1);
  display.print(F("Hello"));
  display.display();
}

void handleButtonInputs() {
  if (switchPressed) {
    switchPressed = false;
    if (currentItem->id <= 3) {
      currentItem = currentItem->currentChild;
      renderMenu();
    } else if (4 <= currentItem->id && currentItem->id <= 6) {
      if (activeMode->id != currentItem->id) {
        activeMode->active = false;
        currentItem->active = true;
        activeMode = currentItem;
      }
      currentItem = &autoModes;
      renderMenu();
      #ifdef DEBUG_MEMORY
        Serial.println(freeMemory());
      #endif
    }
  }

  RotaryEncoder::Direction direction = encoder.getDirection();
  if (direction == RotaryEncoder::Direction::CLOCKWISE) {
#ifdef DEBUG
    Serial.println(F("cw"));
#endif
    currentItem = currentItem->nextSibling;
    renderMenu();
  } else if (direction == RotaryEncoder::Direction::COUNTERCLOCKWISE) {
#ifdef DEBUG
    Serial.println(F("ccw"));
#endif
    currentItem = currentItem->prevSibling;
    renderMenu();
  } else if (direction == RotaryEncoder::Direction::NOROTATION ) {
#ifdef DEBUG
    Serial.println(F("nr"));
#endif
    // ?
  }
}

void renderMenu() {
  display.clearDisplay();
  printPrevSibling();
  printCurrentItem();
  printNextSibling();
#ifdef DEBUG_MEMORY
  Serial.println(freeMemory());
#endif
  display.display();
}

void printPrevSibling() {
#ifdef DEBUG
  Serial.println(currentItem->prevSibling->name);
#endif
  display.setTextSize(2);
  Serial.println(currentItem->prevSibling->name);
  byte x1 = 64 - currentItem->prevSibling->name.length() * 6;
  if (currentItem->prevSibling->active) {
    display.setTextColor(0, 1);
    display.fillRect(x1 - 2, 0, 2, 16, 1);
  } else {
    display.setTextColor(1, 0);
  }
  display.setCursor(x1, 0);
  display.print(currentItem->prevSibling->name);
}

void printCurrentItem() {
#ifdef DEBUG
  Serial.println(currentItem->name);
#endif
  byte x2 = 64 - currentItem->name.length() * 6;
  byte width = currentItem->name.length() * 12 + 10;
  if (currentItem->active) {
    display.setTextColor(0, 1);
    display.fillRect(x2 - 6, 19, width, 24, 1);
  } else {
    display.setTextColor(1, 0);
    display.drawRect(x2 - 6, 19, width, 24, 1);
  }
  display.setCursor(x2, 23);
  display.print(currentItem->name);
}

void printNextSibling() {
#ifdef DEBUG
  Serial.println(currentItem->nextSibling->name);
#endif
  byte x3 = 64 - currentItem->nextSibling->name.length() * 6;
  if (currentItem->nextSibling->active) {
    display.setTextColor(0, 1);
    display.fillRect(x3 - 2, 47, 2, 16, 1);
  } else {
    display.setTextColor(1, 0);
  }
  display.setCursor(x3, 47);
  display.print(currentItem->nextSibling->name);
}

void onSwitch() {
  hasInputs = true;
  switchPressed = true;
}

void onRotate() {
  hasInputs = true;
  encoder.tick();
}

```

Now the size is like this:

```
Sketch uses 18588 bytes (60%) of program storage space. Maximum is 30720 bytes.
Global variables use 761 bytes (37%) of dynamic memory, leaving 1287 bytes for local variables. Maximum is 2048 bytes.

```

However the improvement is not that great, and I am still left wondering, when the next problem will arise. I am still thankful for further insights besides using a bigger controller, because I am not quite done yet on this one.

If anyone has more ways for me to improve this program without sacrificing performance, as I will be adding a radio, and a microphone, I will accept that as an answer over this one.

---
Tags: programming, library, display, rotary-encoder, oled
---


title: Arduino Core for the Raspberry Pi Pico

text:
# Question
Title: Arduino Core for the Raspberry Pi Pico
I recently bought a Raspberry Pi Pico to play with, and am attempting to upload my first program to it *the Arduino way*, as my own operating system rather than a c++ program over an existing operating system (meaning to replace the built-in Raspberry Pi Pico operating system which runs MicroPython, not in the sense of running Linux, Windows, Mac, or any derivative or fork). I have not found any record of people hacking it like that - is it possible? If so, how would I go about it? Sorry if this is in the wrong Stack Exchange.

# Answer
> 3 votes
## Official support.

Apparently there's official support for it, now anyway.

I was digging around in the Arduino-mbed core, trying to help someone else, specifically in the boards.txt and spied the line:

> pico.name=Raspberry Pi Pico

Unfortunately, I don't have any way to give it a proper test as I don't have one of these. But I did go so far as to install the core and compile a simple hello world program.

## In boards manager

Search for "mbed rp2040"; these names sometimes change, but those terms work well now. You can see in the lower item, I have version 2.0.0 installed.

## Board menu selection

`Tools`/`Board`/`Arduino Mbed OS RP2040`/`Raspberry Pi Pico`

## Seems to work.

As you see it at least builds without error. As I said, I'm unable to give it a real test. But that at least looks promising.

# Answer
> 2 votes
Here is the library for the Arduino IDE and a Raspberry Pi pico.

https://github.com/lrusak/Arduino-Core-Pico

Just install normally as a .zip.

# Answer
> 2 votes
It is worth mentioning this excellent alternative to the Arduino one from Earle F. Philhower. It seems well-maintained and doesn't depend on Mbed OS, so it leaves more space (ram and flash) for your application.

Here an informal comparative list.

---
Tags: raspberrypi
---


# Question
Title: Arduino 5v pin outputting lower power than expected
I have hooked the pin v5 of an Arduino Nano 33 BLE to the A0 pin and measured the value by doing `Serial.println(analogRead(A0));`. I would expect to see 1023 however instead I see the value oscillating around 810.

Any ideas why I am not getting 1023?

P.S.: I am powering the Arduino board through the USB connector.

# Answer
Well, I thought by now someone else would have answered it. But, I'll try. I'm not familiar with this chip and board, so what I can tell you is pretty limited.

In short, you have a 3.3V micro-controller and generally speaking you don't hook 5V signals to them. There are some 3.3V parts that have "5V tolerant" inputs, but that only makes sense for digital inputs so far as I know.

Barring anything unpleasant happening, the behaviour I would expect to see with hooking 5V to the input of a 3.3V ADC is that it would clip at the high end value. So yeah, for 10-bit resolution, which appears to be the default for the Nano 33 BLE and with VDD as the reference, which also appears to be the default, I would expect to see a value at or near 1023. Up until the point that you fry something that is.

I don't know why you're seeing lower values, but since you seem to be operating it out of specifications, I'm not sure that really matters why. If you want to measure 5V with your 3.3V max ADC, you should involve a voltage divider.
> 1 votes

---
Tags: voltage-level, arduino-nano-ble
---


# Question
Title: How to run a sketch for a period (e.g. 1min) and then attiny85 goes to sleepmode automaticaly?
Another beginner to arduino device. My knowledge for programming is so weak. As i mention to the title i would like your help. I just want to run this simple sketch into attiny85 for lets say 1 min and then chip goes to sleepmode by its own. My code is below but i cannot manage to achive what i want. Any help? Many thanks.

```
void setup() {

  pinMode(0, OUTPUT);
  pinMode(1, OUTPUT);
  pinMode(2, OUTPUT);
  pinMode(3, OUTPUT);
  pinMode(4, OUTPUT);

}

void loop() {

                              // put your main code here, to run repeatedly:
  pinMode(0, OUTPUT);
  pinMode(1, OUTPUT);
  pinMode(2, OUTPUT);
  pinMode(3, OUTPUT);
  pinMode(4, OUTPUT);

  digitalWrite(0, HIGH);
  digitalWrite(1, LOW);  // 1
  digitalWrite(2, LOW);
  digitalWrite(3, LOW);
  digitalWrite(4, LOW);
  delay(180);
  digitalWrite(0, LOW);
  digitalWrite(1, HIGH);   // 2
  digitalWrite(2, LOW);
  digitalWrite(3, LOW);
  digitalWrite(4, LOW);
  delay(180);
  digitalWrite(0, LOW);
  digitalWrite(1, LOW);      //3
  digitalWrite(2, HIGH);
  digitalWrite(3, LOW);
  digitalWrite(4, LOW);
  delay(180);
  digitalWrite(0, LOW);
  digitalWrite(1, LOW);   //4
  digitalWrite(2, INPUT);
  digitalWrite(3, HIGH);
  digitalWrite(4, LOW);
  delay(180);
  digitalWrite(0, LOW);
  digitalWrite(1, LOW);   //5
  digitalWrite(2, LOW);
  digitalWrite(3, LOW);
  digitalWrite(4, HIGH);
  delay(180);
  digitalWrite(0, LOW);
  digitalWrite(1, LOW);   //4
  digitalWrite(2, INPUT);
  digitalWrite(3, HIGH);
  digitalWrite(4, LOW);
  delay(180);
  digitalWrite(0, LOW);
  digitalWrite(1, LOW);     //3
  digitalWrite(2, HIGH);
  digitalWrite(3, LOW);
  digitalWrite(4, LOW);
  delay(180);
  digitalWrite(0, LOW);
  digitalWrite(1, HIGH);   // 2
  digitalWrite(2, LOW);
  digitalWrite(3, LOW);
  digitalWrite(4, LOW);
  delay(180);
  digitalWrite(0, HIGH);
  digitalWrite(1, LOW);  // 1
  digitalWrite(2, LOW);
  digitalWrite(3, LOW);
  digitalWrite(4, LOW);

}

```

# Answer
> 3 votes
You can write, at the end of `loop()`, “if one minute has elapsed, then go to sleep”. In C++, that would be:

```
if (millis() >= 60000)  // 60 seconds elapsed
    sleep_mode();

```

You will need to include `<avr/sleep.h>` in order to have access to the `sleep_mode()` function. The sleep is likely to be very short though, probably less than a millisecond, as the ATtiny will be waken up by the next timer interrupt.

If you want a deeper, longer sleep, you could choose a different sleep mode in `setup()`:

```
set_sleep_mode(SLEEP_MODE_PWR_DOWN);

```

Read the datasheet if you want to know what wakeup sources are available in each sleep mode.

Alternatively, if you want to make the ATtiny sleep forever (until the next power cycle), call `cli()` in order to disable the interrupts, right before calling `sleep_mode()`.

---
Tags: attiny85
---


# Question
Title: esp8266 analogRead of 5.5V soil moisture sensor input using voltage divider
On an ESP8266 I try to analogRead(A0) my soil moisture sensor using a voltage divider but I get unexpected low values.

The MT3608 increases the esp's output voltage from 3.3V to 5.5V which is the recommended voltage for my capacitive soil moisture sensor v1.2 (different to the picture below I use v1.2, not v1.0). When there is no voltage divider in the game and the sensor is dry, the sensor outputs ~4.5V (yellow wire). The output is around ~2.3V when the sensor is completely wet.

For my voltage divider I use a 150 Ohm (R1) and a 39 Ohm (R2) resistor. Given ~4.5V Vin on the yellow wire this should provide me with ~0.9V Vout on the green wire, because Vout=Vin\*(R2/(R1+R2)). A voltage \<=1V I could safely attach to the esp8266 A0 analog pin. However, using the voltage devider I measure only 8,3**mV** instead of the expected 0.9**V**! It drops to 7.7mV when Vin is 2.3V (wet sensor).

What am I doing wrong? Any advise is highly appreciated!

For testing I currently use a board which has a build-in internal voltage divider that allows for up to 3.3V input, however in the final design I need to run everything using an ESP12-E without such an internal divider.

# Answer
When designing a voltage divider with 2 resistors, there are 2 things to consider:

* The ratio between R1 and R2, which gives the output voltage: U(out) = U(in) * \[R2 / (R1 + R2)\]
* The magnitude of each resistors: to get a 1/2 ratio, you need to have R1 = R2 no matter their value. But depending the value of your resistors (it can be 10Ω, 1kΩ, 100kΩ or 10MΩ for example), you will have a different current travelling through the bridge. The higher the resistors, the lower the current, and vice-versa.

When mesuring voltage inside the voltage divider, the ADC can be considered as a load to the circuit (as shown below). Some forums state that the input resistor of the ESP8266 ADC is around 20MΩ. If the resistors of the bridge are too low, the current will be high and will only travel through the bridge, leaving not enough current for the ADC to measure (electrons are lazy and always take the path of least resistance). On the other hand, if the resistors are too high, the current will be to low to be accurately detected as well.

In most cases, voltage dividers are build with resistors between 10kΩ and 1MΩ. This allows enough current to travel through the ADC to give an accurate measure of the voltage.

As suggested by dandavis comment, choosing (R1 ; R2) = (15kΩ ; 3,9kΩ) or (150kΩ ; 39kΩ) should work in your circuit.
> 2 votes

---
Tags: esp8266, sensors, voltage-divider
---


# Question
Title: Sending Data Between Arduino Nano and D1 Mini
I am sending data from Arduino Nano to D1 Mini,

*Transmitter is Arduino Nano*

**Transmitter Code:**

```
#include <DES.h>
#include <SoftwareSerial.h>
SoftwareSerial link(2, 3); // Rx, Tx
DES des;
byte in[8];
String  input;
char text[20];
char charVal[6];
char buf[30];
void setup() {
  link.begin(9600);
  Serial.begin(9600);
  Serial.println("Hello! Pleace Enter Your Data to Encrypt");
}
void tdesTest() {
  byte out[8];
  byte key[] = {
    0x3b, 0x38, 0x98, 0x37, 0x15, 0x20, 0xf7, 0x5e, // key A
    0x92, 0x2f, 0xb5, 0x10, 0xc7, 0x1f, 0x43, 0x6e, // key B
    0x3b, 0x38, 0x98, 0x37, 0x15, 0x20, 0xf7, 0x5e, // key C (in this case A)
  };
  Serial.println();
  Serial.println("====== Triple-DES test ======");
  //encrypt
  Serial.print("Encrypt...");
  unsigned long time = micros();
  des.tripleEncrypt(out, in, key);
  time = micros() - time;
  Serial.print("done. (");
  Serial.print(time);
  Serial.println(" micros)");
  delay(10000);
  printArray(out, link);
  link.write(out, 9);
  delay(2000);
  //decrypt
  for (int i = 0; i < 8; i++)
  {
    in[i] = out[i];
  }
  Serial.print("Decrypt...");
  time = micros();
  des.tripleDecrypt(out, in, key);
  time = micros() - time;
  Serial.print("done. (");
  Serial.print(time);
  Serial.println(" micros)");
  printArray(out);
  delay(2000);
}
//passing output and Print
void printArray(byte output[], Print& serial)
{
  for (int i = 0; i < 8; i++)
  {
    if (output[i] < 0x10)
    {
      Serial.print("0");
    }
    Serial.print(output[i], HEX);
    Serial.print(" ");
    delay(100);
  }

  Serial.println();
}
//printing output without link pass
void printArray(byte output[])
{
  for (int i = 0; i < 8; i++)
  {
    if (output[i] < 0x10)
    {
      Serial.print("0");
    }
    Serial.print(output[i], HEX);
    Serial.print(" ");
    delay(100);
  }
  Serial.println();
}
void userdata() {
  Serial.println("Sending User Data");
  byte user[] = {0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x30};
  printArray(user, link);
  link.write(user, 9);
  delay(100);
  tdesTest();

}
void loop() {
  while (Serial.available() > 0) {
    String  input = Serial.readString(); // read the incoming data as string
    memset(in, 0, 9); // Erase the contents of in[]
    input.toCharArray((char *)in, 9); // Copy up to 8 bytes from the string

    userdata();
  }
}

```

And receiving same from *D1 Mini (ESP8266)*

**Receiver Code:**

```
//Receiver code
#include <SoftwareSerial.h>
SoftwareSerial link(4, 0); // Rx, Tx

byte greenLED = 13;
byte cString[8];
byte chPos;
byte ch;
byte out[8];
String hexstring = "";

void setup()
{
  link.begin(9600); //setup software serial
  Serial.begin(9600);    //setup serial monitor
  pinMode(greenLED, OUTPUT);
}

void loop()
{

  while (link.available() > 0)
  {
    ESP.wdtDisable(); // This helps th avoid not reciving data after second try

    //read incoming char by char:
    ch = link.read();
    cString[chPos] = ch;
    chPos++;

    digitalWrite(greenLED, HIGH); //flash led to show data is arriving
    delay(20);
    digitalWrite(greenLED, LOW);

  }
  if (ch != 0)
  {
    printArray(cString);
    ESP.wdtEnable(1);
    Serial.flush();
    cString[chPos] = 0; //terminate cString
    chPos = 0;
  }

}

//printing output
void printArray(byte output[])
{
  for (int i = 0; i < 8; i++)
  {
    if (output[i] < 0x10)
    {
      Serial.print("0");
    }
    Serial.print(output[i], HEX);
    hexstring += String(output[i], HEX);
    Serial.print(" ");
    delay(100);

  }
  Serial.println();
  Serial.println("Your String Sir:");
  Serial.print(hexstring);
  Serial.println();
  ch = 0; // Avoid printing 0s when no data is recived
  hexstring = ""; //Clear the memeory of hexstring
}

```

**In Receiver I am receiving data as below:**

I want to get data in Single Stream to receiver *as Example: 31 30 30 30 30 30 30 30 7E B5 2D 4D 93 CB 08 BA* or in receiver join two streams in to a single stream,

**On Side Note:** 1st Part is Plain Data and 2nd Part will be Encrypted Data

Could anyone please help..

# Answer
> 0 votes
Managed Get it Working:

Change the Transmitter Code to Cascade Two Char Streams Before Sending:

**Transmitter Code:**

```
#include <DES.h>
#include <SoftwareSerial.h>
SoftwareSerial link(2, 3); // Rx, Tx
DES des;
byte in[8];
String  input;

void setup() {
  link.begin(9600);
  Serial.begin(9600);
  Serial.println("Hello! Pleace Enter Your Data to Encrypt");

}

//passing output and Print
void printArray(byte output[], Print& serial)
{
  for (int i = 0; i < 8; i++)
  {
    if (output[i] < 0x10)
    {
      Serial.print("0");

    }
    Serial.print(output[i], HEX);
    Serial.print(" ");
    delay(100);

  }

  Serial.println();

}
//printing output without link pass
void printArray(byte output[])
{
  for (int i = 0; i < 8; i++)
  {
    if (output[i] < 0x10)
    {
      Serial.print("0");

    }
    Serial.print(output[i], HEX);
    Serial.print(" ");
    delay(100);

  }
  Serial.println();
}

void userdata_and_Encrypt() {
  Serial.println("Sending User Data");
  byte username[] = {0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30};
  printArray(username, link);
  byte username_data = (username, 9);
  delay(100);

  byte out[8];
  byte key[] = {
    0x3b, 0x38, 0x98, 0x37, 0x15, 0x20, 0xf7, 0x5e, // key A
    0x92, 0x2f, 0xb5, 0x10, 0xc7, 0x1f, 0x43, 0x6e, // key B
    0x3b, 0x38, 0x98, 0x37, 0x15, 0x20, 0xf7, 0x5e, // key C (in this case A)
  };

  Serial.println();
  Serial.println("====== Triple-DES test ======");
  //encrypt
  Serial.print("Encrypt...");
  unsigned long time = micros();
  des.tripleEncrypt(out, in, key);
  time = micros() - time;
  Serial.print("done. (");
  Serial.print(time);
  Serial.println(" micros)");
  delay(100);
  printArray(out, link);
  byte password_data = (out, 9);
  delay(100);
  byte data_stream = username_data + password_data;
  printArray(data_stream, link);
  link.write(out, 17);

  //decrypt
  for (int i = 0; i < 8; i++)
  {
    in[i] = out[i];
  }
  Serial.print("Decrypt...");
  time = micros();
  des.tripleDecrypt(out, in, key);
  time = micros() - time;
  Serial.print("done. (");
  Serial.print(time);
  Serial.println(" micros)");
  printArray(out);
  delay(100);

}

void loop() {

  while (Serial.available() > 0) {

    String  input = Serial.readString(); // read the incoming data as string
    memset(in, 0, 9); // Erase the contents of in[]
    input.toCharArray((char *)in, 9); // Copy up to 8 bytes from the string

    userdata_and_Encrypt();

  }
}

```

Receiver Code to Accept 16 Bytes

**Receiver Code:**

```
//Receiver code
#include <SoftwareSerial.h>
SoftwareSerial link(4, 0); // Rx, Tx

byte greenLED = 13;
byte cString[8];
byte chPos;
byte ch;
byte out[8];
String hexstring = "";
static String data = "";

void setup()
{
  link.begin(9600); //setup software serial
  Serial.begin(9600);    //setup serial monitor
  pinMode(greenLED, OUTPUT);
}

void loop()
{

  while (link.available() > 0)
  {
    ESP.wdtDisable(); // This helps th avoid not reciving data after second try

    //read incoming char by char:
    ch = link.read();
    cString[chPos] = ch;
    chPos++;

    digitalWrite(greenLED, HIGH); //flash led to show data is arriving
    delay(20);
    digitalWrite(greenLED, LOW);

  }
  if (ch != 0)
  {
    printArray(cString);
    ESP.wdtEnable(1);
    Serial.flush();
    cString[chPos] = 0; //terminate cString
    chPos = 0;
  }

}

//printing output
void printArray(byte output[])
{
  for (int i = 0; i < 16; i++)
  {
    if (output[i] < 0x10)
    {
      Serial.print("0");
    }
    Serial.print(output[i], HEX);
    hexstring += String(output[i], HEX);
    Serial.print(" ");
    delay(100);

  }
  Serial.println();

  Serial.println("Your String Sir:");
  Serial.println(hexstring);

  Serial.println();
  ch = 0; // Avoid printing 0s when no data is recived
  hexstring = ""; //Clear the memeory of hexstring
}

```

**Working Output:**

---
Tags: serial, esp8266, arduino-nano, data
---


# Question
Title: How to difference hardware reset and software reset?
I have an arduino code with an SD card where I save some data. When I load a new code, The SD must update with the new data that I put in the code, but if I reset the Arduino by the reset button, I don´t want the SD data to change.

To sum up, I want to reload SD data only when I update the code, and not with hardware reset

Any ideas?

# Answer
> 3 votes
You can't. There is no "software" reset. When you upload new code a hardware reset is triggered by the DTR pin of the USB interface chip.

Instead I would suggest maintaining a "data version number" on the SD card. Read it on startup and, if it differs from the expected version number (which you update in your code manually) it creates the data for you and sets the version number.

---
Tags: sd-card, reset, sd
---


# Question
Title: how to display text to 8x8 matrix with 64-bit long integers?
I have an array of 64-bit integers to display on an 8x8 led matrix

```
const int LEN1 = sizeof(Hours);
const uint64_t Hours[] = {
  0x00043c3c3c3c3c00,
  0x000c3c3c3c3c3c00,
  0x001c3c3c3c3c3c00,
  0x0000001818000000,
  0x0000001818100000,
  0x0000001818180000,
  0x00000018181c0000,
  0x000000181c1c0000,
  0x0000001c1c1c0000,
  0x0000041c1c1c0000,
  0x00000c1c1c1c0000
};

```

and here I have a loop to display it:

```
void displayImage(uint64_t image) {
  for (int i = 0; i < 8; i++) {
    byte row = (image >> i * 8) & 0xFF;
    for (int j = 0; j < 8; j++) {
      lc.setLed(0, i, j, bitRead(row, j));
    }
  }
}

```

but I can't use a loop in this way and I'm not proficient in byte shifting principles too.

can you please explain how the loop above works or help me to write this loop as

```
const int LEN1 = sizeof(Hours);

void displayImage(Hours[]) {
  for (int i = 0; i < LEN1; i++) {
    //display Hours
    }
}

```

# Answer
> 0 votes
ok, well there are some things I don't know about your code, and hardware, like if the LCD library can handle uint64\_t datatypes. I know the Serial.print() function can only handle up to a unit32\_t, so I'm using that.

I think your length variable might not be the right length, you might want to add in a check for that in your code. Much of the Arduino code is 8 bit.

```
void setup() {
Serial.begin(9600);
uint32_t b = 0x0;

const uint64_t Hours[] = {
  0x00043c3c3c3c3c00,
  0x000c3c3c3c3c3c00,
  0x001c3c3c3c3c3c00,
  0x0000001818000000,
  0x0000001818100000,
  0x0000001818180000,
  0x00000018181c0000,
  0x000000181c1c0000,
  0x0000001c1c1c0000,
  0x0000041c1c1c0000,
  0x00000c1c1c1c0000
};

//const int LEN1 = sizeof(Hours[0]);
const int LEN1 = sizeof(Hours)/sizeof(uint64_t);
       Serial.print("Length: ");
       Serial.println(LEN1);

   for (int i = 0; i < LEN1; i++) {
       b=Hours[i]>>16;
       Serial.println(b,HEX);
       }
}

void loop() {
}

```

I think this code will do what you want, at least as I understand it. beware of what data-types your LCD library can handle.

---
Tags: arduino-mega, c++, display, led-matrix
---


title: Listening Serial Ports

text:
# Question
Title: Listening Serial Ports
guys. I need your help. I have 6 Serial Channels and I need to listen this channel and be sure which channel is working? How can I do that? Can I listen this channel by using digital inputs? Or Do I have to use a devices which has a 6 Serial ports? Like 2 Arduino Mega?

# Answer
> 2 votes
For your needs you don't need actual UARTs. You can do it all with normal GPIO pins and one (or more) interrupts.

UART communication is characterised by having a "start bit" at the beginning of all bytes. That is, in TTL terms, a transition from HIGH to LOW. You just need to look out for that transition.

You could:

* Use Pin Change interrupts on 6 pins to monitor for any FALLING transistion, or
* Use one interrupt pin with a *wired OR* of all the signals along with individual pins for each signal to determine which triggered the interrupt.

To determine "is it active" you just need to know that an interrupt has occurred and which pin triggered it, and has that been seen within a certain time period (to be decided by you).

---
Tags: serial, arduino-mega, softwareserial, communication
---