# Question
Title: Stuck making multi, many button, joysticks
I'm stuck, I figured I'd ask here for some help... Note I'm a newb and this is essentially my first Arduino project beyond blink...

I'm creating Virtual cockpit panels for DCS World, using an Arduino Leonardo as an HID device. I'm using three SN74HC165 Shift-In registers for multi-buttons (24) - as it seemed the easiest - and all in all it does work...

So I figured that I'm using only 4 pins on the Leonardo, so why not try to setup 3 of these "shift-in clusters" (12 pins) to appear as 3 separate joysticks?

I got the one working and I got 2 more joysticks showing up in Windows10... now my problem is: how would I setup 2 more "shiftIn Clusters", I've tried many things but I must defer to outside help (cause I really don't know what I'm doing)

Edit to clarify: So each joystick need 3 or 4 shift registers making 24-32 buttons on each joystick

Shift In Lib: https://github.com/…/Ardu…/blob/master/ShiftIn/src/ShiftIn.h

Joy2 Lib: https://github.com/MHeironimus/ArduinoJoystickLibrary

Here's an image of the Layout I want: https://i.stack.imgur.com/sEtRp.png

... any help would relieve a great headache, Thank for your time

```
#include <ShiftIn.h>
#include <Joystick.h>

// use <n> shift registers
ShiftIn<3> shift;             // use three shift register

// Create joystick
// TESTING MULTI JOYSTICKS
// 1/3 Works!!!
// 3/3 Appear in Windows
// ????? must add shiftIn sections for 2nd and 3rd joysticks????
// (add pin usage + modify line 77-79 stuff)

#define JOYSTICK_COUNT 3
Joystick_ Joystick[JOYSTICK_COUNT] = {
  Joystick_(0x03, JOYSTICK_TYPE_GAMEPAD, 32, 0, false, false, false, false, false, false, false, false, false, false, false),
  Joystick_(0x04, JOYSTICK_TYPE_GAMEPAD, 32, 0, false, false, false, false, false, false, false, false, false, false, false),
  Joystick_(0x05, JOYSTICK_TYPE_GAMEPAD, 32, 0, false, false, false, false, false, false, false, false, false, false, false),
};

// Set to true to test "Auto Send" mode or false to test "Manual Send" mode.
//const bool testAutoSendMode = true;
const bool testAutoSendMode = false;

const unsigned long gcCycleDelta = 1000;
const unsigned long gcAnalogDelta = 25;
const unsigned long gcButtonDelta = 500;
unsigned long gNextTime = 0;
unsigned int gCurrentStep = 0;
int gJoystickId = 0;

/*
// WORKING SECTION Single Joystick with Shift Reg
Joystick_ Joystick(JOYSTICK_DEFAULT_REPORT_ID, JOYSTICK_TYPE_GAMEPAD,
  32, 0,                        // Button Count, Hat Switch Count
  false, false, false,          // X and Y, but no Z Axis
  false, false, false,          // No Rx, Ry, or Rz
  false, false,                 // No rudder or throttle
  false, false, false);         // No accelerator, brake, or steering
*/

void setup() {

  shift.begin(8, 9, 11, 12);  // set pins of the shift register
//  shift[1].begin(7, 6, 5, 4);  // set pins of the shift register
//  shift[2].begin(3, 2, 1, 0);  // set pins of the shift register

 Joystick[0].begin();
 Joystick[1].begin();
 Joystick[2].begin();
}

void loop() {

  if (shift.update()) {
    for (int i = 0; i < shift.getDataWidth(); i++)
    Joystick[0].setButton(i, shift.state(i));            // just press or release the button
  }
/*if (shift[1].update()) {
    for (int i = 0; i < shift[1].getDataWidth(); i++)
    Joystick[0].setButton(i, shift[1].state(i));            // just press or release the button
  }
if (shift[2].update()) {
    for (int i = 0; i < shift[2].getDataWidth(); i++)
    Joystick[0].setButton(i, shift[2].state(i));            // just press or release the button
  }
  delay(10);
*/
}

```

# Answer
> 1 votes
Each `ShiftIn` instance handles just one connection. You need to make multiple instances.

```
ShiftIn shift1<3>;
ShiftIn shift2<3>;
ShiftIn shift3<3>;

```

Then you `begin` each of them:

```
void setup() {
    shift1.begin(8, 9, 11, 12);
    shift2.begin(7, 6, 5, 4);
    shift3.begin(3, 2, 1, 0);
    ... etc ...
}

```

Each `shiftx` is a completely separate entity. You can just repeat your block of code for each `shift` object:

```
if (shift1.update()) {
    for (int i = 0; i < shift1.getDataWidth(); i++)
    Joystick[0].setButton(i, shift1.state(i));
}

if (shift2.update()) {
    for (int i = 0; i < shift2.getDataWidth(); i++)
    Joystick[1].setButton(i, shift2.state(i));
}

if (shift3.update()) {
    for (int i = 0; i < shift3.getDataWidth(); i++)
    Joystick[2].setButton(i, shift3.state(i));
}

```

You could arrange the `ShiftIn` objects into an array like you do with your `Joystick` objects and then loop through them, but that is pretty pointless for just three of them.

---
Tags: shift-register, joystick
---


# Question
Title: Controlling 16x2 LCD backlight (I2C module)
I've installed an I2C module on my 16x2 LCD so i don't have access to all those LCD pins to control the backlight LED.

**BUT** there is a 100 ohm smd resistor in series with anode of the backlight LED, i want to remove the resistor and use Arduino PWM to control the backlight or i can just replace that resistor with a 330 ohm or a 1K resistor.

*Red box showing the resistor and blue box showing the Jumper.*

Also I2C module itself have a jumper for LED backlight which also goes to that resistor...

Just wanted to ask here and make sure it is going to work before doing any modification to the LCD.

which way is better? is it going to work?

---

**UPDATE:** *i used Arduino PWM and a 2n2222 transistor and was able to successfully control the backlight brightness via jumper pins of I2C module.*

# Answer
It's hard to tell from the limited information, but chances are the "backlight jumper" mentioned in passing in the datasheet can be simply removed. This will then give you two pins. One will connect to pin 3 of the IO expander, and the other will connect to the back light anode itself.

Which is which you will have to discover for yourself. One of them will have the 100Ω resistor in line with it as well.

If you can't see the tracks (some black boards are hard to make them out) then you should get a digital multimeter and set it to continuity mode and probe the pins to see where they lead.

Once you have identified which pin is which you can connect the one that goes to the back light to your Arduino and drive it with PWM.
> 1 votes

---
Tags: lcd
---


# Question
Title: lcd.clear doesn't work with Serial.begin(9600) on Arduino Mega 2560
So I have a standard 16x2 LCD display with 16 pins. The LCD display works fine with every other aspect, however, the "lcd.clear" function doesn't work with "Serial.begin(ANY BAUD)". I have tried changing bauds and downgrading the board software but it still doesn't work.

Basically, instead of clearing the display like it should do, it displays a weird character with 4 horizontal lines (in one character space) and then continues to write stuff after it.

Here is my code:

```
#include <LiquidCrystal.h>
LiquidCrystal lcd(1, 2, 4, 5, 6, 7);

void setup() {
 pinMode(8, INPUT);
 lcd.begin(16,2);
 Serial.begin(9600);
}

void loop() {
 lcd.print("incorrect");
 delay(3000);
 lcd.clear();
 delay(100);
}

```

Whenever I delete the Serial.begin everything works fine, but when I add it the clear function doesn't work anymore.

So in this case, what happens is that the Arduino prints "incorrect", then instead of clearing the display, it prints out four horizontal lines, and then continues to print out "incorrect" infinitely.

# Answer
> 1 votes
Pins 0 and 1 are the hardware serial pins on the Mega. If you're going to use Serial, then you can't connect your LCD to those pins or it won't work. Even if you are only connected to Serial through the USB, pins 0 and 1 are still acting as Tx and Rx.

# Answer
> 0 votes
Buddy you are using those pins which are used for communication purpose that is pin No. 0 and 1 is for RXD and TXD

---
Tags: serial, arduino-mega, lcd
---


# Question
Title: I cannot open/write to dataFile SD shield in mySketch but have no problem with Datalogger example sketch from the SD library...?
Hello Arduino Community

I am collecting data and attempting to log it on to a Deek Robot SD shield via a Mega.

I have the data in a dataString which I can Serial.print to the monitor but would like to log it to an SD card instead. When I run the the Datalogger example sketch from the SD library I can see the data and access the datalog file from the SD card (as per point of the example) but when I try to cross-pollinate the example with mySketch the debugging message

> error opening datalog.txt

is all I get.

I've uploaded the sketch, apologies it is pretty long, there's some adc stuff going on, the call for the data file open and write etc starts on line 200 and ends on 212.

I've tried positioning the datafile functions in different places in the code, using other libraries, reading forum posts but I am getting nowhere. if anyone could point out what I'm doing wrong I would be eternally grateful.

Cheers, Michael

```
//!!!change this to name of sketch!!!!
#define SKETCH_VERSION "SD for loop array test"

//include relevant libraries
#include <EnableInterrupt.h>
#include <SPI.h>
#include <SD.h>

//globally define pins
#define BUSY 3    //purple*
#define RD 4      //yellow* RD+CS tied together
#define RESET 5   //grey*
#define CONVST 6  //green* CONVSTA+CONVSTB soldered together on the board
#define RANGE 7   //blue*   *not permanent - double check!!!*

#define DB0 38
#define DB1 39
#define DB2 40
#define DB3 41
#define DB4 42
#define DB5 43
#define DB6 44
#define DB7 45
#define DB8 46
#define DB9 47
#define DB10 48
#define DB11 49
#define DB12 50
#define DB13 51
#define DB14 52
#define DB15 53

byte statusLed       = 13;
byte sensorPin1       = 10;
byte sensorPin2       = 11;
byte sensorPin3       = 12;

int sensorValue[8];
int rawData[16];

//change the size  of these arrays to match the amount of channels being read by the ADC
int adcChannel[5];
int adcData[5];
int channelCount=5;

volatile byte pulseCount1;
volatile byte pulseCount2;
volatile byte pulseCount3;

int pulses[3];

// cs pin for sd-shield *NB 53 for Mega
const int chipSelect = 53;

unsigned long oldTime;

void setup() {             //set up the hardware

  Serial.begin(9600);
  //sd card.....
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }

  Serial.print("Initializing SD card...");

  // see if the card is present and can be initialized:
  if (!SD.begin(chipSelect)) {
    Serial.println("Card failed, or not present");
    // don't do anything more:
    while (1);
  }
  Serial.println("card initialized.");

  enableInterrupt(BUSY, bitBang, FALLING);

  oldTime            = 0;

  pinMode(DB0, INPUT_PULLUP);
  pinMode(DB1, INPUT_PULLUP);
  pinMode(DB2, INPUT_PULLUP);
  pinMode(DB3, INPUT_PULLUP);
  pinMode(DB4, INPUT_PULLUP);
  pinMode(DB5, INPUT_PULLUP);
  pinMode(DB6, INPUT_PULLUP);
  pinMode(DB7, INPUT_PULLUP);
  pinMode(DB8, INPUT_PULLUP);
  pinMode(DB9, INPUT_PULLUP);
  pinMode(DB10, INPUT_PULLUP);
  pinMode(DB11, INPUT_PULLUP);
  pinMode(DB12, INPUT_PULLUP);
  pinMode(DB13, INPUT_PULLUP);
  pinMode(DB14, INPUT_PULLUP);
  pinMode(DB15, INPUT_PULLUP);

  pinMode(RESET, OUTPUT);
  pinMode(CONVST, OUTPUT);
  pinMode(RD, OUTPUT);
  pinMode(RANGE, OUTPUT);
  pinMode(BUSY, INPUT);

  //reset ADC to begin conversion
  digitalWrite(RESET, HIGH);
  delayMicroseconds(10);
  digitalWrite(RESET, LOW);

  digitalWrite(CONVST, LOW);
  digitalWrite(RD, HIGH);
  digitalWrite(RANGE, LOW);
  digitalWrite(BUSY, LOW);

  delayMicroseconds(100);

  // Set up the status LED line as an output
  pinMode(statusLed, OUTPUT);
  digitalWrite(statusLed, HIGH);  // We have an active-low LED attached

  pinMode(sensorPin1, INPUT);
  digitalWrite(sensorPin1, HIGH);

  pinMode(sensorPin2, INPUT_PULLUP);
  digitalWrite(sensorPin2, HIGH);

  pinMode(sensorPin3, INPUT_PULLUP);
  digitalWrite(sensorPin3, HIGH);

  pulseCount1        = 0;
  pulseCount2        = 0;
  pulseCount3        = 0;

  oldTime            = 0;

  // the hall effect sensors are configured to trigger on a FALLING state change
  // (transition from HIGH state to LOW state)
  enableInterrupt(sensorPin1, pulseCounter1, FALLING);
  enableInterrupt(sensorPin2, pulseCounter2, FALLING);
  enableInterrupt(sensorPin3, pulseCounter3, FALLING);

  //this prints the name of the sketch !!!read line 1!!!
  Serial.print("sketch version: ");
  Serial.println(SKETCH_VERSION);

}

void loop() {
  //Serial.print("hello");
  //change this value to preferred sampling rate
  if ((millis() - oldTime) == 1000) {

    oldTime = millis();

    //Serial.print(millis());
    //Serial.print("\t");

    //tell ADC to start read (converting analogue input to digital output)
    delayMicroseconds(10);
    digitalWrite(CONVST, LOW);
    delayMicroseconds(10);
    digitalWrite(CONVST, HIGH);
    //when read-conversion is complete ADC sends the BUSY pin low triggering the bitBang ISR

    //print ADC data from array within the bitBang ISR to a string
    String adcString = "";
    for(int thisChannel=0; thisChannel<channelCount; thisChannel++){
      adcString += String(adcData[thisChannel]);
      adcString += ",";
    }

    //disable interrupt to access current pulse count
    disableInterrupt(sensorPin1);
    disableInterrupt(sensorPin2);
    disableInterrupt(sensorPin3);
    //grab current pulse count and store in a variable
    pulses[0] = pulseCount1;
    pulses[1] = pulseCount2;
    pulses[2] = pulseCount3;
    //reset pulse count
    pulseCount1 = 0;
    pulseCount2 = 0;
    pulseCount3 = 0;
    //enable interrupt and start incrementing pulse count again
    enableInterrupt(sensorPin1, pulseCounter1, FALLING);
    enableInterrupt(sensorPin2, pulseCounter2, FALLING);
    enableInterrupt(sensorPin3, pulseCounter3, FALLING);

    String pulseString = "";
    for(int i=0; i<3; i++){
      pulseString += String(pulses[i]);
      if (i<2) {
        pulseString += ",";
      }
    }

    String dataString = String(adcString + pulseString);
  // open the file. note that only one file can be open at a time,
  // so you have to close this one before opening another.
  File dataFile = SD.open("datalog.txt", FILE_WRITE);

  // if the file is available, write to it:
  if (dataFile) {
    dataFile.println(dataString);
    dataFile.close();
    // print to the serial port too:
    Serial.println(dataString);
  }
  // if the file isn't open, pop up an error:
  else {
    Serial.println("error opening datalog.txt");
  }

 //Serial.println(dataString);

  }
//start again
}

//grabbing ADC data ISR (for n channel)
void bitBang ()  {
  //a for loop to bitbang the values fom the analogue (ADC) channels (maximum 8) sequentially storing them in a variable array (equal to the channels of the ADC)
  for(int thisChannel=0; thisChannel<channelCount; thisChannel++){
  //send ADC read pin low to bitbang the first channel
  digitalWrite(RD, LOW);
  //read the state of the 16 pins and store in a variable
  rawData[0] = digitalRead(DB15);
  rawData[1] = digitalRead(DB14);
  rawData[2] = digitalRead(DB13);
  rawData[3] = digitalRead(DB12);
  rawData[4] = digitalRead(DB11);
  rawData[5] = digitalRead(DB10);
  rawData[6] = digitalRead(DB9);
  rawData[7] = digitalRead(DB8);
  rawData[8] = digitalRead(DB7);
  rawData[9] = digitalRead(DB6);
  rawData[10] = digitalRead(DB5);
  rawData[11] = digitalRead(DB4);
  rawData[12] = digitalRead(DB3);
  rawData[13] = digitalRead(DB2);
  rawData[14] = digitalRead(DB1);
  rawData[15] = digitalRead(DB0);
  //convert into 16bit 2s compliment and store in a variable array
  adcData[thisChannel] = rawData[0] | (rawData[1] << 1) | (rawData[2] << 2) | (rawData[3] << 3) | (rawData[4] << 4) | (rawData[5] << 5) | (rawData[6] << 6) | (rawData[7] << 7) |  (rawData[8] << 8) | (rawData[9] << 9) | (rawData[10] << 10) | (rawData[11] << 11) | (rawData[12] << 12) | (rawData[13] << 13) | (rawData[14] << 14) | (rawData[15] << 15);
  //send ADC pin high to say we have read the first channel
  digitalWrite(RD, HIGH);
  //repeat for n channels
  }
}

//counting pulses ISRs
void pulseCounter1(){
  // Increment the pulse counter
  pulseCount1++;
}
void pulseCounter2(){
  // Increment the pulse counter
  pulseCount2++;
}
void pulseCounter3(){
  // Increment the pulse counter
  pulseCount3++;
}

```

# Answer
The SD card uses SPI for communications. You appear to be using those pins for some other purpose. If you want to use the SD card, then you need to choose other pins and let the SD card have 50, 51, 52, and 53.
> 0 votes

---
Tags: arduino-mega, sd-card, datalogging
---


title: ESP12E Boot vs SPI

text:
# Question
Title: ESP12E Boot vs SPI
I was wondering how I could overcome the next issue;

My ESP8266 12E is connected as follows:

* GPIO0 ground if needed to program, vcc otherwise
* GPIO2 vcc
* GPIO15 ground

Bootmodes explained in the this schematic

I also want to connect a MCP3002 to my ESP. However to use SPI I also need the GPIO15 pin to be connected to the Chip Select pin.

MCP connections explained in this article

---

I tried connecting the GPIO15 pin from the ESP to the CS pin of MCP3002 and connecting ground in between. This did not work though, should I switch/remove the ground after boot somehow? (Or should I connect it differently?)

# Answer
The io 15 is SS if esp8266 is slave. If esp8266 is SPI master, you can choose any free pin as CS of the slave.

---

The esp8266 arduino boards package SPISlave library examples have a solution for master if esp8266 is slave.

The state of the boot pins is required only at boot. You should wire boot pins over a 10 kOhm resistor to create a pull-up/pull-down which can be override by pin output state to use the pins for devices which are OK with or need pull-up or pull-down, for example momentary switches (buttons).
> 3 votes

---
Tags: esp8266, spi
---


# Question
Title: Wire SlaveReceiver : will the registered function in onRecieve interrupt/conflict with loop block?
I am currently researching on I2C, and I made a configuration that has MasterWriter that transmits data to a SlaveReceiver that will store the data received from Master, into an SD card, and then transmit the same line of data by GPRS onto my back end.

Now the new requirement needs some kind of a caching system, so that if the GPRS failed to transmit, it'll instead save into the SD card under a different filename (the previous step of saving into SD Card is still done but it's for another purpose), so when the GSM signal needed has recovered it'll read the cached/backed-up data, and then transmit the backed-up data. So that means I'll use the loop block (which currently only has one line of delay function).

My question is, will the triggered function "receiveEvent" registered in setup for Wire Slave :

> Wire.onReceive(receiveEvent);

conflict with the ongoing loop block where the system reads the backed-up data and sends the backed-up data?

Here's my SlaveReceiver code :

```

#define ONLINE_MODE 1 //  turn on for GSM.
#define CACHE_MODE 1 //   turn on for SD-based caching
#define I2C_MODE 1  //    turn on for I2C mode SDA-SCL

#include <Arduino.h>
#include "Slave_GSM_SD.h"

#if ONLINE_MODE
// Sim900
#include "GSM.h"
SIM900 gprs;
#endif

#if I2C_MODE
#include <Wire.h>
#endif

#if CACHE_MODE
//SD Card
#include <SPI.h>
#include <SD.h>
#define DEBUG_SD 1
#define SD_CS_PIN 4
File cacheFile;
#endif

void setup()
{
    console.begin(9600);
    while (!console);

    #if CACHE_MODE
     //SD Card
    Serial.print(F("Initializing SD card..."));

    if (!SD.begin(SD_CS_PIN)) {
      Serial.println(F("initialization failed!"));
      while (1);
    }
    // open the file. note that only one file can be open at a time,
    // so you have to close this one before opening another.
    cacheFile = SD.open("CACHE.txt", FILE_WRITE);
    Serial.println(F("SD Card initialization done."));
    #endif

    #if ONLINE_MODE
    gprsSetup();
    #endif

    #if I2C_MODE
    Wire.begin(8);                // join i2c bus with address #8
    Wire.onReceive(receiveEvent); // register event
    #endif
    console.println(F("SLAVE GSM SD READY"));

}

// function that executes whenever data is received from master
// this function is registered as an event, see setup()
// [Q] : will this interrupt/conflict with loop() if loop is still ongoing?
void receiveEvent(int howMany) {
  #if DEBUG_I2C
  Serial.print(F("available bytes : "));
  Serial.print(howMany);
  Serial.print(F(" or "));
  Serial.println(Wire.available());
  #endif

  #if I2C_MODE
  char jsonData[128]="";
  while (Wire.available()) { // loop through all but the last
    char c = Wire.read(); // receive byte as a character

    int len = strlen(jsonData);
    jsonData[len] = c;
    jsonData[len+1] = '\0';

    #if DEBUG_I2C
    Serial.print(c);         // print the character
    #endif

    if (c == '}'){

      #if CACHE_MODE
      writeToSd(jsonData);
      #endif

      #if ONLINE_MODE
      gprsSequence(jsonData);
      #endif

      #if DEBUG_I2C
      Serial.println(F("SAVING TRIGGERED"));
      Serial.println(jsonData);
      #endif
    }

  }
  #endif
}

void writeToSd(char *jsonToWrite){

  #if CACHE_MODE
  // open the file. note that only one file can be open at a time,
 // so you have to close this one before opening another.
  cacheFile = SD.open("CACHE.txt", FILE_WRITE);
  if (cacheFile) {
    cacheFile.write(jsonToWrite);
    cacheFile.close();
  }

  #if DEBUG_SD
  Serial.println(F(" << "));
  // re-open the file for reading:
    cacheFile = SD.open("CACHE.txt");
    if (cacheFile) {
    Serial.println("CACHE.txt:");

    // read from the file until there's nothing else in it:
    while (cacheFile.available()) {
      Serial.write(cacheFile.read());
    }
      // close the file:
      cacheFile.close();
    } else {
      // if the file didn't open, print an error:
      Serial.println(F("error opening CACHE.txt"));
    }
  #endif
  #endif

}

void loop() {
    // i wanted to code the cached-data sending here
    delay(2000);
}

void gprsSetup() {
  //... cleared for brevity
}

void gprsSequence(char *jsonData) {
    //... cleared for brevity. the point is, this function is to send the jsonData by GPRS
}

```

# Answer
> 2 votes
Generally the `onReceive` callback function is called from an ISR in the `Wire` library. That means, that no other interrupts can be handled during that time. For this reason an ISR always should be as short as possible. Writing to the SD card is a rather long process and it also uses interrupts, so it might block forever, when used in an ISR (though I'm not sure, since I didn't look through the SD library). You should do the SD card stuff outside of the ISR. In the ISR you can receive the I2C message and then set a flag variable, that will tell the code in the `loop()` function, that new data is available and that it can start processing it. That way your ISR stays short and the other operations will not be blocked by it. Do the same with the direct sending of GPRS data.

Also note, that transmitting Serial data inside of an ISR also does not work for the same reason (Serial relies on interrupts). The calls to `Serial.print()` or `Serial.write()` will only fill the libraries internal buffer. The data will get transmitted after the ISR was left. If you try to print/write data to Serial, when the buffer is full, the library will block, until the buffer has again space for sending the data, which will never happen inside the ISR. So you should be cautious with writing Serial inside an ISR. A bit doesn't hurt, but it can get a big problem.

> will the triggered function "receiveEvent" registered in setup for Wire Slave `Wire.onReceive(receiveEvent);` conflict with the ongoing loop block where the system reads the backed-up data and sends the backed-up data?

From the general logic there cannot happen more than 1 specific data operation on the SD card at the same time. If you are currently writing one file, you cannot simply break the transmission through an interrupt and writing another file without breaking things. The transaction has to be completed, or you will fastly corrupt your file system. But, as I wrote above, this isn't really possible either way, because the SD card calls will not work properly inside of an ISR. So just put all the GPRS and SD card code into the `loop()` function and trigger the corresponding code blocks with a flag from the ISR. That way nothing can conflict here.

---
Tags: i2c, gsm, sd-card, wire-library, loop
---


# Question
Title: How to Run Stepper motor through Serial Communication
I am trying to run a Stepper motor from my c++ application, from which I sent commands but its not running not sure why would it not run, outside serial check it run but inside serial check it not run.

Here is my code, not sure what am doing wrong, my first time with Arduino.

```
#include <AccelStepper.h>

#define BAUD 9600

// CNC Shield V3  Step and Dir pins on Mega 2560
#define step_pin_x 2
#define dir_pin_x 5
#define MOTOR_X_ENABLE_PIN 8
// Drive A4988
#define motorInterfaceType 1

AccelStepper stepper_X = AccelStepper(motorInterfaceType, step_pin_x, dir_pin_x);

void setup() {
  Serial.begin(BAUD);
  pinMode(53, OUTPUT);   // for red led it pin # 53
  pinMode(MOTOR_X_ENABLE_PIN, OUTPUT);  // for X stepper motor

    stepper_X.setMaxSpeed(1000);
    stepper_X.setSpeed(500);
}

void loop() {
    String input;
  //If any input is detected in arduino
  if(Serial.available() > 0){
    //read the whole string until '\n' delimiter is read
    input = Serial.readStringUntil('\n');

    if (input.equals("ON")){
       digitalWrite(53, HIGH);   // Turn ON RED LED
       stepper_X.runSpeed();      // Suppose to run stepper motor .. but not working
       Serial.println("X Motors:: "+input);

    }else if (input.equals("OFF")){
       stepper_X.stop();
       digitalWrite(53, LOW);    // Turn OFF RED LED
       Serial.println("X Motors:: "+input);
    }

  }else{
  //  stepper_X.runSpeed();      // if uncommented stepper motor will run
  }
}

```

**Update** so it seems its code blocking issues

i update my code according to tut : https://majenko.co.uk/blog/reading-serial-arduino

```
    char buf[80];

    int readline(int readch, char *buffer, int len) {
        static int pos = 0;
        int rpos;

        if (readch > 0) {
            switch (readch) {
                case '\r': // Ignore CR
                    break;
                case '\n': // Return on new-line
                    rpos = pos;
                    pos = 0;  // Reset position index ready for next time
                    return rpos;
                default:
                    if (pos < len-1) {
                        buffer[pos++] = readch;
                        buffer[pos] = 0;
                    }
            }
        }
        return 0;
    }

void loop() {
   if (readline(Serial.read(), buf, 80) > 0) {
   if(strcmp("n", buf) == 0){
          digitalWrite(53, HIGH);
         stepper_X.setMaxSpeed(1000);
         stepper_X.setSpeed(500);
          stepper_X.runSpeed();
          Serial.print("All Motors:: ");
          Serial.print(buf);

        }
    }
}

```

now its working ok

**Update 2 :** c++ sending command via Serial

```
    std::string input_command = "ON";
    //Creating a c string
     char *c_string = new char[input_command.size() + 1];
     //copying the std::string to c string
     std::copy(input_command.begin(), input_command.end(), c_string);
     //Adding the delimiter
     c_string[input_command.size()] = '\n';

// using this serial lib : https://github.com/manashmndl/SerialPort
   writeSerialPort(c_string, MAX_DATA_LENGTH);

```

# Answer
> 2 votes
Per the documentation of the AccelStepper’s `runSpeed()` method:

> You must call this as frequently as possible, but at least once per step interval,

It appears the AccelStepper library is not compatible with blocking code. Not a big deal, blocking code is almost always bad practice anyway. However, `Serial.readStringUntil()` is a blocking function: it will prevent the program from doing any useful work.

You have to read the serial port in a non-blocking fashion, use the commands to set the motor speed, and always call `runSpeed()` as frequently as possible.

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


# Question
Title: Why is the IDE not able to find the board despite it being clearly seen and selected?
i'm having an odd problem where despite having the correct port selected 3 times i'm still getting an error as shown below:  message:

```
Arduino: 1.8.9 (Windows 10), Board: "Adafruit Feather M0, Arduino, Off"

Sketch uses 20876 bytes (7%) of program storage space. Maximum is 262144 bytes.
Atmel SMART device 0x10010005 found
Device       : ATSAMD21G18A
Chip ID      : 10010005
Version      : v2.0 [Arduino:XYZ] Mar  5 2016 17:46:52
Address      : 8192
Pages        : 3968
Page Size    : 64 bytes
Total Size   : 248KB
Planes       : 1
Lock Regions : 16
Locked       : none
Security     : false
Boot Flash   : true
BOD          : true
BOR          : true
Arduino      : FAST_CHIP_ERASE
Arduino      : FAST_MULTI_PAGE_WRITE
Arduino      : CAN_CHECKSUM_MEMORY_BUFFER
Erase flash
done in 0.832 seconds

Write 21164 bytes to flash (331 pages)

[=====                         ] 19% (64/331 pages)
[===========                   ] 38% (128/331 pages)
[=================             ] 58% (192/331 pages)
[=======================       ] 77% (256/331 pages)
[============================= ] 96% (320/331 pages)
[==============================] 100% (331/331 pages)
done in 0.128 seconds

Verify 21164 bytes of flash with checksum.
Verify successful
done in 0.016 seconds
CPU reset.
Couldn't find a Board on the selected port. Check that you have the correct port selected.  If it is correct, try pressing the board's reset button after initiating the upload.

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

```

# Answer
> 5 votes
The SAMD boards connect to computer over native USB support of the MCU. The handling of the USB is done by Arduino core functions linked at build to your sketch.

A consequence of using the native USB port is, if your sketch has a problem, it influences the USB communication. In this case you can activate the bootloader to handle the USB port and the upload. It is done by **double clicking the reset button** on board.

---
Tags: arduino-ide, communication, error, samd21g
---


# Question
Title: How to NOT repeat a piece of code again and again?
I have a VERY long code:

> Sketch uses 30468 bytes (92%) of program storage space. Maximum is 32768 bytes.

I've been trying to reduce it's size so i can write more code, one of my main part of code which repeated many times in switch cases or in if statements is related to de-bouncing the buttons.

Here's a piece of my code as an example:

```
  case 12:
    if ((millis() - millistimer) > BounceD) {
      if (receivedValue == RFb) {
        magnetDistance += 5;
        millistimer = millis();
        receivedValue = 0;
      }
    }
    if ((millis() - millistimer) > BounceD) {
      if (receivedValue == RFd) {
        magnetDistance -= 5;
        millistimer = millis();
        receivedValue = 0;
      }
    }
    break;

```

The de-bouncing actions happens in each and every case and for each and every button.

There's two buttons which in each `case` increase/decrease different values.

How to avoid repeating the de-bouncing action for every button?

---

**EDIT:**

The `recievedValue` is updated via RC buttons value once any button is pressed on the remote.

# Answer
In the short example of above, first find out what is a duplicate (the two outer `if` statements including their body), than the differences:

* Rfb versus Rfd
* +5 versus -5

Than make a function for the duplicated code, and turn all differences into a parameter (I don't know the type of Rfd, so I take an int for it).

You will get:

```
case 12:
  processButton(&Rfb,  5); // Offset magnet distance by +5
  processButton(&RFd, -5); // Offset magnet distance by -5
  break;

  ...

void processButton(int* rf, int diff)
{
  if ((millis() - millistimer) > BounceD) {
    if (receivedValue == *rf) {
      magnetDistance += diff;
      millistimer = millis();
      *rf = 0;
    }
  }
}

```

Note that if `magnetDistance` and `millistimer` are local variables you also have to pass them (as pointer to change the value), if they are globals you can keep the code as is above.

**UPDATE**

The way parameter works is as follows. E.g.

```
processButton(Rfb,  5);

```

Will call the following function:

```
void processButton(int rf, int diff)

```

Where value rf will be Rfb, and diff will be 5 (+5).

Thus when `magnetDistance += diff;` is executed, diff will be +5 and magnetDistance will be increased with +5. In the next call, magnetDistance will be -5 and thus will be subtracted.

**UPDATE 2**

To change a variable, you have to pass it as pointer, otherwise the (copied) parameter value will be changed and not return its value to the called function. So you have to give the parameter as an address (& operator), and use -\> instead of . to get to the value.
> 2 votes

---
Tags: programming
---


title: Connect 20 12v led to an arduino mega

text:
# Question
Title: Connect 20 12v led to an arduino mega
I want to control about 20 leds with an arduino mega. This leds works with 12v voltage.

I tried to put 20 relays but this solution is not good for me because leds will often blink

I have also tried transistors but it needs to make a pcb.

I am looking for a solution without having to create a pcb

Any idea ?

Thanks

# Answer
> 2 votes
You can use the commonly available L298N module to drive four of your LEDs with each module. That means you would need five of them.  Those modules are suitable for driving either one stepper motor, two DC motors (in both directions), or four "unidirectional" loads such as your LEDs.

The input can be connected directly to your MEGA, but you may need additional series resistors depending on the LED you use (though this likely does not apply for LEDs specified as "12V").

There are also LED driver eval boards available which may suit your needs: https://www.digikey.de/product-detail/de/adafruit-industries-llc/1455/1528-1019-ND/4990768

# Answer
> 2 votes
The ULN2803 is a chip with 8 darlington transistors in it designed for driving higher voltage, low-ish current, loads like this. With 3 of them you have 24 channels to drive your LEDs.

You can get them on a breakout board quite easily, or as a DIP chip for working with breadboards.

# Answer
> 1 votes
Three TPIC6B595 shift registers, controlled by 3 pins from the Mega, can do this easily. Shift in 3 bytes with on/off state of the LEDs. Can sink 150mA per output from 12V source. The LEDs need current control, from simple resistor for 20mA loads, to a constant current driver per LED for higher current LEDs.

I used them to sink current from 12V for the LED strings in this display. The small digits needed ~ 20mA per segment, the larger digit is really 2 groups of 3 LEDs, drawing about 40mA per segment. One shift register per digit.

https://www.youtube.com/watch?v=6HZ0Mr51jUY

# Answer
> 0 votes
Try s MOS- FET transistor. Its not expensive and easy to drive. Can be directly connected to the Arduino. Look for standard circuit diagrams. 1 P- Mos Fet and 1 Resistor per channel, esch can drive several Amperes st 12V...

---
Tags: arduino-mega
---


# Question
Title: How do I send MIDI properly with ESP8266?
So, I've finally able to send and receive MIDI using Arduino.

My next thing to do was sending 5 pin MIDI to rtpMIDI, and vice versa, using ESP8266, but so far I can't even send MIDI correctly. So far, I used this library, and it send midi without issues with Arduino Mega. But using Wemos D1, strange thing happens.

this is output of MIDI OX. Pretty sure I wasn't sending MIDI CC.

Here's the code so far :

```
#include <MIDI.h>

 // Created and binds the MIDI interface to the default hardware Serial port
 MIDI_CREATE_DEFAULT_INSTANCE();

 void setup()
 {
     MIDI.begin(MIDI_CHANNEL_OMNI);  // Listen to all incoming messages
 }

 void loop()
 {
     // Send note 42 with velocity 127 on channel 1
     MIDI.sendNoteOn(42, 127, 1);

     // Read incoming messages
     MIDI.read();
 }

```

UPDATE : Here goes the settings.
Any reason why this happens? Please help me. Thanks!

Schematics :
Basically I just change the Arduino to Wemos D1 Uno.

# Answer
> 1 votes
NOTE : Probably not the answer you're looking for, but it works for me.
Solution : Move the jumper from 5V to Vin.
Why? I don't know. It just works.
Please notice that this is Wemos D1 Uno, which has adaptor input, which can receive 9-24V.
If you're going to use the adaptor, **IT MAY BROKE YOUR MIDI DEVICE!**
As far as I know, Vin stands for Voltage Input, and everything from the adaptor is routed there. That means if you use 24v adaptor, Vin is 24v!
I'm only planning to use USB as power supply, so yeah. it works for me.
If you're going to use Vin with external power supply, please use voltage regulator to 5v. Better safe than sorry.
Anyway, since I'm planning to use 6N137 to receive MIDI also on this board, here goes :

> Input voltages greater than 7 V must be avoided to preclude damage to the gate oxide of the input stage. This damage is not necessarily permanent, but will adversely affect the expected lifetime of the circuit. The gate oxide of AHC devices is only 200 Å thick. An input voltage of 7 V corresponds to a field strength over the gate oxide of 350 kV/cm. Although breakdown of the oxide is expected only at input voltages above 10 V, electrons tunnel increasingly into the gate oxide at field strengths greater than 350 kV/cm, influencing characteristics of the transistors and causing failure.

Source : this question on electronics stackexchange.

---
Tags: esp8266, midi
---


title: Software I2C - sending data

text:
# Question
Title: Software I2C - sending data
I'm trying to read a voltage in from a power supply to an Arduino Micro, then send it to an oscilloscope through an I2C (MCP4725). I would use the default pins on the Micro but I want to wire three I2C and the default bus only allows two. As such, I'm trying to use the SoftI2CMaster library

I've looked through examples and documentation but I can't seem to get it to send any data. I've been successful scanning (from examples) and finding the I2C addresses, so I assume that the trouble is at the end of my code.

Any tips would be greatly appreciated!

```
#define SDA_PORT PORTD
#define SDA_PIN 4 // = A4
#define SCL_PORT PORTC
#define SCL_PIN 6 // = A5
#include <SoftWire.h>

#define I2C_7BITADDR 0x62 //MCP4725

SoftWire Wire = SoftWire();

int aPin;

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

void loop(void){
  aPin = analogRead(A0); //read in from power supply
  Wire.beginTransmission(I2C_7BITADDR);
  Wire.write(aPin); //send voltage to osc.
  Wire.endTransmission();
}

```

# Answer
The main problem seems to be, that you are not adhering to the MCP's communication protocol. You just try to directly and only send the pure analog measurement to it.

Look at this image from page 18 of the MCP4725's datasheet:

It describes the operation is Fast Mode, which seems to be the correct mode for this. (Similar descriptions for the other modes can be found below that image). The first byte is done by the SoftWire library, but the following is your responsibility. The next 2 bytes consist (in this order) of 2 bit's setting the Fast Mode, 2 bit's for the devices power down select (both zero for normal DAC operation) and then the 12 bits of the actual voltage value for the DAC.

At this point I will show another problem with your code. You read an analog voltage with the Arduinos ADC, which is a 10 bit number (of type `int`) and use it in

```
Wire.write(aPin);

```

But the parameter for `Wire.write()` is defined as `uint8_t` (see line92 in SoftWire.h of the Softwire library), which means, that your `int` value get's casted and you loose all bits above 255 (the lower byte), because `uint8_t` just cannot store more.

**What you have to do:** You should put the I2C data bytes together in your code and then send them. This may look like this:

```
byte byte1 = (aPin & 0x0F00) >> 8;
byte byte2 = (aPin & 0xFF);

```

This code uses bitwise operators. The `&` will do an AND operation, the `>>` shifts the bits to the right by the amount after the operator. The `0x` denotes a value in hex representation (binary representation would be `0b`). So for the first byte we are doing an AND with the value `0x0F00`, which will give us a value with only the first 4 bits of the second byte of `aPin`. Then we shift the result 8 bits to the right, so that the remaining data is nicely aligned to the right of your byte. We don't need to include the mode bits and power down select bits here, since they are zero anyway. If you want to set them non-zero you could bitwise OR them (of course with the correct shift, so that the bits have the correct position in the resulting byte):

```
byte mode_bits = 0b10;
byte power_down_bits = 0b11;
byte byte1 = (mode_bits << 6) | (power_down_bits << 4) | (aPin & 0x0F00) >> 8;

```

Then you can send these bytes out with I2C:

```
Wire.beginTransmission(I2C_7BITADDR);
Wire.write(byte1);
Wire.write(byte2);
Wire.endTransmission();

```

That should work, though note, that I have not tested this. I just read the datasheet, which is always a must read.

**What happened with your original code:** The datasheet states for the command "Write DAC Register" (which uses 4 bytes including the address byte) the following:

> The device ignores any partially received data bytes if the I2C communication with the Master ends before completing the 4th byte.

So it just drops any I2C messages, that are not complete. Though it is not stated clearly, we can be pretty sure, that the same happens also for the other operation modes. You were sending only 1 byte, so the MCP found the message incomplete and ignored it.

---

That said, there is a principle to work around the limit of only 2 devices on the same bus, which I also only learned recently about. You might not wanna go this way here, but it's a great idea and a valid solution to the problem with the limit.

Every MCP has 1 address pin A0, which set's 1 bit of the address, resulting in 2 possible addresses. On an I2C bus there must not be more than 1 device with the same address. But if that doubled address is never called, the bus doesn't have a problem.

You would connect the A0 pins of each MCP to one digital output pin of the Arduino each. By setting the state of these output pins you can change the address of the MCPs (requirement is, that the MCP actually checks the A0 pin during operation, but the datasheet seems to suggest this). Now you keep every A0 pin on one level, so that all MCPs have the same address. To communicate with one, you would change the state of it's A0 pin to change it's address. Now this MCP is the only MCP with this address (all other MCPs have the other address). You can now communicate with it. When you want to communicate with another MCP, you reset the first MCPs A0 pin and then change the next MCPs A0 pin.

That way you make sure, that on one of the two addresses, there will always be 1 MCP at maximum, while you never use the other address. You can use as many MCPs, as you have digital output pins to change their addresses.
> 3 votes

---
Tags: i2c, arduino-micro, software
---


title: Refactoring bad design?

text:
# Question
Title: Refactoring bad design?
Could someone help me how to refactor old very complex code ?

Original used just setup and everything else was in single ISR. But as it was bigger and bigger, code is quite slow and quite random sometimes, even PC emulator did not helpped much (probably some long operations like printing are sometimes interrupted by next interrupt depending on analog values, buttons, etc.).

Is there any guide how to maintain such a project or is there only way out start again from scratch ?

As there are few important regulations also event queue would be needed, but not sure if there is any pattern or a template to start from in case of restart. A-Star 32U4 Micro has \<32kB flash and code is hard to fit in yet (there are also big fonts).

*Example of font unpack code, but hope this part is quite ok:*

```
void Adafruit_GFX::drawChar(int16_t x, int16_t y, unsigned char c,
  uint16_t color, uint16_t bg, uint8_t size) {
...
    uint8_t blockSize = 0;
    if(packed) blockSize = pgm_read_byte(&bitmap[bo++]); // for first char pick 1st bit array only
    BitStreamsReader bitStream(&bitmap[bo++], packed?blockSize:0); // ptr, blockSize(if packed)
    BitXorBuffer rowXorBuf(w); // row XOR buffer (each row is XORed with)
    bool chk;
    for(yy=0; yy<h; yy++) {
        rowXorBuf.rewind();
        for(xx=0; xx<w; xx++) {
            chk = bitStream; // read 1b
            if(packed) chk = rowXorBuf.xorMove(chk); // xor with XOR buffer
            if(chk) {
                if(size == 1) {
                    writePixel(x+xo+xx, y+yo+yy, color);
                } else {
                    writeFillRect(x+(xo16+xx)*size, y+(yo16+yy)*size,
                        size, size, color);
                }
            }
        }
    }
...

class BitStreamsReader {
public:
    BitStreamsReader(uint8_t *arr, unsigned int maxSize) {
        blockSize = maxSize;
        bitMask = 0x80;
        bytePtr = arr;
        zerosCount = 0;
        remainingBits = 0;
        markBitInit();
    }
    operator bool() {
        if(!blockSize) { // unpacked stream
            bool retVal = !!(pgm_read_byte(bytePtr) & bitMask);
            next();
            return retVal;
        } else if(remainingBits) {
            bool retVal = !!(pgm_read_byte(bytePtr) & bitMask);
            next();
            if(!--remainingBits) {
                markBitInit();
            }
            return retVal;
        } else if(zerosCount) {
            if(!--zerosCount) {
                markBitInit();
            }
            return 0;
        }
        return 0; //throw "??";
    }
private:
    void markBitInit() {
        if(blockSize) {
            if(pgm_read_byte(bytePtr) & bitMask) {
                remainingBits = blockSize;
            } else {
                zerosCount = blockSize;
            }
            next();
        }
    }
    void next () {
        if(bitMask == 0x01) {
            bitMask = 0x80;
            bytePtr++;
        } else {
            bitMask >>= 1;
        }
    };
    uint8_t *bytePtr, bitMask, zerosCount, remainingBits, blockSize;
};

class BitXorBuffer {
public:
    BitXorBuffer(int bufSize) {
        bufSize = bufSize/8+!!(bufSize&7);
        bitBuf = new uint8_t[bufSize];
        memset(bitBuf, 0, bufSize);
        rewind();
    }
    ~BitXorBuffer() {
        delete[] bitBuf;
    }
    void rewind() {
        bitMask = 128;
        bytePtr = bitBuf;
    }
    bool xorMove(bool by) {
        if(bitMask & *bytePtr) by ^= true;
        *bytePtr |= bitMask;
        if(!by) {
                *bytePtr ^= bitMask;
        }
        nextBit();
        return by;
    }
private:
    void nextBit() {
        if(bitMask > 1) {
            bitMask >>= 1; // move bit in XOR buffer
        } else {
            bitMask = 128;
            bytePtr++;
        }
    }
    uint8_t *bytePtr, *bitBuf, bitMask;
};

```

# Answer
I will try to answer your question as good as possible, though it is quite broad.

To my knowing there is no ONE design pattern or template, that fit's all cases. But depending on the actual functions of your code you can go different ways using libraries (which are somewhat like templates in this sense).

You can get easy multitasking by using libraries like FreeRTOS. You might even find a compatible version of SafeRTOS, a sibling of FreeRTOS, which has a bigger focus on security. Though the whole RTOS thing might not be right for you and it needs your code to be mostly rewritten/redesigned.

Depending on what ISRs are used and what they are for, you might really need to use interrupts to let the device react immediately. In that case you basically have not choice, but to refactor the whole code as described in the comments (moving as much code as possible to the main loop, making the ISR drastically smaller). For this here some general advice:

* First make a graph of the devices function as it should be. Identify code portions that have a common function, but them into blocks, draw arrows between the blocks to show, how they are connected logically. Then identify which portions are really time critical and what the time contrains are (e.g. Do you need the device to react to an event within a few clock cycles or is it ok, if the reaction comes a few us or ms later?). Mark how often the involved events occur at average and at maximum.
* Now look at the code blocks directly. Which of them need interrupts to work and what happens with them, if interrupts are turned of during their operation (since - as you already identified - reactivating interrupts inside an ISR can get very messy). For example with interrupts off, Serial prints will not be send directly (because this relies on interrupts). Instead the libraries buffer will be filled. When the buffer is already full, a print will wait for the buffer to empty a big (which does not happen with interrupts off).
* Move all code, that is not really time critical, into an if statement in the main loop function. The if statement should be activated by a flag, that would be set in the ISR (be sure to declare it volatile).
* Make sure, that there is nothing blocking in your code (no `delay()`, no waiting for an event in an infinite loop). That also might require serious refactoring, but it's important if you want a fast reaction also outside of the ISR. You might want to look into Finite State Machines for this (they are quite easy to implement and a very powerful construct).
* Keep debug prints small, so that it cannot mess up your timing.
* Lastly: Make some documentation. That is mostly reglected, because it is not that rewarding, but it can save many hours for the next programmer, that needs to maintain your code.

That might seem very time consuming, difficult and not like the comprehensive guide you were looking for. That's the reason, why maintaining legacy code is mostly a real pain in the a\*** and does cost companies a lot of money.

At one point or another the technical debt has to be paid. The inventor of the code clearly didn't (or he/she would't have written an ISR this big), so now you will most likely have to go the hard way.
> 1 votes

---
Tags: programming, code-review, code-optimization
---


# Question
Title: 16/2 arduino I2C lcd display not lighting up?
I am working with an I2C lcd display with an arduino uno board I have connected the gnd pin to gnd of arduino uno and the vcc pin to 5V of arduino uno and the display is not even lighting up there is only a red led lighting up on the back so I tryed connecting the rest of the pins and run a code to detect the i2c display and it worked successfully I got the adress but the lcd did not light up. The lcd display is a new one I bought yesterday here are the pictures:

https://photos.app.goo.gl/x9QPAWig98yLg4DW9

The script I tryed to display text was this one with the NewLiquidCristal library:

```
//Libraries
#include <Wire.h>
#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x3F, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);  // Set the
LCD I2C address, if it's not working try 0x27.

void setup(){
lcd.begin(16,2);   // iInit the LCD for 16 chars 2 lines
lcd.backlight();   // Turn on the backligt (try lcd.noBaklight() to turn it
off)
lcd.setCursor(0,0); //First line
lcd.print("I2C LCD Tutorial");
lcd.setCursor(0,1); //Second line
lcd.print("*Ardumotive.com*");
}

```

Here is the model nmber of the I2C: PCF8574A And the lcd is a QAPASS Ui also I don't have a spec sheet and the LCD seems to show empty chars when rotating the pot.

# Answer
Try this:

```
#include <Wire.h>
#include <LiquidCrystal_I2C.h>

// LiquidCrystal_I2C lcd(0x27, 16, 2);
// OR
LiquidCrystal_I2C lcd(0x3F, 16, 2);

void setup(){
lcd.begin();
lcd.backlight();
lcd.setCursor(5,0);
lcd.print("TA DAA...!");
}
void loop{
// do nothing here
}

```

If that didn't work probably your LCD have a different address than `0x27` which in that case you should run a I2C scanner to show you the addresses of I2Cs that connected to your Arduino:

```
#include <Wire.h>
// I2C scanner

void setup()
{
  Wire.begin();

  Serial.begin(9600);
  Serial.println("\nI2C Scanner");
}

void loop()
{
  byte error, address;
  int nDevices;

  Serial.println("Scanning...");

  nDevices = 0;
  for(address = 1; address < 127; address++ )
  {
    // The i2c_scanner uses the return value of
    // the Write.endTransmisstion to see if
    // a device did acknowledge to the address.
    Wire.beginTransmission(address);
    error = Wire.endTransmission();

    if (error == 0)
    {
      Serial.print("I2C device found at address 0x");
      if (address<16)
        Serial.print("0");
      Serial.print(address,HEX);
      Serial.println("  !");

      nDevices++;
    }
    else if (error==4)
    {
      Serial.print("Unknow error at address 0x");
      if (address<16)
        Serial.print("0");
      Serial.println(address,HEX);
    }
  }
  if (nDevices == 0)
    Serial.println("No I2C devices found\n");
  else
    Serial.println("done\n");

  delay(5000);           // wait 5 seconds for next scan
}

```

Check the jumper behind the I2C module (plug it out and in again).

Check the voltage of LED using a multimeter if there's no voltage there, *maybe* it's just a "bad LCD" try replacing it.
> 2 votes

---
Tags: arduino-uno, i2c, lcd
---


# Question
Title: Rate of serial communication (UART) of a sensor is faster than speed of processing of microcontroller
I have a Vector Nav VN100 IMU sensor that sends data serially UART. I have interfaced it with ATmega32. It receives data (ROLL angel) from the sensor and according to the ROLL angel, it controls a servo motor.

My question, if the sending rate is faster than processing speed of the ATmega32, then some data from the sensor will be dropped. How to overcome this problem?

# Answer
> 1 votes
When using an embedded processor's hardware implemented UART, it is often the case that the rate at which the software processes the data is a fraction of the Gross bit rate some times referred to as the Baud rate. If the UART is configured to handle 8 bit RS-232 where the Gross bit rate is 10000 bits per second, the processor only has to handle data at a faction of that rate. Perhaps 1/10 given several bits of over head and space between characters.

Processor intervention can be further reduced if the hardware UART contains several bytes of buffering. For every doubling of the number of hardware supported bytes of buffering, processor interventions events are cut in half.

Beyond this, there are embedded processors in which the UART supports DMA or Direct Memory Accessing. This is where the hardware UART will write the received data directly into the processor's memory with out need of processor intervention. This feature is usually only found on feature rich embedded processors.

Study this PDF to understand the abilities and limitations of the ATmega32 processor. Specifically the USART section starting on page 140.

---
Tags: serial, avr, eeprom
---


# Question
Title: ESP - Nodemcu amica - attachInterrupt crash program
I get new boards from the shop but they are little different from the previous version. I got software what works ok on Nodemcu lolin v3 now I get Nodemcu Amica what is almost same board but if I got attachInterrupt function in the program it crashes immediately.

```
    attachInterrupt(6, bowlingCall, RISING);
//attachInterrupt(digitalPinToInterrupt(D1), statekCall, RISING);

```

I try different pins but not change. I debug all program(comment all out and left just attachInterrupt and it crashes again).

```
    ets Jan  8 2013,rst cause:2, boot mode:(3,6)

load 0x4010f000, len 1384, room 16
tail 8
chksum 0x2d
csum 0x2d
v8b899c12
~ld

```

The board cycle in the reboot sequence, even serial output do not work ok. Why did esp crash at attachInterupt on this board?

# Answer
thanks @Juraj.

Ok, so all you need is rewrite all your interrupt function. For example:

```
void getStatusFromMaster()

```

to

```
void ICACHE_RAM_ATTR getStatusFromMaster()

```
> 1 votes

---
Tags: esp8266, interrupt, nodemcu, debugging
---


title: Update `char* `

text:
# Question
Title: Update `char* `
I have a class containing few `char*` variables:

```
char* msgTopic     = "myHome/MSGS";
char* groupTopic   = "myHome/All";
char* errorTopic   = "myHome/Err";

```

but, I wish to have it defined outside the class and not hardcoded (update only `prefixTopic` outside the class,

```
char* prefixTopic  = "myHome";
char* msgTopic     = ""; // also tried-->  char* msgTopic = "AAAAAAAAAAA";
char* groupTopic   = "";
char* errorTopic   = "";

```

and then, down the code to have it defined as:

```
sprintf(msgTopic  ,"%s/Messages",prefixTopic);
sprintf(groupTopic,"%s/All",prefixTopic);
sprintf(errorTopic,"%s/Errors",prefixTopic);

```

**BUT**

both ways ( when defining variables as `""`, or just filled it up with chars to allocate space) caused topics to be defined with errors ( mostly - one variable contained both topics ).

Appreciated any help ( I don't think context of class is relevant )

# Answer
> 2 votes
First, you have to think about using dynamic or pre-allocated strings. Dynamic memory is not recommended for Arduino, so I will use pre-allocated strings.

In that case you need to think about the maximum length, I will take 32 for now:

```
#include <stdio.h>

class YourClass
{
  static const int MaxTopicLength = 32;

  char _msgTopic[MaxTopicLength];
  char _groupTopic[MaxTopicLength];
  char _errorTopic[MaxTopicLength];

  void FillStrings(const char* prefixTopic);
};

```

Than create in your class a function to fill the strings (untested):

```
void YourClass::FillStrings(const char* prefixTopic)
{
  snprintf(_msgTopic  , MaxTopicLength, "%s/Messages", prefixTopic);
  snprintf(_groupTopic, MaxTopicLength, "%s/All"     , prefixTopic);
  snprintf(_errorTopic, MaxTopicLength, "%s/Errors"  , prefixTopic);
}

```

---
Tags: string, pointer
---


# Question
Title: Arduino digital pin status not transmitting via NRF24L01 where as analog pin status is getting transmitted ,Why?
I am currently working with a project using NRF24L01 which I integrated with my Joystick so that I can make it wireless.While transmitting the information in my Joystick to the receiver only analog pin status is getting transmitted where as digital pin status is not getting transmitted.

```
Transmitter Code:

#include <nRF24L01.h>
#include <printf.h>
#include <RF24.h>
#include <RF24_config.h>
#include <SPI.h>
#include <Wire.h>

//Define the digital inputs
#define tGL1 7
#define tGL2 6
#define b1 5
#define b2 4
#define b3 3
#define b4 2

const int MPU = 0x68; // MPU6050 I2C address
float AccX, AccY, AccZ;
float GyroX, GyroY, GyroZ;
float accAngleX, accAngleY, gyroAngleX, gyroAngleY;
float angleX, angleY;
float AccErrorX, AccErrorY, GyroErrorX, GyroErrorY;
float elapsedTime, currentTime, previousTime;
int c = 0;

RF24 radio(9,10);
const byte address[6]="00001";

struct Data_Package {
  byte j1PotX;
  byte j1PotY;
  byte j2PotX;
  byte j2PotY;
  byte button1;
  byte button2;
  byte button3;
  byte button4;
  byte tSwitch1;
  byte tSwitch2;
  byte pot1;
  byte pot2;
};

Data_Package data;

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  initialize_MPU6050();

  radio.begin();
  radio.openWritingPipe(address);
  radio.setAutoAck(false);
  radio.setDataRate(RF24_250KBPS);
  radio.setPALevel(RF24_PA_LOW);

  pinMode(tGL1, INPUT_PULLUP);
  pinMode(tGL2, INPUT_PULLUP);
  pinMode(b1, INPUT_PULLUP);
  pinMode(b2, INPUT_PULLUP);
  pinMode(b3, INPUT_PULLUP);
  pinMode(b4, INPUT_PULLUP);

   data.j1PotX = 127; // Values from 0 to 255. When Joystick is in resting position, the value is in the middle, or 127. We actually map the pot value from 0 to 1023 to 0 to 255 because that's one BYTE value
   data.j1PotY = 127;
   data.j2PotX = 127;
    data.j2PotY = 127;
//  data.j1Button = 1;
//  data.j2Button = 1;
  data.pot1 = 1;
  data.pot2 = 1;
  data.tSwitch1 = 1;
  data.tSwitch2 = 1;
  data.button1 = 1;
  data.button2 = 1;
  data.button3 = 1;
  data.button4 = 1;

}

void loop() {
  // put your main code here, to run repeatedly:
  data.j1PotX = map(analogRead(A2), 0, 1023, 0, 255); // Convert the analog read value from 0 to 1023 into a BYTE value from 0 to 255
  data.j1PotY = map(analogRead(A1), 0, 1023, 0, 255);
  data.j2PotX = map(analogRead(A3), 0, 1023, 0, 255);
  data.j2PotY = map(analogRead(A0), 0, 1023, 0, 255);
  data.pot1 = map(analogRead(A7), 0, 1023, 0, 255);
  data.pot2 = map(analogRead(A6), 0, 1023, 0, 255);

  data.tSwitch2 = digitalRead(tGL2);

  data.button1 = digitalRead(b1);
  data.button2 = digitalRead(b2);
  data.button3 = digitalRead(b3);
  data.button4 = digitalRead(b4);

  if (digitalRead(tGL1) == 0) {
    read_IMU();    // Use MPU6050 instead of Joystick 1 for controling left, right, forward and backward movements
  }

  radio.write(&data, sizeof(Data_Package));
}

```

This is the Reciever Code

```
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
RF24 radio(9, 10);   // nRF24L01 (CE, CSN)
const byte address[6] = "00001";
unsigned long lastReceiveTime = 0;
unsigned long currentTime = 0;
// Max size of this struct is 32 bytes - NRF24L01 buffer limit
struct Data_Package {
  byte j1PotX;
  byte j1PotY;
  byte j2PotX;
  byte j2PotY;
  byte pot1;
  byte pot2;
  byte tSwitch1;
  byte tSwitch2;
  byte button1;
  byte button2;
  byte button3;
  byte button4;
};
Data_Package data; //Create a variable with the above structure
void setup() {
  Serial.begin(9600);
  radio.begin();
  radio.openReadingPipe(0, address);
  radio.setAutoAck(false);
  radio.setDataRate(RF24_250KBPS);
  radio.setPALevel(RF24_PA_LOW);
  radio.startListening(); //  Set the module as receiver
  resetData();
}
void loop() {
  // Check whether there is data to be received
  if (radio.available()) {
    radio.read(&data, sizeof(Data_Package)); // Read the whole data and store it into the 'data' structure
    lastReceiveTime = millis(); // At this moment we have received the data
  }
  // Check whether we keep receving data, or we have a connection between the two modules
  currentTime = millis();
  if ( currentTime - lastReceiveTime > 1000 ) { // If current time is more then 1 second since we have recived the last data, that means we have lost connection
    resetData(); // If connection is lost, reset the data. It prevents unwanted behavior, for example if a drone has a throttle up and we lose connection, it can keep flying unless we reset the values
  }
  // Print the data in the Serial Monitor
  Serial.print("j1PotX: ");
  Serial.print(data.j1PotX);
  Serial.print("; j1PotY: ");
  Serial.print(data.j1PotY);
  Serial.print("; button1: ");
  Serial.print(data.button1);
  Serial.print("; j2PotX: ");
  Serial.println(data.j2PotX);
}

```

When I print the status of the buttons and Joystick in my transmitter(Joystick) I get the correct status of my push button when I press but the status of my push button remain unchanged in the Serial monitor of my Receiver despite there is change other values (I mean the analog value is transmitting correctly)

This the screenshot of my both serial Monitor

# Answer
As Mikael Patel mentions in the comments: your structures do not match between the transmitter and receiver.

```
Transmitter               Receiver
=====================     =====================
struct Data_Package {     struct Data_Package {
      byte j1PotX;    ->      byte j1PotX;
      byte j1PotY;    ->      byte j1PotY;
      byte j2PotX;    ->      byte j2PotX;
      byte j2PotY;    ->      byte j2PotY;
      byte button1;   ->      byte pot1;
      byte button2;   ->      byte pot2;
      byte button3;   ->      byte tSwitch1;
      byte button4;   ->      byte tSwitch2;
      byte tSwitch1;  ->      byte button1;
      byte tSwitch2;  ->      byte button2;
      byte pot1;      ->      byte button3;
      byte pot2;      ->      byte button4;
};                        };

```

With structures, what matters is *not* what each field is called. What matters is the position of the fields in the list. When you compile your code all the names are lost. All that is left is where in the list each entry is.

The best way of avoiding this problem is to have a single header file (make it a library so it's easy to share) that contains the packet structure. Then if you ever make any changes to the packet all the sketches that use it see that change the next time you compile them.
> 2 votes

---
Tags: arduino-uno, arduino-ide, arduino-nano, nrf24l01+, wireless
---


title: RTC timer set point problem

text:
# Question
Title: RTC timer set point problem
This is the timer part of my code:

```
int onHourONE = 11;
int onMinuteONE = 00;
int offHourONE = 23;
int offMinuteONE = 00;
byte PWMstatus = 0;

void setup{}

void loop{
    if ((now.hour() >= onHourONE) && (now.minute() >= onMinuteONE)) {
      PWMstatus = 1;
    }
    if ((now.hour() >= offHourONE) && (now.minute() >= offMinuteONE)) {
      PWMstatus = 2;
    }
    if (PWMstatus == 1) {
      // do this
    }
    if (PWMstatus == 2) {
      // do that
}

```

It's working just fine but the problem is if i set the `offhourONE` less than `onhourONE` it will keep the LED OFF.

for example the time is now 14:00

`onhourONE` and `offminuteONE` is also set on 14:00

`offhourONE` and `offminuteONE` is set on 13:00

So in this case it should keep the LED ON until tomorrow 13:00 **but** it stays OFF obviously because of this statement:

```
if ((now.hour() >= offHourONE) && (now.minute() >= offMinuteONE)) {}

```

I can change that to this:

```
if ((now.hour() == offHourONE) && (now.minute() == offMinuteONE)) {}

```

But then it will only turn OFF the LED at that specific time, in this case if i restart the Arduino like 1 minute after it turned OFF it will turn on again while it should stay off until it reaches the set point of turn ON.

*I know it sounds simple but seems confusing to me, any guidance appreciated...*

# Answer
> 2 votes
You need to add more logic to your program.

As mentioned in another answer you really want to be working with just the highest resolution time interval that matters to you - that is minutes in your case. Convert your hour and minutes of the day into the number of minutes since midnight:

```
onTime = onHourONE * 60 + onMinuteONE;
offTime = offHourONE * 60 + offHourONE;

```

And convert the current time to minutes since midnight:

```
timeNow = now.hour() * 60 + now.minute();

```

Now comes the tricky bit, but since you are now just working with single numbers it's far easier. You now need to work out *what* you are doing.

You have a couple of scenarios:

1. onTime \< offTime - eg: 12:00 to 17:00
2. onTime \> offTime - eg: 21:00 to 03:00

You need to make your decision in a different way depending on which scenario you are in - and comparing a single number with a single number is so much easier than messing with hours and minutes.

So, you can do something like:

```
if (onTime < offTime) {
    if ((timeNow >= onTime) && (timeNow < offTime)) {
      // On!
    } else {
      // Off!
    }
} else {
    if ((timeNow >= onTime) || (timeNow < offTime)) {
      // On!
    } else {
      // Off!
    }
}

```

In English:

* If the start time is before the end time:
    + If the time is both greater than the start time and less than the end time, then it's on.
    + Otherwise it's off.
* Otherwise, of the start time is after the end time:
    + If the time is greater than the start time, *or* it's less than the end time, then it's on.
    + Otherwise it's off.

# Answer
> 1 votes
If it overly complicated to use a combination of seconds, minutes and hours for comparisons. For this you can use the time in seconds, as you get it with `now.secondstime()` or `now.unixtime()`. If you don't want to look at the seconds (so only values multiple to 60), you can do an integer division to get the minutes `now.secondstime()/60`.

To calculate the needed limit values from the combination of hour and minutes, just multiply according to the unit. For seconds `(hour*60+minutes)*60`. For minutes `hour*60+minutes`.

---
Tags: programming
---


# Question
Title: Is there a simple HTTP(S) library that doesn't rely on WiFi?
I'm trying to implement a Mobile Network (only) for the ESP32 using Arduino IDE. So to be able to connect to website up/download files etc. I need to be able to handle various HTTP PUT/GET/POST requests. However, the available libraries seem to always rely on additional WiFi related libraries. I don't want to have to load those as well, as they are quire bloated and not needed for my use scenario.

What options do I have for minimalist HTTP request libraries that does not rely on WiFi or BT or ETH?

# Answer
> 2 votes
The TinyGSM library implements Arduino networking Client base class over GSM modem's AT commands. The library is available in Library Manager.

---
Tags: arduino-ide, library, gsm, http, core-libraries
---


# Question
Title: Timer Countdown to control relay (multiple functions in void loop)
I'm trying to build this project with a simple code. Object is to hit up button to increment minutes or down to decrement minutes then hit start to start countdown, while its counting relay will turn On light till counting is done will turn light off and if I hit end button while counting it will end counting and turn off relay.

Here is my try I would appreciate if you could support me. i can not move to countDown() function in the loop if i press start I need help to figure out a good technique of declaring functions in void loop in arduino

```
#include <LiquidCrystal.h>

LiquidCrystal lcd(1,2,4,5,6,7);

#define numberOfSeconds(num) ((num/1000) % 60 )
#define numberOfMinutes(num) (((num/1000) / 60) % 60)

//unsigned long timeLimit = 3600000; // 1000 ms in 1sec, 60secs in 1min, 60mins in 1hr. so , 1000x60x60 = 3600000ms = 1hr

const int upBtn = 8;
const int downBtn = 9;
const int startBtn = 10;
const int endBtn = 11;

int btnPushCounter = 0;
int minutes;
int seconds;
unsigned long minutesGiven;
unsigned long timeLimit;
unsigned long timeRemaining;

int upBtnState = 0;
int lastUpBtnState = 0;

int downBtnState = 0;
int lastDownBtnState = 0;

int startBtnState = 0;
int lastStartBtnState = 0;

int endBtnState = 0;
int lastEndBtnState = 0;

bool bPress = false;

void setup() {

 lcd.begin(16,2);
 pinMode(upBtn, INPUT_PULLUP);
 pinMode(downBtn, INPUT_PULLUP);
 pinMode(startBtn, INPUT_PULLUP);
 pinMode(endBtn, INPUT_PULLUP);

 lcd.clear();
 lcd.setCursor(0,0);
 lcd.print("Minutes : ");
 lcd.print(btnPushCounter);
}
void loop() {

    checkUp();
    checkDown();
//    countDown();
    if(bPress){
      bPress = false;
      displayNumber();
    }
}

void displayNumber(){
    lcd.clear();
    lcd.setCursor(0,0);
    lcd.print("Minutes : ");
    lcd.print(btnPushCounter);
}

void checkUp(){
  upBtnState = digitalRead(upBtn);
  // compare the buttonState to its previous state
  if (upBtnState != lastUpBtnState) {
    // if the state has changed, increment the counter
    if (upBtnState == HIGH) {
        bPress = true;
      btnPushCounter++;
    }
    delay(50);
  }
  // save the current state as the last state, for next time through the loop
  lastUpBtnState = upBtnState;
}

void checkDown(){
  downBtnState = digitalRead(downBtn);

  // compare the buttonState to its previous state
  if (downBtnState != lastDownBtnState && btnPushCounter != 0 ) {
    // if the state has changed, increment the counter
    if (downBtnState == HIGH) {
        bPress = true;
      btnPushCounter--;
    }
    // Delay a little bit to avoid bouncing
    delay(50);
  }
  // save the current state as the last state, for next time through the loop
  lastDownBtnState = downBtnState;
}

void checkStart(){
  startBtnState = digitalRead(startBtn);
  if(startBtnState != lastStartBtnState){
    if(startBtnState == HIGH){
      bPress = true;
//      lcd.
    }
  }
}

void countDown() {
//  unsigned long timeLimit = 3600000;
  minutesGiven = btnPushCounter;
  timeLimit = minutesGiven * 1000 * 60;
  timeRemaining = timeLimit - millis();
  while(timeRemaining > 0){
    seconds = numberOfSeconds(timeRemaining);
    minutes = numberOfMinutes(timeRemaining);
    lcd.setCursor(2,7);
    lcd.print(minutes);
    lcd.print(" ");
    lcd.print(seconds);
    delay(50);
    timeRemaining = timeLimit - millis();
  }
}

```

# Answer
> 1 votes
I think what you're looking for is to declare your functions near the top of your file, usually before the first function you write, `setup()`, in this case. So add this just above your `setup()` function:

```
// Forward function declarations
void displayNumber(void);
void checkUp(void);
void checkDown(void);
void checkStart(void);
void countDown(void);

```

C compilers (and thus, C++ because it was derived from C) read the source code only once through, so any function must become known to the compiler ahead of where it is first called. This would require you to place all low-level functions first, then all functions that call those, then the functions that call those, ..., etc. And there are some cases that even this arrangement won't solve, e.g., functions that call each other (oww, my brain hurts!!). So function declarations are used to avoid this inconvenience.

Declaring a function just means informing the compiler of its name, the parameter types, and the return type -- the actual function code isn't required at this point.

---
Tags: lcd, timers, relay
---


title: Serial.println() cuts off characters

text:
# Question
Title: Serial.println() cuts off characters
I want to print a string together with number. My code is

```
Serial.println("Test " + index++);

```

(In `setup()` I initialized variable `index` to 0.) In Java it would output

```
Test 0
Test 1
Test 2
Test 3
...

```

But I get this output instead:

```
Test
est
st
t

```

Can anybody explain it to me please?

# Answer
> 6 votes
`Serial.println()` prints the value of one expression. The expression you passed it was \`("Test " + index++).

In C/C++ a character literal such as "Test " evaluates to the memory address its first character. Adding 1 to that address gives the address of the next (or 2nd) character. Adding 2 to it gives the address of the 3rd character, and so on.

To get what you were expecting, the value of the literal, AND the value of the index, you would write:

```
Serial.print("Test ");
Serial.println(index++);

```

If you had created a String variable with the value "Test ", then the String expression, `("Test " + index++)` would have been evaluated differently: The "+" operator would have concatenated the String "Text ", with the String equivalent of the current value of "index"; but that isn't the way a character literal is treated. There is a C++ String library among the Arduino libraries but it's use is not recommended because Strings get reallocated and copied when they get concatenated, resulting in excessive memory use, and the Arduino has very little memory.

# Answer
> 2 votes
JRobert explains very well why it does not work.

Instead of the Serial.print you also can use the sprintf function in case you need a more complicated string to build, or in case you want to mix two different types in one line:

```
char str[100];
int index = 0;
sprintf(str, "Test %d", index++);
Serial.println(str);

```

Make sure the buffer (100) is big enough to store the full string including the end symbol ('\0').

For safety you also can use:

```
snprintf(str, 100, "Test %d", index++);

```

This will make sure max. 100 characters are filled in (and the remainder is clipped).

---
Tags: serial
---


title: Adding WiFi to my Arduino Keypad Lock

text:
# Question
Title: Adding WiFi to my Arduino Keypad Lock
I'm a really passionate beginner with arduino and electronics and I've built a Keypad lock for my room's door (inside the house).

I've used an arduino that activates a motor using a transistor to open the door if the correct pin is entered.

I want to add wifi control to my project. I have a few transistors, relays and ESP01s lying around for the upgrade. I want to use the blynk app and use the ESP01 independently without disturbing or modifying the arduino code. I'll program the ESP01 directly.

These are my requirements:

-A failsafe so I can open the lock via blynk if I forget the pin

-A kill switch that will turn off the arduino if I suspect somebody knows my PIN.

These are my ideas:

-Can I directly connect an ESP GPIO pin to the base of the transistor where the arduino is connected? By doing this can I control the transistor to switch the motor via both the arduino and the ESP 01?

-Can I put a relay module between the arduino and the battery pack and connect it to the ESP? I will connect the relay so that it will disconnect power to the arduino only when powered on. Is this a viable solution for a kill switch?

Any suggestions and ideas about how to go about this will be highly appreciated.

# Answer
> 1 votes
> Can I directly connect an ESP GPIO pin to the base of the transistor where the arduino is connected?

No. You will effectively be connecting two outputs together, and that is very bad.

Instead you will need to add a second transistor in parallel to the first - one controlled by the Arduino and one controlled by the ESP-01.

> Can I put a relay module between the arduino and the battery pack and connect it to the ESP?

Sure. No problem with that.

> I will connect the relay so that it will disconnect power to the arduino only when powered on. Is this a viable solution for a kill switch?

As long as the kill switch doesn't also shut off power to the ESP-01 - otherwise it will just switch on again straight away...

---
Tags: esp8266, wifi, relay, iot, blynk
---


# Question
Title: about how to write data in the whole EEprom?
I have interfaced AT24c1024 EEprom with ATmega32.AT24c1024, which has 512 pages each of 256 bytes. There are two mode of writing (byte write and page write).

In page write mode, it is capable of writing 256 bytes for page; if we want to write 258 bytes, then the first two bytes in the beginning of that page will be overwritten.

My question is: what should I do to write in the whole EEprom (i.e) if I want to write 300 bytes, I want to writes 256 bytes in a page then continues to the next page and so on?

# Answer
In that case you write two pages, the first page containing the first 256 bytes and the second page containing the following 34 bytes.

You can do a speed check to see if writing the second page's 34 bytes by using the byte write is faster, but I doubt that.

In case you want to keep from the second page the remainder of the 34 bytes (the 256-34 bytes following), you first read the second page, than you change the first 34 bytes, than write it back.

Also note that there is a limit on the number of writes on a page. This is called page wearing. So if you write these 2 pages very often, you might want to come up with an algorithm to rotate through all the available pages in your EEPROM, and not writing every time to the same 2 pages.

**EXAMPLE**

Assume you want to write totalBytesToWrite:

```
// Calculate the number of pages to write, round up.
int pagesToWrite = int((totalBytesToWrite + 255) / 256;

for (int page = 0; page < pagesToWrite; page++) // Current page to be written
{
    // Calculate number of bytes to be written in this page, for the last page, write remaining bytes, otherwise 256
    int pageBytesToWrite = (page == pagesToWrite - 1 ? totalBytesToWrite % 256 : 256;

    // Write page (btw, I do not know what the second argument char deviceAddress means)
    page_write(n / 256, ??, &memory[n], pageBytesToWrite);
}

```
> 1 votes

---
Tags: serial, i2c, avr, eeprom
---


# Question
Title: Communication between arduino nano and MCP3424 over I2c
I'm am completing a project of mine that uses an MCP3424 i2c 18bit ADC and an arduino nano to measure temperature with an NTC thermistor but am having trouble with the arduino wire library. This is my first project using i2c so I'm not very knowledgeable about the subject but I have rigorously read the datasheet of the MCP3424 that can be found at (http://ww1.microchip.com/downloads/en/devicedoc/22088b.pdf) and tried many different ways to get it working. Also I'm new to posting on this stackexchange so pardon me if my syntax and what not is not right(I'm doing my best). Here is the code I have so far that is on my arduino.

```
#include<Wire.h>

#define ReadMode 0xDD //Device will output conversion data (7 bits, device address. 1 bit, Read/Write mode)
#define WriteMode 0xDC //Device expects config byte (7 bits, device address. 1 bit, Read/Write mode)
#define ConfigByte18 0x8c //PGA = 1, SPS = 3.75, One-Shot mode, channel 1, initiate new conversion.
#define ConfigByte16 0x88 //PGA = 1, SPS = 15, One-Shot mode, channel 1, initiate new conversion.

void setup() {
  Serial.begin(9600);//Initiate Connection to computer
  Wire.begin();//Initiate Wire library
  Wire.setClock(100000);//make sure clock speed is standard mode
  delay(500);//Allow boot up and settle of ADC
  Wire.beginTransmission(WriteMode);//begin transmission with ADC in Write mode
  Wire.write(ConfigByte18);//configure the ADC with settings found in "ConfigByte18"
  Wire.endTransmission();
  Serial.print("Everything worked\n");

}

void loop() {
  unsigned char x, y, z, a, b, c;
  //Serial.println("Bytes ready to be read:");
  Wire.begin();
  Wire.setClock(100000);//make sure clock speed is standard mode
  Wire.beginTransmission(ReadMode);//begin transmission with ADC in write mode
  Wire.requestFrom(0x6E, 6);//request 6 Bytes of information from MCP3424
  x = Wire.read();//read bytes
  delay(10);
  y = Wire.read();
  delay(10);
  z = Wire.read();
  delay(10);
  a = Wire.read();
  delay(10);
  b = Wire.read();
  delay(10);
  c = Wire.read();
  Serial.print(x);//print bytes
  Serial.print(", ");
  Serial.print(y);
  Serial.print(", ");
  Serial.print(z);
  Serial.print(", ");
  Serial.print(a, HEX);
  Serial.print(", ");
  Serial.print(b, HEX);
  Serial.print(", ");
  Serial.println(c, HEX);
  Wire.endTransmission();
  delay(1000);

}

```

So an explanation of my understanding: In the “void setup” section I begin transmission in write mode (see page 21 of datasheet to follow along with my explanation figure and table 5-3) in the begin transmission function I address the slave with 0xDC because the device address begins with 1101 (pre programmed) and then 110 as I have the two Adr pins tied to +5v and finally 0 as I want to change configuration settings. This translates to 0xDC in hexadecimal. Then I send the slave a byte of information for the configuration register (see page 18 section 5.2). I send 0x8C as I want my settings to be PGA = 1, SPS = 3.75, One-Shot mode, channel 1, initiate new conversion. Which should mean I need to send the slave 10001100 or 0x8c. This communication then ends as “Any byte sent after this second byte will be ignored” according to page 21. Then in the loop I begin transmission the same way apart from now I open transmission in read mode which is 0xDD as the last bit (R/W bit) is now 1. I then request six bytes of information and read the six bytes. If you now go to page 23 of the datasheet you can follow along again. Here I should get three data bytes from the slave and every subsequent byte should be the configuration register settings repeated. For now I am uninterested in the first three data bytes as I first of all just want to know how to change the configuration settings. What gets printed by the arduino instead is three data bytes from the slave, as expected, and then three of the exact same value, also as expected as they should all be the configuration settings. What is being printed in the second three bytes is “90”. Not what I expected. Now I’ve tried to figure out what has happened (hard without an oscilloscope). 90 converted from hex to binary is 10010000 and I believe the default settings are (which can be found on page 18) 00001001 could this be the default settings if so can anyone tell me whats going on and how to fix it? Thank you in advance for the help and thank you for taking the time to read my problem.

# Answer
> 3 votes
The problem is, that you misunderstood, how the `Wire` library handles addresses.

I2C uses an address byte, where the first 7 bits are the actual address and the last bit (Read/Write bit) dictates the direction of the communication. The `Wire` library gives you different functions for both directions (in your case: `Wire.beginTransmission()` for master write and `Wire.requestFrom()` for master read) and hides away the complexity of the Read/Write bit. So what you have to give as an address is the pure address of the device without the Read/Write bit. To write the configuration you used the address `0xDC`, but the actual address of the device is `0x6E` as you used it in the `Wire.requestFrom()` call.

Also in your `loop()` you try to start a master write with `Wire.beginTransmission()`, though you are starting a master read directly after it. `Wire.beginTransmission()` and `Wire.endTransmission()` are purely for master write transactions. So you should delete these lines here. For master read the call to `Wire.requestFrom()` and the corresponding reading is enough.

**What happens in your code:** In `setup()` you write the new configuration data to a wrong address (`0xDC` instead of `0x6E`). The transmission fails, as there is most likely no device with this address at the bus, but you don't notice, since you are not checking the return value of `Wire.endTransmission()`, which would show an error code. Then in the `loop()` function you reinitialize and reconfigure the whole `Wire` library again, which makes no sense, as Juraj mentioned in his comments. Though it will only cost some cycles of computation time. Then the library get's set to master write mode (no actual I2C action here, just interal to the library) and then to master read mode (actual I2C action. The provided number of bytes get's read here from the slave). At the end you say to the library, that is should finish the master write transmission from before, which is not there anymore (since you've done a master read). So this will do nothing. Also you are doing many delays between the reads, which is not necessary. When the `Wire.requestFrom()` function returns, all the I2C communication is finished. The bytes, that could be received, are received and written into the libraries buffer. `Wire.read()` will only read the next value from the buffer, remove it from there and return the value. No I2C action at that point, so the `delay(10)` is useless

TL;DR:

* Always use the correct address without Read/Write bit: `0x6E`
* Initialize and configure the `Wire` library only once in `setup()`
* Remove `Wire.beginTransmission()` and `Wire.endTransmission()` from the `loop()` function, as you are only doing master read there.
* Remove the `delay(10);` lines between the calls to `Wire.read()`

---
Tags: i2c, arduino-ide
---


# Question
Title: Sampling rate of multiple analog pins on Arduino
as I checked on Arduino website, they mentioned all boards: UNO, Nano, Mini, Mega have maximum sample rate 10kHz for each analog pin. So my concern is: 1) is there any difference between sampling rate when reading a single analog pin and multiple analog pins? For example, if we read only 1 analog input, maximum sample rate can reach 10kHz. How about maximum sample rate when we want to read 6 analog inputs? Maximum sample rate will be 10kHz or (10/6)kHz? Can we do analog input reading simultaneously or not?

2) What if I want to get sampling rate at least 1kHz for each Arduino board (assume 5 analog inputs)?

3) In case we need to connect several Arduino boards via I2C or SPI protocol, is sampling rate related to these 2 protocols?

# Answer
1) You only have one ADC on board and all the pins run through a mux. You can only read one pin at time. If you're willing to give up some resolution then you might can read a little faster but it gets tough. What's worse is that when you are switching pins really fast it can mess with your readings so that for some things, especially when input impedance is high, you have to read twice and throw away the first reading. So that essentially cuts your sampling rate in half right there.

2) That may be doable. Or at least something close to it. You'd run in free-running mode and write a tight ISR to read the interrupt when the analog read is finished and record every other value and switch the pin every other time. Theoretically you should get pretty close to 1kHz with 5 pins. Maybe a little faster if you give up a little resolution.

3) Those communications protocols run at light speed compared to the analog read.
> 2 votes

---
Tags: arduino-uno, arduino-mega, arduino-nano, analog-sampling
---


# Question
Title: Controlling multiple stepper motors non-simultaneously
I want to control multiple stepper motors one after another and at different speeds/directions. I am using the ULN2003 driver and the stepper has 5 coils.

My current code for controlling one motor is:

```
#include <Stepper.h>

const int stepsPerRevolution = 500;  // change this to fit the number of steps per revolution
// for your motor

// initialize the stepper library on pins 8 through 11:
Stepper myStepper(stepsPerRevolution, 8, 10, 9, 11);

void setup() {
  // set the speed at 60 rpm:
  myStepper.setSpeed(50);
  // initialize the serial port:
  Serial.begin(9600);
}

void loop() {
  // step one revolution  in one direction:
  Serial.println("clockwise");
  myStepper.step(stepsPerRevolution);

  // step one revolution in the other direction:
  Serial.println("counterclockwise");
  myStepper.step(-stepsPerRevolution);
}

```

How would I define each stepper motor differently?

Sorry if I have not asked the question properly. I will try to clarify as time goes on.

# Answer
> 1 votes
Like @chris! suggested, you could include two Stepper variables. So in the line where you were initializing the variable, you could instead have:

```
Stepper steppermotor1(stepsPerRevolution, 8, 10, 9, 11);

Stepper steppermotor2(stepsPerRevolution, 4, 5, 6, 7);

```

and then continue on with the code for speed, rotation and so on for each motor.

---
Tags: stepper, stepper-motor
---


# Question
Title: Distinguishing between multiple Infra Red Transmitters
I am working on an Arduino project where I use an infra red camera along with 4 transmitters placed each on a corner of a square platform to park a robot perfectly on this platform. However, it is important for the camera to distinguish between the 4 transmitters. (it should know the right transmitters from the left and the upper transmitters from the lower). Can anyone please help me find a solution to this problem?

# Answer
It's a symmetry problem, you can solve it breaking the simmetry. Options:

* use three transmitter instead of four, the plane and its center is still determined.
* move one transmitter in the middle of the side of the square.
* use different duty cycle for one (or more) transmitter.
* use linear polarizing filters on the transmitters and a rotating filter on the camera lense.
* ...

I guess that also SVD could be helpful to find the pattern's center, when the camera is not centered and perpendicular.
> 2 votes

---
Tags: arduino-uno, sensors, infrared
---


title: Compile error in Ubuntu 18.04

text:
# Question
Title: Compile error in Ubuntu 18.04
I'm trying to compile a code to arudino pro micro, I have the right option for compiling like the port and the type of the board,but I get an error,I can't copy

# Answer
This is likely a permission problem. The user likely does not have permission to read from and write to the port created when plugging in the Arduino. This can be temporally fixed using the following command:

```
sudo chmod 666 /dev/ttyACM0

```

However, this procedure is only temporary as the port is recreated every time the Arduino is reconnected to the computer. And upon recreation the permissions are reset to their defaults for security reasons.

A better solution is to determine the group which the port belongs to and to add the users expected to access these connected devices to that group.

Plugin and list the port to determine its group:

```
ls -l /dev/ttyACM*

```

or

```
ls -l /dev/ttyUSB*

```

The group the ports belong to will likely be "dialout". Add the user to that group:

```
usermod -a -G dialout user_name

```

...where user\_name is replaced by the name of the user who needs access to the port. If you don't know the name of the current user you can use this command:

```
whoami

```
> 2 votes

# Answer
Sorry for the late reply,it worked in the ide that I download from the web,apparently ide from the ubuntu software won't work. Thank for the answer
> 0 votes

---
Tags: compile, arduino-pro-micro, compilation-errors
---