# Question
Title: Why am I only seeing white screen in TFT 1.44 ST7735?
I just bought the 3rd TFT and in all my attempts I get the white screen I don't know what I'm doing wrong!

This time I bought it and **followed their instruction's** guide

I created this schematic using Fritzing which is the one I'm using but still I am getting the white screen again

Here are some Photos of what is the **TFT displaying**.

Finally, I did also used the recommended testing code which is listed in: File \> Examples \> Adafruit ST7735 and ST7789 library \> graphicstest

Also, I have did commented the slightly changed. So this is the code I'm using:

```
/**************************************************************************
  This is a library for several Adafruit displays based on ST77* drivers.

  Works with the Adafruit 1.8" TFT Breakout w/SD card
    ----> http://www.adafruit.com/products/358
  The 1.8" TFT shield
    ----> https://www.adafruit.com/product/802
  The 1.44" TFT breakout
    ----> https://www.adafruit.com/product/2088
  as well as Adafruit raw 1.8" TFT display
    ----> http://www.adafruit.com/products/618

  Check out the links above for our tutorials and wiring diagrams.
  These displays use SPI to communicate, 4 or 5 pins are required to
  interface (RST is optional).

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

  Written by Limor Fried/Ladyada for Adafruit Industries.
  MIT license, all text above must be included in any redistribution
 **************************************************************************/

#include <Adafruit_GFX.h>    // Core graphics library
#include <Adafruit_ST7735.h> // Hardware-specific library for ST7735
#include <Adafruit_ST7789.h> // Hardware-specific library for ST7789
#include <SPI.h>

#ifdef ADAFRUIT_HALLOWING
  #define TFT_CS        39 // Hallowing display control pins: chip select
  #define TFT_RST       37 // Display reset
  #define TFT_DC        38 // Display data/command select
  #define TFT_BACKLIGHT  7 // Display backlight pin
#elif defined(ESP8266)
  #define TFT_CS         4
  #define TFT_RST        16
  #define TFT_DC         5
#else
  // For the breakout board, you can use any 2 or 3 pins.
  // These pins will also work for the 1.8" TFT shield.
  #define TFT_CS        10
  #define TFT_RST        9 // Or set to -1 and connect to Arduino RESET pin
  #define TFT_DC         8
#endif

// OPTION 1 (recommended) is to use the HARDWARE SPI pins, which are unique
// to each board and not reassignable. For Arduino Uno: MOSI = pin 11 and
// SCLK = pin 13. This is the fastest mode of operation and is required if
// using the breakout board's microSD card.

// For 1.44" and 1.8" TFT with ST7735 (including HalloWing) use:
Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_RST);

// For 1.54" TFT with ST7789:
//Adafruit_ST7789 tft = Adafruit_ST7789(TFT_CS, TFT_DC, TFT_RST);

// OPTION 2 lets you interface the display using ANY TWO or THREE PINS,
// tradeoff being that performance is not as fast as hardware SPI above.
//#define TFT_MOSI 11  // Data out
//#define TFT_SCLK 13  // Clock out
//Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_MOSI, TFT_SCLK, TFT_RST);

float p = 3.1415926;

void setup(void) {
  Serial.begin(9600);
  Serial.print(F("Hello! ST77xx TFT Test"));

#ifdef ADAFRUIT_HALLOWING
  // HalloWing is a special case. It uses a ST7735R display just like the
  // breakout board, but the orientation and backlight control are different.
  tft.initR(INITR_HALLOWING);        // Initialize HalloWing-oriented screen
  pinMode(TFT_BACKLIGHT, OUTPUT);
  digitalWrite(TFT_BACKLIGHT, HIGH); // Backlight on
#else
  // Use this initializer if using a 1.8" TFT screen:
 // tft.initR(INITR_BLACKTAB);      // Init ST7735S chip, black tab

  // OR use this initializer (uncomment) if using a 1.44" TFT:
  tft.initR(INITR_144GREENTAB); // Init ST7735R chip, green tab

  // OR use this initializer (uncomment) if using a 0.96" 180x60 TFT:
  //tft.initR(INITR_MINI160x80);  // Init ST7735S mini display

  // OR use this initializer (uncomment) if using a 1.54" 240x240 TFT:
  //tft.init(240, 240);           // Init ST7789 240x240
#endif

  Serial.println(F("Initialized"));

  uint16_t time = millis();
  tft.fillScreen(ST77XX_BLACK);
  time = millis() - time;

  Serial.println(time, DEC);
  delay(500);

  // large block of text
  tft.fillScreen(ST77XX_BLACK);
  testdrawtext("Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur adipiscing ante sed nibh tincidunt feugiat. Maecenas enim massa, fringilla sed malesuada et, malesuada sit amet turpis. Sed porttitor neque ut ante pretium vitae malesuada nunc bibendum. Nullam aliquet ultrices massa eu hendrerit. Ut sed nisi lorem. In vestibulum purus a tortor imperdiet posuere. ", ST77XX_WHITE);
  delay(1000);

  // tft print function!
  tftPrintTest();
  delay(4000);

  // a single pixel
  tft.drawPixel(tft.width()/2, tft.height()/2, ST77XX_GREEN);
  delay(500);

  // line draw test
  testlines(ST77XX_YELLOW);
  delay(500);

  // optimized lines
  testfastlines(ST77XX_RED, ST77XX_BLUE);
  delay(500);

  testdrawrects(ST77XX_GREEN);
  delay(500);

  testfillrects(ST77XX_YELLOW, ST77XX_MAGENTA);
  delay(500);

  tft.fillScreen(ST77XX_BLACK);
  testfillcircles(10, ST77XX_BLUE);
  testdrawcircles(10, ST77XX_WHITE);
  delay(500);

  testroundrects();
  delay(500);

  testtriangles();
  delay(500);

  mediabuttons();
  delay(500);

  Serial.println("done");
  delay(1000);
}

void loop() {
  tft.invertDisplay(true);
  delay(500);
  tft.invertDisplay(false);
  delay(500);
}

void testlines(uint16_t color) {
  tft.fillScreen(ST77XX_BLACK);
  for (int16_t x=0; x < tft.width(); x+=6) {
    tft.drawLine(0, 0, x, tft.height()-1, color);
    delay(0);
  }
  for (int16_t y=0; y < tft.height(); y+=6) {
    tft.drawLine(0, 0, tft.width()-1, y, color);
    delay(0);
  }

  tft.fillScreen(ST77XX_BLACK);
  for (int16_t x=0; x < tft.width(); x+=6) {
    tft.drawLine(tft.width()-1, 0, x, tft.height()-1, color);
    delay(0);
  }
  for (int16_t y=0; y < tft.height(); y+=6) {
    tft.drawLine(tft.width()-1, 0, 0, y, color);
    delay(0);
  }

  tft.fillScreen(ST77XX_BLACK);
  for (int16_t x=0; x < tft.width(); x+=6) {
    tft.drawLine(0, tft.height()-1, x, 0, color);
    delay(0);
  }
  for (int16_t y=0; y < tft.height(); y+=6) {
    tft.drawLine(0, tft.height()-1, tft.width()-1, y, color);
    delay(0);
  }

  tft.fillScreen(ST77XX_BLACK);
  for (int16_t x=0; x < tft.width(); x+=6) {
    tft.drawLine(tft.width()-1, tft.height()-1, x, 0, color);
    delay(0);
  }
  for (int16_t y=0; y < tft.height(); y+=6) {
    tft.drawLine(tft.width()-1, tft.height()-1, 0, y, color);
    delay(0);
  }
}

void testdrawtext(char *text, uint16_t color) {
  tft.setCursor(0, 0);
  tft.setTextColor(color);
  tft.setTextWrap(true);
  tft.print(text);
}

void testfastlines(uint16_t color1, uint16_t color2) {
  tft.fillScreen(ST77XX_BLACK);
  for (int16_t y=0; y < tft.height(); y+=5) {
    tft.drawFastHLine(0, y, tft.width(), color1);
  }
  for (int16_t x=0; x < tft.width(); x+=5) {
    tft.drawFastVLine(x, 0, tft.height(), color2);
  }
}

void testdrawrects(uint16_t color) {
  tft.fillScreen(ST77XX_BLACK);
  for (int16_t x=0; x < tft.width(); x+=6) {
    tft.drawRect(tft.width()/2 -x/2, tft.height()/2 -x/2 , x, x, color);
  }
}

void testfillrects(uint16_t color1, uint16_t color2) {
  tft.fillScreen(ST77XX_BLACK);
  for (int16_t x=tft.width()-1; x > 6; x-=6) {
    tft.fillRect(tft.width()/2 -x/2, tft.height()/2 -x/2 , x, x, color1);
    tft.drawRect(tft.width()/2 -x/2, tft.height()/2 -x/2 , x, x, color2);
  }
}

void testfillcircles(uint8_t radius, uint16_t color) {
  for (int16_t x=radius; x < tft.width(); x+=radius*2) {
    for (int16_t y=radius; y < tft.height(); y+=radius*2) {
      tft.fillCircle(x, y, radius, color);
    }
  }
}

void testdrawcircles(uint8_t radius, uint16_t color) {
  for (int16_t x=0; x < tft.width()+radius; x+=radius*2) {
    for (int16_t y=0; y < tft.height()+radius; y+=radius*2) {
      tft.drawCircle(x, y, radius, color);
    }
  }
}

void testtriangles() {
  tft.fillScreen(ST77XX_BLACK);
  int color = 0xF800;
  int t;
  int w = tft.width()/2;
  int x = tft.height()-1;
  int y = 0;
  int z = tft.width();
  for(t = 0 ; t <= 15; t++) {
    tft.drawTriangle(w, y, y, x, z, x, color);
    x-=4;
    y+=4;
    z-=4;
    color+=100;
  }
}

void testroundrects() {
  tft.fillScreen(ST77XX_BLACK);
  int color = 100;
  int i;
  int t;
  for(t = 0 ; t <= 4; t+=1) {
    int x = 0;
    int y = 0;
    int w = tft.width()-2;
    int h = tft.height()-2;
    for(i = 0 ; i <= 16; i+=1) {
      tft.drawRoundRect(x, y, w, h, 5, color);
      x+=2;
      y+=3;
      w-=4;
      h-=6;
      color+=1100;
    }
    color+=100;
  }
}

void tftPrintTest() {
  tft.setTextWrap(false);
  tft.fillScreen(ST77XX_BLACK);
  tft.setCursor(0, 30);
  tft.setTextColor(ST77XX_RED);
  tft.setTextSize(1);
  tft.println("Hello World!");
  tft.setTextColor(ST77XX_YELLOW);
  tft.setTextSize(2);
  tft.println("Hello World!");
  tft.setTextColor(ST77XX_GREEN);
  tft.setTextSize(3);
  tft.println("Hello World!");
  tft.setTextColor(ST77XX_BLUE);
  tft.setTextSize(4);
  tft.print(1234.567);
  delay(1500);
  tft.setCursor(0, 0);
  tft.fillScreen(ST77XX_BLACK);
  tft.setTextColor(ST77XX_WHITE);
  tft.setTextSize(0);
  tft.println("Hello World!");
  tft.setTextSize(1);
  tft.setTextColor(ST77XX_GREEN);
  tft.print(p, 6);
  tft.println(" Want pi?");
  tft.println(" ");
  tft.print(8675309, HEX); // print 8,675,309 out in HEX!
  tft.println(" Print HEX!");
  tft.println(" ");
  tft.setTextColor(ST77XX_WHITE);
  tft.println("Sketch has been");
  tft.println("running for: ");
  tft.setTextColor(ST77XX_MAGENTA);
  tft.print(millis() / 1000);
  tft.setTextColor(ST77XX_WHITE);
  tft.print(" seconds.");
}

void mediabuttons() {
  // play
  tft.fillScreen(ST77XX_BLACK);
  tft.fillRoundRect(25, 10, 78, 60, 8, ST77XX_WHITE);
  tft.fillTriangle(42, 20, 42, 60, 90, 40, ST77XX_RED);
  delay(500);
  // pause
  tft.fillRoundRect(25, 90, 78, 60, 8, ST77XX_WHITE);
  tft.fillRoundRect(39, 98, 20, 45, 5, ST77XX_GREEN);
  tft.fillRoundRect(69, 98, 20, 45, 5, ST77XX_GREEN);
  delay(500);
  // play color
  tft.fillTriangle(42, 20, 42, 60, 90, 40, ST77XX_BLUE);
  delay(50);
  // pause color
  tft.fillRoundRect(39, 98, 20, 45, 5, ST77XX_RED);
  tft.fillRoundRect(69, 98, 20, 45, 5, ST77XX_RED);
  // play color
  tft.fillTriangle(42, 20, 42, 60, 90, 40, ST77XX_GREEN);
}

```

Please don't mark this question as duplicated because I looked at the other guy he/she was using different guide.. the one I'm using is posted by the company I purchased the TFT from.

# Answer
> 2 votes
I would like to suggest some changes in your code i.e.

Your Code:

```
/**************************************************************************
  This is a library for several Adafruit displays based on ST77* drivers.

  Works with the Adafruit 1.8" TFT Breakout w/SD card
    ----> http://www.adafruit.com/products/358
  The 1.8" TFT shield
    ----> https://www.adafruit.com/product/802
  The 1.44" TFT breakout
    ----> https://www.adafruit.com/product/2088
  as well as Adafruit raw 1.8" TFT display
    ----> http://www.adafruit.com/products/618

  Check out the links above for our tutorials and wiring diagrams.
  These displays use SPI to communicate, 4 or 5 pins are required to
  interface (RST is optional).

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

  Written by Limor Fried/Ladyada for Adafruit Industries.
  MIT license, all text above must be included in any redistribution
 **************************************************************************/

#include <Adafruit_GFX.h>    // Core graphics library
#include <Adafruit_ST7735.h> // Hardware-specific library for ST7735
#include <Adafruit_ST7789.h> // Hardware-specific library for ST7789
#include <SPI.h>

#ifdef ADAFRUIT_HALLOWING
  #define TFT_CS        39 // Hallowing display control pins: chip select
  #define TFT_RST       37 // Display reset
  #define TFT_DC        38 // Display data/command select
  #define TFT_BACKLIGHT  7 // Display backlight pin
#elif defined(ESP8266)
  #define TFT_CS         4
  #define TFT_RST        16
  #define TFT_DC         5
#else
  // For the breakout board, you can use any 2 or 3 pins.
  // These pins will also work for the 1.8" TFT shield.
  #define TFT_CS        10
  #define TFT_RST        9 // Or set to -1 and connect to Arduino RESET pin
  #define TFT_DC         8
#endif

// OPTION 1 (recommended) is to use the HARDWARE SPI pins, which are unique
// to each board and not reassignable. For Arduino Uno: MOSI = pin 11 and
// SCLK = pin 13. This is the fastest mode of operation and is required if
// using the breakout board's microSD card.

// For 1.44" and 1.8" TFT with ST7735 (including HalloWing) use:
Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_RST);

// For 1.54" TFT with ST7789:
//Adafruit_ST7789 tft = Adafruit_ST7789(TFT_CS, TFT_DC, TFT_RST);

// OPTION 2 lets you interface the display using ANY TWO or THREE PINS,
// tradeoff being that performance is not as fast as hardware SPI above.
//#define TFT_MOSI 11  // Data out
//#define TFT_SCLK 13  // Clock out
//Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_MOSI, TFT_SCLK, TFT_RST);

```

changes suggested:

```
/**************************************************************************
  This is a library for several Adafruit displays based on ST77* drivers.

  Works with the Adafruit 1.8" TFT Breakout w/SD card
    ----> http://www.adafruit.com/products/358
  The 1.8" TFT shield
    ----> https://www.adafruit.com/product/802
  The 1.44" TFT breakout
    ----> https://www.adafruit.com/product/2088
  as well as Adafruit raw 1.8" TFT display
    ----> http://www.adafruit.com/products/618

  Check out the links above for our tutorials and wiring diagrams.
  These displays use SPI to communicate, 4 or 5 pins are required to
  interface (RST is optional).

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

  Written by Limor Fried/Ladyada for Adafruit Industries.
  MIT license, all text above must be included in any redistribution
 **************************************************************************/

#include <Adafruit_GFX.h>    // Core graphics library
#include <Adafruit_ST7735.h> // Hardware-specific library for ST7735
#include <Adafruit_ST7789.h> // Hardware-specific library for ST7789
#include <SPI.h>

  #define TFT_CS        10
  #define TFT_RST        9 // Or set to -1 and connect to Arduino RESET pin
  #define TFT_DC         8

// OPTION 1 (recommended) is to use the HARDWARE SPI pins, which are unique
// to each board and not reassignable. For Arduino Uno: MOSI = pin 11 and
// SCLK = pin 13. This is the fastest mode of operation and is required if
// using the breakout board's microSD card.

// For 1.44" and 1.8" TFT with ST7735 (including HalloWing) use:
//Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_RST);

// For 1.54" TFT with ST7789:
//Adafruit_ST7789 tft = Adafruit_ST7789(TFT_CS, TFT_DC, TFT_RST);

// OPTION 2 lets you interface the display using ANY TWO or THREE PINS,
// tradeoff being that performance is not as fast as hardware SPI above.
#define TFT_MOSI 11  // Data out
#define TFT_SCLK 13  // Clock out
Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_MOSI, TFT_SCLK, TFT_RST);

```

Replace your that part with one I suggested as **You commented tha SCK and MISO pins in your code so no data transfer is happening on those pins.** Secondly I made changes according to your hardware configuration as well.

---
Tags: tft
---


# Question
Title: Pin headers too long for the sensor i bought
https://www.amazon.co.uk/Adafruit-TCS34725-Color-Sensor-Filter/dp/B00OKCRU5M/ref=sr\_1\_3?keywords=adafruit+rgb+sensor&qid=1559653098&s=computers&sr=1-3

Just bought this colour sensor for a project and as you can see it comes with the pins detached. There are 8 pins but only 7 holes so how do i assemble it? I'm assuming its super obvious since i havent seen anyone else ask it so im sorry! Thanks in advance.

# Answer
Cut one pin off.

Get some wire cutters and position them in the groove between the last and next to last pins in the row. Squeeze. One pin will pop off.
> 6 votes

---
Tags: adafruit
---


# Question
Title: RGB LED Mode toggle - Trying to avoid using main loop()
I'd like to start by saying that I have only been dabbling in electronics (not just Arduino) for about 3 days now.

I am trying to write a sketch which changes an RGB LED when a push switch is pressed.

There are 6 modes -

```
0 = off
1 = dim
2 = mid brightness
3 = full brightness
4 = cycle through RGB colours
5 = pause the colour cycle at the current colour

```

I have managed to get this working using the code below this explanation. What I would like to know is this - Since the LED only changes state when the button is pressed, is it possible to avoid the use of the main 'loop()' entirely?

Will work fine for modes 0, 1, 2 and 3, but the interrupt cannot fire until mode 4 has finished 1 entire colour cycle.

```
/*
 * LED MODES
 * 0 = off
 * 1 = dim
 * 2 = mid
 * 3 = bright
 * 4 = colour cycle
 * 5 = colour select
 */
volatile int ledMode = 0; // off
const int maxLEDMode = 5;
volatile bool buttonPressed = false;

int rPin = 9;
int gPin = 10;
int bPin = 11;
int ledPin = 5;
int buttonPin = 2;
int currentVals[] = {0, 0, 0};

void setup() {
  Serial.begin(9600);
  pinMode(rPin, OUTPUT);
  pinMode(gPin, OUTPUT);
  pinMode(bPin, OUTPUT);
  pinMode(ledPin, OUTPUT);
  pinMode(buttonPin, INPUT);

  attachInterrupt(digitalPinToInterrupt(buttonPin), buttonPress, FALLING);
}

void loop() {
  setBrightness(); // try and move outside of main loop
}

// Ensure that buttonPress does not trigger twice
void buttonPress(){
  if(digitalRead(buttonPin) == 0){
    delay(10);
    if(digitalRead(buttonPin) == 0){

      setMode();
      buttonPressed = true;
      Serial.println(ledMode);
    }
  }
}

//Increment LED Mode until max level is reached
void setMode(){
  if(ledMode == maxLEDMode){
    ledMode = 0;
  } else {
    ledMode++;
  }
}

//Set LED colours depending on ledMode
void setBrightness(){
  buttonPressed = false;

  if(ledMode == 0){
    mode0();
  }

  if(ledMode == 1){
    mode1();
  }

  if(ledMode == 2){
    mode2();
  }

  if(ledMode == 3){
    mode3();
  }

  if(ledMode == 4){
    mode4();
  }

  if(ledMode == 5){
    mode5();
  }
}

//Fade to off
void mode0 (){
  fadeTo(0, 0, 0, 10);
}

// Fade to dim light
void mode1 (){
  int val = 255/5;
  fadeTo(val, val, val, 100);
}

// Fade to medium light
void mode2 (){
  int val = (255/3);
  fadeTo(val, val, val, 100);
}

// Fade to bright light
void mode3 (){
  fadeTo(255, 255, 255, 100);
}

// Endlessly cycle through RGB colours
void mode4(){
    fadeToWithCheck(255, 0, 0, 500);
    fadeToWithCheck(255, 255, 0, 500);
    fadeToWithCheck(0, 255, 0, 500);
    fadeToWithCheck(0, 255, 255, 500);
    fadeToWithCheck(0, 0, 255, 500);
    fadeToWithCheck(255, 0, 255, 500);
}

// Pause LED on colour inherited from Mode4
void mode5(){
  int rExisting = currentVals[0];
  int gExisting = currentVals[1];
  int bExisting = currentVals[2];
  fadeTo(rExisting, gExisting, bExisting, 1);
}

// Fade to given colour, with awareness of mode4 toggles
void fadeToWithCheck(int r, int g, int b, int interval){
  if(ledMode == 4){
    int rExisting = currentVals[0];
    int gExisting = currentVals[1];
    int bExisting = currentVals[2];

    for(int i = 0; i <= interval; i++){
      analogWriteInverted(rPin, map(i, 0, interval, rExisting, r));
      analogWriteInverted(gPin, map(i, 0, interval, gExisting, g));
      analogWriteInverted(bPin, map(i, 0, interval, bExisting, b));

      if(buttonPressed == true){
        Serial.println("stopping loop");
        currentVals[0] = map(i, 0, interval, rExisting, r);
        currentVals[1] = map(i, 0, interval, gExisting, g);
        currentVals[2] = map(i, 0, interval, bExisting, b);
        break;
      }
      delay(10);
    }

    if(buttonPressed == true){
      buttonPressed = false;
    } else {
      currentVals[0] = r;
      currentVals[1] = g;
      currentVals[2] = b;
    }
  }
}

// Fade to given colour
void fadeTo(int r, int g, int b, int interval){
  int rExisting = currentVals[0];
  int gExisting = currentVals[1];
  int bExisting = currentVals[2];

  for(int i = 0; i <= interval; i++){
    analogWriteInverted(rPin, map(i, 0, interval, rExisting, r));
    analogWriteInverted(gPin, map(i, 0, interval, gExisting, g));
    analogWriteInverted(bPin, map(i, 0, interval, bExisting, b));
    delay(10);
  }
  currentVals[0] = r;
  currentVals[1] = g;
  currentVals[2] = b;
}

// Invert given value due to cathode/anode LED
void analogWriteInverted( byte pin, byte value)
{
  analogWrite(pin, 255-value);
}

```

Any help or advice at all would be appreciated! Many thanks, Rob

**UPDATE - Working solution**

Following on from the advice given by Michel, the following code meets my needs perfectly.

```
#include "TimerOne.h"

/*
 * LED MODES
 * 0 = off
 * 1 = dim
 * 2 = mid
 * 3 = bright
 * 4 = colour cycle
 * 5 = colour select
 */
volatile int ledMode = 0; // off
const int maxLEDMode = 5;
volatile bool buttonPressed = false;
unsigned long lastDebounceTime = -1;
unsigned long debounceDelay = 200;
int lastButtonState = HIGH;
int buttonState;
long secondTimer = 1000000;

int rPin = 6;
int gPin = 5;
int bPin = 3;
int buttonPin = 2;
int currentVals[] = {0, 0, 0};
int mode4Vals[] = {0, 0, 0};
int mode4Stage = 0;

long fadeInterval = 0;
long lastSeenInterval;

void setup() {
  Serial.begin(9600);
  pinMode(rPin, OUTPUT);
  pinMode(gPin, OUTPUT);
  pinMode(bPin, OUTPUT);
  pinMode(buttonPin, INPUT);

  Timer1.initialize(secondTimer / 1000);
  attachInterrupt(digitalPinToInterrupt(buttonPin), buttonPress, FALLING);

  turnOff();
}

void loop() {
  //setBrightness(); // try and move outside of main loop

}

void turnOff(){
  analogWriteInverted(rPin,0);
  analogWriteInverted(gPin,0);
  analogWriteInverted(bPin,0);

  currentVals[0] = 0;
  currentVals[1] = 0;
  currentVals[2] = 0;
}

// Ensure that buttonPress does not trigger twice
void buttonPress(){
  int reading = digitalRead(buttonPin);

  if (lastDebounceTime < 0 || (millis() - lastDebounceTime) > debounceDelay) {
    lastDebounceTime = millis();
    if(ledMode != 4){
        clearTimer();
    }
        setMode();
        buttonPressed = true;
        Timer1.attachInterrupt(incrementGlobalFadeInterval);
      }
    }

//Increment LED Mode until max level is reached
void setMode(){
  if(ledMode == maxLEDMode){
    ledMode = 0;
  } else {
    ledMode++;
  }
}

//Set LED colours depending on ledMode
void setBrightness(){
  buttonPressed = false;

  switch(ledMode){
    case 0: mode0(); break;
    case 1: mode1(); break;
    case 2: mode2(); break;
    case 3: mode3(); break;
    case 4: mode4(); break;
    case 5: mode5(); break;
    default: abort();
  }

}

//Fade to off
void mode0 (){
  fadeTo(0, 0, 0, 400);
}

// Fade to dim light
void mode1 (){
  int val = 255/5;
  fadeTo(val, val, val, 50);
}

// Fade to medium light
void mode2 (){
  int val = (255/3);
  fadeTo(val, val, val, 50);
}

// Fade to bright light
void mode3 (){
  fadeTo(255, 255, 255, 50);
}

// Endlessly cycle through RGB colours
void mode4(){
  switch(mode4Stage){
    case 0: fadeToWithCheck(255, 0, 0, 2000); break;
    case 1: fadeToWithCheck(255, 255, 0, 2000); break;
    case 2: fadeToWithCheck(0, 255, 0, 2000); break;
    case 3: fadeToWithCheck(0, 255, 255, 2000); break;
    case 4: fadeToWithCheck(0, 0, 255, 2000); break;
    case 5: fadeToWithCheck(255, 0, 255, 2000); break;
    default: abort();
  }
}

// Pause LED on colour inherited from Mode4
void mode5(){
  currentVals[0] = mode4Vals[0];
  currentVals[1] = mode4Vals[1];
  currentVals[2] = mode4Vals[2];

  int rExisting = currentVals[0];
  int gExisting = currentVals[1];
  int bExisting = currentVals[2];
  fadeTo(rExisting, gExisting, bExisting, 1);
}

// Fade to given colour, with awareness of mode4 toggles
void fadeToWithCheck(int r, int g, int b, int interval){
  if(ledMode == 4){
    int rExisting = currentVals[0];
    int gExisting = currentVals[1];
    int bExisting = currentVals[2];

    if(fadeInterval <= interval && lastSeenInterval != fadeInterval){
      lastSeenInterval = fadeInterval;
      analogWriteInverted(rPin, map(fadeInterval, 0, interval, rExisting, r));
      analogWriteInverted(gPin, map(fadeInterval, 0, interval, gExisting, g));
      analogWriteInverted(bPin, map(fadeInterval, 0, interval, bExisting, b));

      mode4Vals[0] = map(fadeInterval, 0, interval, rExisting, r);
      mode4Vals[1] = map(fadeInterval, 0, interval, gExisting, g);
      mode4Vals[2] = map(fadeInterval, 0, interval, bExisting, b);
    } else {
      currentVals[0] = map(fadeInterval, 0, interval, rExisting, r);
      currentVals[1] = map(fadeInterval, 0, interval, gExisting, g);
      currentVals[2] = map(fadeInterval, 0, interval, bExisting, b);
      fadeInterval = 0;

      if(mode4Stage == 5){
        mode4Stage = 0;
      } else {
        mode4Stage++;
      }
    }
  }
}

// Fade to given colour
void fadeTo(int r, int g, int b, int interval){
  int rExisting = currentVals[0];
  int gExisting = currentVals[1];
  int bExisting = currentVals[2];

  if(fadeInterval <= interval && fadeInterval != lastSeenInterval){
    lastSeenInterval = fadeInterval;
    analogWriteInverted(rPin, map(fadeInterval, 0, interval, rExisting, r));
    analogWriteInverted(gPin, map(fadeInterval, 0, interval, gExisting, g));
    analogWriteInverted(bPin, map(fadeInterval, 0, interval, bExisting, b));
  } else {
    clearTimer();
    currentVals[0] = r;
    currentVals[1] = g;
    currentVals[2] = b;
  }
}

void incrementGlobalFadeInterval(){
  fadeInterval++;
  setBrightness();
}

void clearTimer(){
  Timer1.detachInterrupt();
  fadeInterval = 0;
  lastSeenInterval = -1;
}

// Invert given value due to cathode/anode LED
void analogWriteInverted( byte pin, byte value)
{
  analogWrite(pin, 255-value);
}

```

# Answer
**Keep interrupt shorts**

Inside an interrupt, do not use long pauses, thus not a delay. As chrisl notes below (see comment) delay does not even work inside an interrupt, since it is based on millis(), which are not updated within an interrupt.

The reason is that interrupts should be as short as possible (so even if you would use a for loop with micros() or another way to hold the execution time), because it can cause new interrupts not to be called (during an interrupt, no new interrupts will be called, at least not with the same/lower priority). So always keep code within interrupts very short, especially delay's are violating this, but also serial.print statements.

I see you use this function which will be called if you put everything in the interrupt handler:

```
// Fade to given colour
void fadeTo(int r, int g, int b, int interval){
  int rExisting = currentVals[0];
  int gExisting = currentVals[1];
  int bExisting = currentVals[2];

  for(int i = 0; i <= interval; i++){
    analogWriteInverted(rPin, map(i, 0, interval, rExisting, r));
    analogWriteInverted(gPin, map(i, 0, interval, gExisting, g));
    analogWriteInverted(bPin, map(i, 0, interval, bExisting, b));
    delay(10);
  }
  currentVals[0] = r;
  currentVals[1] = g;
  currentVals[2] = b;
}

```

**Removing delays**

To remove the delay, is a bit tricky though. What you need to do is (approximately):

* Create a global variable instead of the loop variable (i, but give it a better name)
* Calling an additional interrupt based on 10 ms (the delay).
* In that interrupt, handle the next iteration (so increase the global variable `i` (but the new name)
* Handle post processing (e.g. if i == interval, execute the last three statements of the function (and possibly other statements from called functions in the original code).

**Multiple `if` to one `switch` statement**

Also you can use a switch statement.. Instead of

```
 if(ledMode == 0){
    mode0();
  }

  if(ledMode == 1){
    mode1();
  }

  if(ledMode == 2){
    mode2();
  }

  if(ledMode == 3){
    mode3();
  }

  if(ledMode == 4){
    mode4();
  }

  if(ledMode == 5){
    mode5();
  }
}

```

Use

```
switch (ledMode)
{
case 0:
  mode0();
  break;

case 1:
  mode1();
  break;

..

case 5:
  mode5();
  break;

default:
   abort(); // Error condition
}

```

Since the cases are so simple I put them normally on one line:

```
switch (ledMode)
{
case 0: mode0(); break;
case 1: mode1(); break;
..
case 5: mode5(); break;
default: abort();
}

```

**Button debouncing**

In your remark you say after a button press, sometimes the function is called multiple times. This is caused by button bouncing. When you press a button, for a short time, the contact is somewhere between on and off. During this time, it can change a few times between on and off, thus you get multiple calls, mostly very short after each other. To prevent this, use button debouncing (check the Arduino site for a Button Debounce example). It means that you check if a certain state has been stable for some time, and than perform the action, instead of immediately.
> 1 votes

# Answer
Remove the `buttonPressed = false;` from fadeToWithCheck. As in mode4 this function is called four times, only the current call is skipped if the button is pressed. The following calls are not skipped, because your reset buttonPressed back to false.

There is no need for this, as it's already reset back to false at the beginning of setBrightness.
> 0 votes

---
Tags: led, interrupt, button, rgb-led
---


# Question
Title: Controlling JX PDI-6221MG Digital Servo with Arduino
So, I naively bought two of these JX PDI-6221MG Digital Servos thought they would work with the Arduino straight out of the box, just like MG996R did, for instance, but it seems they won't. However, I hear some clicking noise when the motor is connected, tho.

These are the Servo specs:

```
Dead band: 2μs
Working frequence: 1520μs / 330hz
Operating Speed (4.8V): 0.18 sec/60°
Operating Speed (6V): 0.16 sec/60°
Stall Torque (4.8V): 17.25 kg/cm
Stall Torque (6V):  20.32 kg/cm
Dimensions: 40.5X20.2X38mm
Weight:  62 g
Connector Wire Length: JR  265 mm
Bearing: 2BB

```

Manufacturer site: http://www.jx-servo.com/English/Product/49513727.html

Additionally, I used 5V 2.4A power input alongside with the Arduino Nano running just some sample code:

```
#include <Servo.h>

Servo myservo;  // create servo object to control a servo
// twelve servo objects can be created on most boards

int pos = 0;    // variable to store the servo position

void setup() {
  myservo.attach(3);  // attaches the servo on pin 9 to the servo object
}

void loop() {
  for (pos = 0; pos <= 180; pos += 1) { // goes from 0 degrees to 180 degrees
    // in steps of 1 degree
    myservo.write(pos);              // tell servo to go to position in variable 'pos'
    delay(15);                       // waits 15ms for the servo to reach the position
  }
  for (pos = 180; pos >= 0; pos -= 1) { // goes from 180 degrees to 0 degrees
    myservo.write(pos);              // tell servo to go to position in variable 'pos'
    delay(15);                       // waits 15ms for the servo to reach the position
  }
}

```

Wiring:

I tested the same configuration with MG996R and SG90 and it worked. So what am I missing here?

# Answer
> 1 votes
I managed to get servos running with 6 V and 3 A powered from lab power supply (GOPHERT CPS-1620 0-16V 0-20A). I guess, at the end, it was power supply which was crucial.

# Answer
> 1 votes
If you connect the servo to the same power supply as the MPU make sure you have a robust amperage rating. As soon as the servo tries to move, the current draw shoots way up and your MPU will hit a brownout state and reboot. At the very least you will need a capacitor at the power input to the MPU.

---
Tags: motor, servo
---


# Question
Title: Getting maximum value from HX711 and use it in the code further
i am using HX711 module to get value from load cell.my projects is a tensile strength testing machine,which will increase the load gradually and break at its maximum capacity.therefore i need the maximum value at which the specimen breaks.and use that value in the code to calcuate the tensile strengh of the specimen using the formula(tensile strength=load/cross section area of specimen). Please help me with this and if possible ,i will be very gratefull if anyone can help me with the code too. Thank you

# Answer
> 1 votes
We won't write the code for you, since we are not a free coding service, but I will try to give you some hints, how you can do it.

1. **Timing of measurements:** The measurements themselves can be done with one of the HX711 libraries, that are available on the web, but you may want to time them to get more regular measurements. This can be done in a non-blocking coding style like in the `BlinkWithoutDelay` example, that comes with the Arduino IDE. It involves the `millis()` function to measure the time since the last measurement and act accordingly. This is explained many times troughout the web and on this site.
2. **Saving the data and finding the maximum:** This depends on what else you want to do with the data.

* **Saving all data for later processing**: You might want to save all data (the load curve) for later use. In this case you have to define an array of appropriate length (the length depends on the duration and frequency of the measurement). Also define a position variable or pointer, that marks the current position in this array. Everytime when you do a measurement, you save the result to the array element at the saved position and increment the position variable after that. After the end of the measurement, you declare a value variable with the value of the first array element. Then you loop through all the following elements (`for(int i=1;i<array_length;i++)`). Inside the loop you calculate and save the maximum of 2 numbers: The value of the current array element and the saved variable. This can be done with `saved_value = max(saved_value, array[i]);`. When the loop is finished, you will have the maximum value in the `saved_value` variable.
    * **No saving of data:** You can also calculate a flying maximum without saving all data. Declare a variable (`max_value`), that will hold the maximum value, and set it to zero. Then, everytime when you do a measurement, you execute `max_value = max(current_value, max_value);` which calculates the maximum of the two numbers (current measurement and the previously calculated maximum). At the end of the measurement you will have the absolute maximum in the `max_value` variable.
3. **Sensing the end of measurement:** You need to sense the end of the measurement (when the specimen breaks) (though this can be done manually if you like). For this I would suggest to calculate the speed in which the load changes. During the measurement the load will increase slowly. In the moment of breaking the load will decrease very fast. The speed between two load measurments is calculated by `(value(x) - value(x-1))/measurement_interval`. You can define a threshold of negative speed, so that every speed below it (faster negative decrease of load) will be sensed as breaking of specimen. You can check this on every measurement with a simple `if` statement, or you can calculate the speed over more than 2 consecutive measurements. That depends on the actual speed of load change and the frequency of load measurements.
4. **Calculating the tensile strength:** This is just writing your formula into the code using the variable names, that you used in the previous code. Be sure to use the correct variable type for your needs. Most likely you would want to use `float`.
5. **Getting input from user:** This depends largely on your planned means of interaction with the user. Is the Arduino connected to a PC and you use a serial terminal program? Then you can use this for user input (You might want to look at the `SerialEvent` example of the Arduino IDE, which shows how to work with messages and delimiter characters). Do you want to add a keypad and a LCD display? There are library available for these too, so it should not be very difficult to learn how to use then to get user input.

---
Tags: arduino-uno
---


# Question
Title: How to handle a ESP8266 webserver only to the access point?
I'm developing a application that needs to be somewhat secure, so to configure the parameters it handles a GPIO interrupt (from a button) to open a server, that lets you configure it. The problem is that it is configured to send an email, so it is connected to the wifi.

With this in mind, I need to detect the source of the connection so I can serve the html only to the access point connections.

Is it possible?

# Answer
It is not documented, but you can construct WiFiServer or ESP8266WebServer with IP address. If you use the IP address of the AP, the server will be available only on the SoftAP. If you use the IP address of the station, the server will be available only on STA interface.

```
#include <ESP8266WiFi.h>

WiFiServer telneServer(23);

void setup() {
  ...
  telneServer = WiFiServer(WiFi.softAPIP(), 23);
//  telneServer = WiFiServer(WiFi.localIP(), 23);
  telneServer.begin();

```
> 0 votes

---
Tags: esp8266, web-server
---


# Question
Title: Receiving garbled `char` array returned by a function
I return a `char[300]` array from a function. If I intialize a `char*` variable with it, the return is garbled, but not if I append it to a `String`. What gives?

```
  const char* post2 =  uploadHourCsv(timeNow,pulseChangeHour) ;
  String postS2 = "";
  postS2 =  uploadHourCsv(timeNow,pulseChangeHour) ;
  //const char* post2 = { uploadHourCsv(timeNow,pulseChangeHour) };
  if( debug ) {
    Serial.print("received in loop() as : [");
    Serial.println(post2);
    Serial.print("String : [");
    Serial.println(postS2);
  }

...

char postStr[300] = "";
// populate array
if( debug ) {
  Serial.print("postStrCsv generated: ");
  Serial.println(postStr);
}
return postStr;

```

> postStrCsv generated: 00000003;3| 0.00;8|17.55;9|17.55;10|18.12;11|16.92;20|93817;22|93789;101|6;time|1559646000;
>
> received in loop() as : \[000?⸮@⸮⸮?" ⸮⸮?17.55;9|17.58! @0⸮⸮⸮⸮G% @5~\`⸮h⸮?⸮⸮
>
> String : \[00000003;3| 0.00;8|17.55;9|17.55;10|18.12;11|16.92;20|93817;22|93789;101|6;time|1559646000;

# Answer
It's because you're returning a pointer to a local variable.

You are only returning the address in memory where your char array is allocated. That allocation is on the stack and only exists for the lifetime of the function. But you still have the address where that memory was allocated, and you're using it as if it's still allocated.

When you append it to a String room is allocated on the heap and the data is copied in. That heap allocation remains until the String object is destroyed, either by going out of scope or by you manually destroying it.

It's pure chance that the data is still available and intact at the point of copying.

In short:

* You must **never** return a pointer to a locally allocated (non-static) array.

Things you can do that are correct:

My preferred method is the first, whereby you define an array in the outer scope, then pass that (and possibly the array length) to the function. The function then populates the array it has been passed. This also has the advantage that the function can use the return value to indicate a status or other quantity.

For example:

```
void myFunc(char *buf, int len) {
    for (int i = 0; i < len - 1; i++) {
        buf[i] = 'A';
    }
    buf[len - 1] = 0;
}

char myBuf[20];
myFunc(myBuf, 20);
Serial.println(myBuf);

--> AAAAAAAAAAAAAAAAAAAA

```
> 12 votes

# Answer
Following Majenko's invaluable advice and incorporating another similar approach, final working implementation was to treat the function as a method to operate upon the `char[300]` array as "out parameter".

```
char postStr[300] =  "";
uploadHourCsv(timeNow,pulseChangeHour,postStr) ;
...

void uploadHourCsv(int unixtimeEvent, int pulseChange, char* postStr) {
  // prepare data and variables
  strcat(postStr, stationId);
  strcat(postStr,";3|"); // chuva hora
  strcat(postStr, dtostrf(rainHour,6,2,charDummy));
  ...
}

```
> 1 votes

---
Tags: c++
---


# Question
Title: Is it possible to do an OTA update using a GitHub link
I need to be able to download software updates through the internet without having my MKR1000 plugged in. Either that or have new code being pushed from my server (C++) to my MKR1000, and then rebooting with the new code. Any help is useful. Thanks.

# Answer
> 1 votes
It may be possible if you can write your own bootloader, but it certainly won't be easy.

The normal way of doing OTA updates is to use a chip that has segmentable and remappable flash memory (such as the ESP32, ESP8266, PIC32MZ, etc) where your sketch is running from one segment, and that loads the new code from whatever source into the other segment. It then changes a single boot flag and resets the MCU, and the MCU then maps the second segment into the place of the first (swaps the two segments over) and runs the new code.

That can't be done with the SAMD21 since it has no remappable flash memory segments.

So the best you could hope for would be to reboot into a custom bootloader which then connects to the internet to download new code to flash into the main portion of the flash memory. And of course that would replace the existing bootloader and take a lot of work to create.

---

Addendum:

Apparently there is the "WiFi101OTA" library which allows over-the-air updates on SAMD21 boards. By all accounts this receives the new code and stores it away somewhere (a chunk of the internal flash, SD card, etc) and then copies that data to the main portion of the flash using a function running from RAM.

While this sounds good, I would **not** recommend using it in a live situation. For development it's fine, but not "in the field".

This is simply because there is no protection against "bricking" a unit. Once the copy from storage to main flash starts you are at the point of never being able to go back. If that write should fail for whatever reason (there is a power outage, or the sketch crashes, or any of a myriad of other unpredictable reasons) the unit is dead. You would have to manually reprogram the unit with a cable to bring it back to life.

By having the programming done by the bootloader (incidentally, some devices, such as AVR based boards, can *only* write to flash from the bootloader) the code that does the writing never gets overwritten, so a simple manual reset of the unit can restart the programming and recover the board.

If you were to adopt this library you would of course have to modify it to "pull" the update, not receive a "pushed" update. This should be trivial, but some level of network programming ability would be needed.

---
Tags: c++, wifi, http, mkr1000
---


# Question
Title: Trying to individually control the servos in my robot using keyboard input
```
#include<Servo.h>
Servo ser1;
Servo ser2;
Servo ser3;
Servo ser4;
Servo ser5;
int poser = 0;
int val;
int mot;

void setup() {
  Serial.begin(9600);
  ser1.attach(4);
  ser2.attach(5);
  ser3.attach(6);
  ser4.attach(7);
  ser5.attach(8);
}

void loop() {
    Serial.print("Choose the motor");
      mot=Serial.read();
      switch(mot)
      {
        case 1:
        {
            val = Serial.read();
            if (val == 'd')
             {
                poser += 1;
                ser1.write(poser);
               delay(15);
             }
           if (val == 'a')
             {
                poser -= 1;
                ser1.write(poser);
                delay(15);
             }
           break;
         }
       case 2:
         {
           val = Serial.read();
           if (val == 'd')
            {
               poser += 1;
               ser2.write(poser);
               delay(15);
            }
           if (val == 'a')
            {
               poser -= 1;
               ser2.write(poser);
               delay(15);
            }
           break;
         }
      case 3:
         {
           val = Serial.read();
           if (val == 'd')
            {
              poser += 1;
              ser3.write(poser);
              delay(15);
            }
          if (val == 'a')
            {
              poser -= 1;
              ser3.write(poser);
              delay(15);
            }
          break;
         }
       case 4:
         {
            val = Serial.read();
            if (val == 'd')
             {
                poser += 1;
                ser4.write(poser);
                delay(15);
             }
           if (val == 'a')
             {
                poser -= 1;
                ser4.write(poser);
                delay(15);
             }
           break;
         }
       case 5:
         {
           val = Serial.read();
           if (val == 'd')
             {
                poser += 1;
                ser4.write(poser);
                delay(15);
             }
           if (val == 'a')
             {
                poser -= 1;
                ser4.write(poser);
                delay(15);
             }
           break;
          }
      default:
          {
              Serial.print("Type valid number");
              break;
          }
    }
  }

```

The code just shows "Choose the motor type valid number" repeatedly and the arm contorts as soon as I upload it. Can someone please check the code and tell me what could've gone wrong?

# Answer
The values that you get from read are characters not integers. You will receive the character '1' or '2' not the integers you are currently checking for. As a result, none of the cases will match and you will always end up at the `default:` block of code.

So, you need to modify your case statement to check for characters. I.e.

```
switch(mot){
        case '1':       // put your digit in quoted
        {

```

And so on throughout the program
> 0 votes

# Answer
I would suggest you to add these line in your code.

`while(!Serial.available()){;}` before `mot = Serial.read();`

This will hold you logic till any input received from Serial.

Same you add before `val = Serial.read();`.
> 0 votes

---
Tags: robotics
---


title: Maximum Capacity Debugging

text:
# Question
Title: Maximum Capacity Debugging
**1. Example**

Check the program below for an Arduino Nano, Old Bootloader, for variable values of `N`.

* For low values (`N<=1857`), the program outputs `"[FFFFFFFF]"`,
* For higher values (`1858<=N<=1953`), the program outputs unpredictable variations of this string,
* For higher values (`1954<=N<=1955`), the program outputs fails flooding the symbol `"["`,
* Over a certain value (`1956<=N`), the programs does not output any character.

I didn't check extensively these results, which could be very different actually, and totally platform dependent, but I guess, reproducible.

Note that *no dynamic allocation* is being used.

Note that *everything is initialized*, first `4` values to `0xFF`, next `N-3` values to `0x00` (Ref.).

The compilation do not show any relevant alert, showing a modest 10% capacity usage.

```
Sketch uses 3206 bytes (10%) of program storage space. Maximum is 30720 bytes.
Global variables use 196 bytes (9%) of dynamic memory, leaving 1852 bytes for local variables. Maximum is 2048 bytes.

```

It is evident from this example how to figure the proper value of `N`, indeed a capacity related issue could be expected (Ref.).

Note these values are by far less than the "guess" value of `N=32767` for 1 byte variables (?) (Ref.).

**2. Problem**

Now, with a considerably huge, real program, I am having the same issue regarding those unexpected results, so I am almost sure (few moments ago) than this is the cause.

When exceeding some "~maximum~" level, the program starts failing, and when "~releasing~" this capacity, the program starts working well (without those deleted functionality of course!).

**3. Question**

**How should I debug, measure, dimension, or prevent this situation**, and specify when it is the proper time to keep this processor, and when should I move into a bigger one, when clearly the compiler is not a reasonable guess?.

```
// CAPACITY TEST
#include <SoftwareSerial.h>

// SET THE PROPER N VALUE
// N<=1857: Last Valid Result
// 1858<=N<=1953: Last Observable Output - Single Char
//     PC=0x0444. [AVR MEMORY] Writing to memory location 0x0948 outside of memory size 0x0900. [UP0]
// 1954<=N<=1955: Last Observable Output - Flood
//     Invalid opcode 0xFFFF at PC=0xA402
//     PC=0x0444. [AVR MEMORY] Writing to memory location 0x0948 outside of memory size 0x0900. [UP0]
// 1956<=N: No Output
//     Invalid opcode 0xFFFF at PC=0xA402
#define N 1857

void setup()
{
    Serial.begin(38400);while (!Serial){;}

    byte a[N+1]={0xFF,0xFF,0xFF,0xFF};

    char si[3];
    Serial.print("[");
    for (int i1=0;i1<=N-1&&a[i1]!=0;i1++){
        sprintf(si,"%02X",a[i1]);
        Serial.print(si);
    }
    Serial.print("]");
}

void loop(){}

```

# Answer
From the bottom to the top of the RAM, you have:

* the .data section (statically allocated initialized variables)
* the .bss section (statically allocated non initialized variables)
* the heap (dynamic allocations with `malloc()` and `new`)
* free space
* the stack (return addresses and automatic local-variable allocations)

See the memories of an Arduino for a more lengthy discussion.

The sizes of the .data and .bss sections are known at build time. This is the “Global variables” memory usage reported at the end of the compilation. The rest of the RAM is available for the heap and the stack. This is the amount reported as “leaving 1852 bytes for local variables”, where “local variables” is a slight oversimplification.

Your example program doesn't use heap allocation. It does use some static allocation, mostly for the `Serial` buffers, and *a lot* of stack for:

* the return addresses from the calls to `main()` and `setup()` (4 bytes)
* the local arrays `a` and `si` (N+4 bytes)
* the memory needed by `sprintf()` or `Serial.print()` (unknown)

Even ignoring the last item, you can see that the whole RAM will be consumed when 4 + N + 4 = 1852, i.e. N = 1844. As you make N larger than this value, the stack bumps into the .bss section, and you start corrupting your global variables. The behavior you describe is consistent with the program corrupting the internal data structures of the `Serial` object.

> How should I debug, measure, dimension, or prevent this situation

There is no easy way to determine beforehand the amount of heap and stack your program will consume. The usual solution is to measure and report it at *run time*. See for example the MemoryFree library (there are many similar to this).
> 2 votes

---
Tags: arduino-nano, memory-usage, debugging
---


# Question
Title: Does upload using `ICSP`overwrite the bootloader?
If I compile a sketch then upload using `ICSP` does it overwrite the bootloader?

I am using Arduino program and `Arduino Uno` as `ICSP`.

# Answer
> 4 votes
Yes.
When you program using ISP you overwrite everything in the chips flash, even the bootloader.

This has some pro's and con's:

* Pro: The program starts immediately, meaning it doesn't wait to check if there's any programming coming in before starting your sketch.
* Con: You need to use ISP to program your Arduino again or to upload the bootloader again.

Normally there is not really any reason for not having the bootloader present but if you are programming bare Atmel chips without a serial interface this way might be preferable.

# Answer
> 1 votes
Yes, it will overwrite the bootloader.

In addition to Hans Neve's list of Pros, it has the added benefit of gaining you a couple hundred bytes (0.5KB) that is otherwise used by the bootloader.

---
Tags: icsp
---


# Question
Title: Can arduino interrupts occur in a middle of if statement?
I got an issues from few days, got some code which reset millis time on successful i2c communication, if not it restart an relay after specified period of time. Here is part of the code:

```
 if ((unsigned long)(i2c1Millis1 - i2cpreviousMillis1) >= i2cset1 )  // check if not restarted soon
        {

```

`i2c1Millis1` are updated every run of the loop and on successful i2c communication.

`i2cpreviousMillis1` is updated on successful i2c request (coming from interrupt)

I manage to debug when false restart occur and looks like `i2c1Millis1` is lower than `i2cpreviousMillis1`

So question is: can an interrupt occur while those two millis are compared when value of `i2c1Millis1` is taken for compare and then come interrupt where `i2cpreviousMillis1` is updated to current millis and it become greater and trigger the condition?

(I already modified my code `i2cpreviousMillis1` is updated with `i2c1Millis1` value on successful communication to prevent that, but it is not working, from time to time it made false restarts).

# Answer
Yes. And it's even worse. Because your variables are `long`s, they are 4 bytes long, and most Arduinos are only 8-bit processors, the code only checks one byte at a time. So for example, after checking the first byte, an interrupt could occur, changing the 2nd, 3rd, and 4th byte. So you end up comparing the first byte of the old value, and other bytes of the new value.

To prevent this you could disable interrupt for a very short time, and make a copy the variable.

```
cli();//disable interrupts
unsigned long temp = i2c1Millis1;
sei();//enable interrupts

```

Or use the util/atomic.h macros

```
#include <util/atomic.h>

...

ATOMIC_BLOCK(ATOMIC_FORCEON)
{
  unsigned long temp = i2c1Millis1;
}

```
> 1 votes

# Answer
Yes, an interrupt can occur at any time and can change the values during a calculation. And since you work with `unsigned long` variables (which are 4 bytes as I remember), it is also possible, that the calculation uses the old value for the first bytes and the new value for the other bytes, meaning that the used value for calcuation is totally garbage.

To prevent that your checks must either be atomic (meaning consisting only of 1 base instruction, which cannot be interrupted, e.g. handling only 1 byte) (that is not possible here), or you must prevent the calculation from being interrupted. For this you can turn off all or only the corresponding interrupt. To turn off all interrupts you can use `noInterrupts()` and `interrupts()` to turn them on again.

But it is questionable, why you need to update this time directly in the ISR. Instead you could only set an atomic flag (1 byte) and check this flag in the loop. If the flag was set, reset it and save the millis value. If you loop runs fast enough (which seems the case, since you already use it to set a millis timestamp) that should be sufficient

Both ways can be used and it depends on you, if it's ok to turn of interrupts for a short time, since you might miss an I2C interrupt this way.
> 1 votes

# Answer
Yes. An interrupt can occur pretty much anywhere.

Interrupts are processed between each *assembly language* instruction. That `if` will be made up of many many ASM instructions, so there are many many places where an interrupt can occur.

To avoid it you use what are called *critical sections* where you disable interrupts before performing some operations, then enable them again afterwards.

It is recommended to keep critical sections as short as possible to avoid breaking your interrupts. For this reason most critical sections generally involve copying values to or from local variables before then doing operations on them.

```
noInterrupts();
uint32_t localPreviousMillis = i2cpreviousMillis1;
interrupts();

if ((unsigned long)(i2c1Millis1 - localPreviousMillis) >= i2cset1 )  // check if not restarted soon

```

On an 8-bit system even assigning a simple value like that can be interrupted. A 32-bit value is made up of four 8-bit values, and an interrupt can occur between the copying of any of those 4 bytes.
> 0 votes

---
Tags: interrupt
---


title: Trouble with i2c on ESP8266

text:
# Question
Title: Trouble with i2c on ESP8266
I have used with partial success I2C with the ESP8266. When it works, it works well, with many devices on the bus. I've examined the signals on a 'scope to assure Vlo, Vhi, Tr, and Tf.

However, often it works not at all. No I2C devices (even if there is only one connected) are detected. This condition is determined by some unknown factor, and it stays in this condition for some time (days?) before it starts working again. Power cycle, reset-by-button, and reset-by-reflashing do not restore operation until it works again.

This has occurred with at least three ESP8266 modules from two different manufacturers with different pinouts. It affects all connected I2C devices. They are all slaves to the ESP8266.

What should I try next?

# Answer
The signals had looked good, but I did not examine them closely enough. When I removed extra pullup resistors I had added on SCL and SDA, I2C worked.
> 0 votes

---
Tags: esp8266, i2c
---


# Question
Title: Can I use an AC signal to make an LED light up with arduino?
I want to use a 220VAC load as a signal and act as a switch to my arduino so Labview could interpret it as an LED ON state. I used a 4n33 octocoupler but it seems that the LED Simulation on labview keeps fluctuating. I think it's because of the negative half of the signal being blocked. Is there a way to fix this?

Here is my schematic

# Answer
> 2 votes
There's certainly an issue with your optocoupler circuit aside from the fluctuation you observe.

During a negative half-wave of 220V, you expect D1 to block the current through the LED. However, 1N4007 as any power rectifier has significant leakage current, about 5μA at normal temperature and up to 50μA when the diode is hot. This current will go though the LED which may have a much lower admissible reverse current (typical 0.1μA), damaging it. One possible schematic would be:

simulate this circuit – Schematic created using CircuitLab

Note that D1 is here not to block reverse current, but rather conduct it safely, protecting the LED of the optocoupler. Also, consider reducing the value of R2 while realising the bulk of current limitation with a non-polar capacitor: this setup will limit the current just the same but will dissipate 0.5W of heat instead of 2W as your resistor would.

Now, in either case the LED is only active when it's forwad-biased, which is less than half of the time, so it's quite normal that you see this fluctuation. In most cases, it can be reasonably dealt with by software: read your pin 3 times with a 5ms delay after each reading, and make a logical AND of your three readings.

If, for some reason you cannot do that in software, you could implement an envelope detector in hardware. I strongly suggest to do it on the low-voltage side instead of 220V side (as e.g. here)

---
Tags: switch
---


# Question
Title: Will the Duemilanove bootloader work in the Uno?
Similar to Will the Uno bootloader work in the Duemilanove? but the other way around.

I have an Arduino Uno. I require a slower upload speed than the 115200 baud rate used in the Uno's Optiboot bootloader.

The Arduino Duemilanove uses the ATmegaBOOT\_168\_atmega328 bootloader which has an upload baud rate of 57600. The Arduino Duemilanove also uses the ATMega328P like used on the Arduino Uno.

Will the Duemilanove bootloader work in the Uno?

# Answer
Yes it will.

Both the Arduino Duemilanove and Arduino Uno use the ATMega328P microcontroller. (There is also a version of Arduino Duemilanove ATMega168 that uses the Diecimila bootloader and that is not compatible, so just watch out).

The main difference between the Arduino Duemilanove and the Arduino Uno is that the Duemilanove uses FTDI FT232R IC, whereas the Uno uses the Atmega8u2 microcontroller fto handle the USB to serial UART interface.

Also important is that both boards both have the same 16MHz clock rate.

The schematic for the Arduino Duemilanove can be found here.
The schematic for the Arduino Uno can be found here.

Of course, instead of selecting `Arduino Uno` as the board type, you need to always select `Arduino Duemilanove or Diecimila` and the `ATmega328` processor.
> 2 votes

# Answer
*The question asks about Y problem. Here is the solution for the problem X in this X-\>Y situation.*

> I require a slower upload speed than the 115200 baud rate used in the Uno's Optiboot bootloader.

The Optiboot bootloader can work on different UART baud rates. The baud rate is configurable as parameter of the make command at build.

If don't want to setup the toolchain for compilation of the bootloader, MCUdude has on GitHub ready Optiboot hex files compiled with many options.

I recommend to use a custom boards definition for boards with not standard settings to burn the bootloader and to upload to the board. Here I have my https://github.com/jandrassy/my\_boards as example.
> 2 votes

---
Tags: arduino-uno, bootloader, arduino-duemilanove
---


# Question
Title: Switching between SPI Devices when one is an SD card
I'm using a USB Barcode scanner connected via a USB shield, I'm able to get the readings from the barcode using this example, After getting this readings, I'd like to save it to an SD card but the SD card won't initialize since the barcode also uses SPI, how can I deactivate the ICSP in order to activate the SD card? Or how to switch between multiple SPI slaves?

# Answer
> 1 votes
with SPI there is an implicit slave select pin on each device that must be pulled low to enable the device.

Connect each slave select pin of the SPI device to their own unused digital pin on your arduino and keep it pulled high until you want to talk to the slave.

However not all SPI devices will properly put the MISO pin into high impedance when SS is pulled high so you may need to use a tristate buffer on that pin or use a multiplexer.

When adding your own tristate buffer (for example a HS125) you need to connect each MISO pin of the SPI device to the input of a buffer, the slave select is then connected to the output enable pin of the tristate. The outputs of the buffers can be connected together along with the MISO pins of the devices that do properly go high impedance to the MISO of the master.

When using multiplexers there are 2 options:

1. You can daisy chain 2:1 multiplexers by connecting the MISO of the device to the 0-input of the mux and the Slave select to the select input pin of the mux.
2. you can use a \>2 multiplexer to select the correct MISO line based on the address of a set of S lines. Then with a decoder you can provide the actual SS signal to the SPI device. This way you only need 2 SS pins for 4 SPI devices.

# Answer
> 0 votes
Refer to the schematic below for a visual explanation of what is explained in this thread regarding a tri-state buffer. I have used this circuit successfully on a PCB. I got this schematic from: © 2017 Vishnu M Aiea. www.vishnumaiea.in

---
Tags: usb, shields, spi
---


# Question
Title: Why am not being able to initialize the Micro-SD?
The reason I bought this MicroSD board because to follow their **guide** and I have used the recommend code in: File \> Example \> SD \> CardInfo also did the slight change in the code for `const int chipSelect = 10;`

Here is the exact code I am using:

```
/*
  SD card test

  This example shows how use the utility libraries on which the'
  SD library is based in order to get info about your SD card.
  Very useful for testing a card when you're not sure whether its working or not.

  The circuit:
    SD card attached to SPI bus as follows:
 ** MOSI - pin 11 on Arduino Uno/Duemilanove/Diecimila
 ** MISO - pin 12 on Arduino Uno/Duemilanove/Diecimila
 ** CLK - pin 13 on Arduino Uno/Duemilanove/Diecimila
 ** CS - depends on your SD card shield or module.
     Pin 4 used here for consistency with other Arduino examples

  created  28 Mar 2011
  by Limor Fried
  modified 9 Apr 2012
  by Tom Igoe
*/
// include the SD library:
#include <SPI.h>
#include <SD.h>

// set up variables using the SD utility library functions:
Sd2Card card;
SdVolume volume;
SdFile root;

// change this to match your SD shield or module;
// Arduino Ethernet shield: pin 4
// Adafruit SD shields and modules: pin 10
// Sparkfun SD shield: pin 8
// MKRZero SD: SDCARD_SS_PIN
const int chipSelect = 10;

void setup() {
  // Open serial communications and wait for port to open:
  Serial.begin(9600);

    pinMode(10, OUTPUT); // change this to 53 on a mega(don't follow this!!)
    digitalWrite(10, HIGH); // Add this line

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

  Serial.print("\nInitializing SD card...");

  // we'll use the initialization code from the utility libraries
  // since we're just testing if the card is working!
  if (!card.init(SPI_HALF_SPEED, chipSelect)) {
    Serial.println("initialization failed. Things to check:");
    Serial.println("* is a card inserted?");
    Serial.println("* is your wiring correct?");
    Serial.println("* did you change the chipSelect pin to match your shield or module?");
    while (1);
  } else {
    Serial.println("Wiring is correct and a card is present.");
  }

  // print the type of card
  Serial.println();
  Serial.print("Card type:         ");
  switch (card.type()) {
    case SD_CARD_TYPE_SD1:
      Serial.println("SD1");
      break;
    case SD_CARD_TYPE_SD2:
      Serial.println("SD2");
      break;
    case SD_CARD_TYPE_SDHC:
      Serial.println("SDHC");
      break;
    default:
      Serial.println("Unknown");
  }

  // Now we will try to open the 'volume'/'partition' - it should be FAT16 or FAT32
  if (!volume.init(card)) {
    Serial.println("Could not find FAT16/FAT32 partition.\nMake sure you've formatted the card");
    while (1);
  }

  Serial.print("Clusters:          ");
  Serial.println(volume.clusterCount());
  Serial.print("Blocks x Cluster:  ");
  Serial.println(volume.blocksPerCluster());

  Serial.print("Total Blocks:      ");
  Serial.println(volume.blocksPerCluster() * volume.clusterCount());
  Serial.println();

  // print the type and size of the first FAT-type volume
  uint32_t volumesize;
  Serial.print("Volume type is:    FAT");
  Serial.println(volume.fatType(), DEC);

  volumesize = volume.blocksPerCluster();    // clusters are collections of blocks
  volumesize *= volume.clusterCount();       // we'll have a lot of clusters
  volumesize /= 2;                           // SD card blocks are always 512 bytes (2 blocks are 1KB)
  Serial.print("Volume size (Kb):  ");
  Serial.println(volumesize);
  Serial.print("Volume size (Mb):  ");
  volumesize /= 1024;
  Serial.println(volumesize);
  Serial.print("Volume size (Gb):  ");
  Serial.println((float)volumesize / 1024.0);

  Serial.println("\nFiles found on the card (name, date and size in bytes): ");
  root.openRoot(volume);

  // list all files in the card with date and size
  root.ls(LS_R | LS_DATE | LS_SIZE);
}

void loop(void) {
}

```

and this is the schematic I have used as they recommended  but the serial monitor keeps outputting `Initializing SD card...initialization failed` I have tried wiring again and again but I am still getting the same result.

Here are the **photo** of the **wiring and running** the test. There is something I'm not sure if it is helpful but after I upload the file and before the serial monitor output:

```
Initializing SD card...initialization failed. Things to check:
* is a card inserted?
* is your wiring correct?
* did you change the chipSelect pin to match your shield or module?

```

a red led located next to R1 of the MicroSD card starts flashing and before that output, it flashes faster then it stops and I will be presenting with that output.

Things I have tried...

* Different card
* Without the card
* Tried the 3v
* Tried using pin 4 for chipSelect

Please don't mark as duplicate because I looked at the other and I'm trying to use this guide by this company and also this guide was presenting as a solution for others and here I am using it.

**Edit 1:**

After the writing this question, I had to upload the file again so I can take pictures when I did that this time the serial monitor outputs:

```
23:02:10.089 ->
23:02:10.089 -> Initializing SD card...initialization failed. Things to check:
23:02:12.106 -> * is a card inserted?
23:02:12.106 -> * is your wiring correct?
23:02:12.106 -> * did you change the chipSelect pin to match your shield or module?

```

Looks like I am stuck with that and the only number keep changing

```
23:11:02.769 ->
23:11:02.769 -> Initializing SD card...initialization failed. Things to check:
23:11:04.778 -> * is a card inserted?
23:11:04.778 -> * is your wiring correct?
23:11:04.778 -> * did you change the chipSelect pin to match your shield or module?

```

**Edit 2:**

Sorry but it looks these numbers coming because I did mark the `show timestamps` box by mistake.

# Answer
The board on the photo is Arduino Micro, not Arduino Nano. Arduino Micro doesn't have SPI on pins 11, 12, 13. Use pins MOSI, MISO and SCK.

* MO to DI
* MI to DO
* SCK to CLK
* you can use any pin as CS, only set it as parameter to `SD.begin()`
> 1 votes

---
Tags: sd-card, datalogging
---


# Question
Title: ESP 32 changing frequency instead of duty cycle
Using this code on an esp32 allow to vary duty cycle of the PWM with a fixed 5000Hz frequency and is working fine.

My question is how to vary frequency and keep duty cycle on a fixed value?

```
// the number of the LED pin
const int ledPin = 16;  // 16 corresponds to GPIO16

// setting PWM properties
const int freq = 5000;
const int ledChannel = 0;
const int resolution = 8;

void setup(){
  // configure LED PWM functionalitites
  ledcSetup(ledChannel, freq, resolution);

  // attach the channel to the GPIO to be controlled
  ledcAttachPin(ledPin, ledChannel);
}

void loop(){
  // increase the LED brightness
  for(int dutyCycle = 0; dutyCycle <= 255; dutyCycle++){
    // changing the LED brightness with PWM
    ledcWrite(ledChannel, dutyCycle);
    delay(15);
  }

  // decrease the LED brightness
  for(int dutyCycle = 255; dutyCycle >= 0; dutyCycle--){
    // changing the LED brightness with PWM
    ledcWrite(ledChannel, dutyCycle);
    delay(15);
  }
}

```

Thanks

# Answer
If you want to change the pwm frequency during runtime there is a function `ledc_set_freq()` for this purpose. I'm not sure if your duty cycle will remain valid, but I guess it does as long as the resolution does not change. You will have to try that on your own and eventually implement a compensation.
> 0 votes

---
Tags: pwm, esp32, frequency
---


# Question
Title: Fail to return int value from a function
I have created `myJSON` library to simplify read and write values from/ to FLASH of my ESP8266 NodeMCU/ Wemos Mini.

I do not want to "mess up" the question, posting my entire code/ library - but to try to explain what happens -

I get a `0` value when reading a specific `key` (and not its saved `value` ). My assumption is that is has nothing to do with `myJSON` library, but my understanding in returning a value from a function.

Code is as follows:

(some explanations first):

1) `json` is an instance of `myJSON` library.

2) `json.setValue(key, value)` \- gets a `key` and a `value` ( char/ int) and save it to FLASH.

3)`json.getINTValue(key, return_var)`\- gets a `key` and return its `int` value to `return_var`. function return 1 - for successful read, and 0 when not.

inside `setup()`

```
int int_val;
// json.setValue("int_key",343); // commented out after first run - to be sure is is saved and read from flash.
Serial.println(json.getINTValue("int_key",int_val)); // NOTE 2
Serial.print("Value is: "); // NOTE 3
Serial.println(int_val);   //  NOTE 3

```

`myJSON` ( only relevant code )

```
bool myJSON::getINTValue (const char *key, int retval){
        StaticJsonDocument<DOC_SIZE> tempJDOC;
        myJSON::readJSON_file(tempJDOC);
        bool hasKey = tempJDOC.containsKey(key);
        if (hasKey){
          retval = tempJDOC[key];
          Serial.print("retval :"); // NOTE 1
          Serial.println(retval);  // NOTE 1
          return 1;
        }
        else {
          return 0; // when key is not present
        }
}

void myJSON::setValue(const char *key, char *value){
        StaticJsonDocument<DOC_SIZE> tempJDOC;
        myJSON::readJSON_file(tempJDOC);
        tempJDOC[key]=value;
        myJSON::saveJSON2file(tempJDOC);
}
void myJSON::setValue(const char *key, int value){
        StaticJsonDocument<DOC_SIZE> tempJDOC;
        myJSON::readJSON_file(tempJDOC);
        tempJDOC[key]=value;
        myJSON::saveJSON2file(tempJDOC);
}

```

result is (SEE NOTATIONS):

```
21:01:03.198 -> retval :343  // OUTPUT NOTE 1
21:01:03.198 -> 1            // OUTPUT NOTE 2
21:01:03.198 -> Value is: 0  // OUTPUT NOTE 3

```

As far a I could understand :

1) `setValue` works as needed ( inc. saving to flash ). 2) unexplained besides getting value = 0, is when setting a `char` value ( there are 2 `myJSON::setValue` functions to deal with `int` and `char`), code works as needed.

Appreciate any help ( and sorry for my English ).

Guy

# Answer
> 2 votes
the parameters of a function call are copied into parameters in the function. if the pointer is copied it still points to a memory where you write the data. if int is copied then changing the value changes the copy, not the variable used as parameter. reference is kind of pointer

how to make an in-out parameter by passing a parameter by reference

```
void setup() {

  Serial.begin(115200);
  int x = 3;
  fnc(x);
  Serial.println(x);
}

void loop() {

}

void fnc(int &x) {
  x = 5;
}

```

prints 5

example with a complex type

```
#include <IPAddress.h>

void setup() {

  Serial.begin(115200);
  IPAddress ip(192, 168, 1, 5);
  fnc(ip);
  Serial.println(ip);
}

void loop() {

}

void fnc(IPAddress& ip) {
  ip = IPAddress(192, 168, 1, 3);
}

```

with &ip it prints 192.168.1.3. without & it prints 192.168.1.5

# Answer
> 2 votes
Your problem is not directly how to return a variable, but how to give a variable from outsite the function as parameter to be filled by the function. There are basically 2 types how you can give a variable to a function: by value or by reference

The definition of `getINTValue()` says

```
getINTValue (const char *key, int retval)

```

so `retval` will be an integer and is called by value. This means, that a local variable with that name is created and filled with the value from the function call parameters. You are writing to this variable, but it get's thrown away when the function returns. And the writing to the local variable didn't change the outsite variable.

You need to use a call by reference. Your function must take a pointer to an integer variable. Then you dereference it and write to it:

```
getINTValue (const char *key, int *retval){
    ...
    *retval = tempJDOC[key];
    ...
}

```

When you call the `getINTValue()` function, it must be done like this:

```
int value;
bool result = getINTValue("int_key", &value);

```

The `&` operator gets you the pointer to the variable `value`, which the function then uses to write a value at that memory location.

---

`char*` is different, because you give an array to the function in this case. The compiler sees, that the used variable is an array and uses the pointer to the first element of the array as parameter. That is a common way, because you can iterate over an array by using pointers (without index numbers). You can do the same with any array of any type, but in this case you only have a single variable, not an array.

---
Tags: functions
---


# Question
Title: Communicating with Arduino Mega 2560 Serial ports through x2 RS232
I am trying to drive a stepper motor using an Arduino Mega 2560. There will ideally be two RS232 signals being read into / written from the Arduino, each using male USB 3.0 connectors; one of these is for configuring and controlling the driver of the motor and the other is simply getting an output torque measurement from a torque meter connected to the motor's shaft.

I am simply wondering if Arduino would be able to handle these two functions, and how I might go about connecting each of the two streams of data. I have looked into this question through Arduino documentation, tutorials, and forums for hours, and finally figured I would contribute to the posts on my own.

Thank you!

* a confused college student

# Answer
> 1 votes
Your main problem seems to be confused by all the information. I will give you some more.

The Arduino speaks UART (Universal Asynchronous Receiver Transmitter) with it's `Serial` interfaces (there are 4 of these on the Mega). This is partly the same protocol as RS232, but it uses TTL logic levels (in this case the levels 5V and 0V), while RS232 has different voltage levels and more lines (like control lines). When you connect your Arduino to a PC, the PC is not directly talking to the Arduinos chip (here the Atmega2560). Instead every Arduino with a USB port has an extra chip. It will handle the (very complex) USB communication, so that you can see an emulated COM port on your PC. The data, that the PC sends to that COM port, get's transmitted over USB to that extra chip, which in turn will convert it to UART signals and send them to the Atmega2560.

All Arduinos, that I know of, have only 1 USB-to-UART chip. But you can add your own USB-to-UART chip to one of the other Serial interfaces. You can use a FTDI chip, an Atmega16U2 or (if you don't want to program an extra chip) simply an USB-to-UART converter cable/module, which you can buy and use directly by just connecting their pins to the Arduinos Serial pins.

---

By the way, it doesn't really matter here, if you use USB3.0 ports, since chips this small cannot work with speeds that high. All these chips use USB2, more is not necessary, they aren't fast enough.

---
Tags: arduino-mega, usb, rs232, stepper-motor
---


# Question
Title: How can I measure the point of contact between two wires?
I'm not sure the best way to ask this question, so I'll try to explain what I'm looking for, and roughly what I think is involved.

I want to measure the point of contact between two wires. This seems like it could be a resistance measurement, but I wasn't sure if that was the best way to go as it seems like the amount of change would be too small to measure.

Specifically I have two wires (more likely some sort of conductive ribbon) on a glove. One wire runs along the index finger, and the other is at the tip of the thumb. When someone touches their thumb to their finger, I want a value that indicates approximately where they touched.

For example, if they touch the tip of their finger to their thumb the value would be 1. If they touched their thumb to their first knuckle, then the value would be 0.75. And so forth. With a touch between two "points" producing a value in between.

Ideally someone could slide their thumb down their finger and produce a slowly changing value from 1 to 0.

Is resistance the way to go for this? It seems like there could a lot of other variables (surface area of contract, humidity, etc) that could dramatically change the resistance. Is there a better method?

**Update:** Because of some *overzealous* votes to close and confusion, this will be using the Arduino platform (maybe an ESP32, if that matters) once I figure out what sort of sensors and systems to work with.

# Answer
you could try 4 terminal sensing.

I have not used it myself, but the basic idea is to try to normalise for some of the external factors you mention.

As for the Arduino, the analog to digital converters have 10 bits of precision. This means you will get 1023 distinct values as the input voltage varies betwee 0 and Vmax (+5 or +3.3 depending upon the actual device). So that is fairly precise, usually you just use the value from the analog read - but you can convert to a value between 0 and 1 by dividing:

```
    int analogInt = analogRead(<your port here- e.g. A0>);
    double analogFloat = analogInt / 1023.0

```

Which begs the question, did you try using a 2 wire system? Assuming just 1000 data points, and a finger being, say, 5cm in length; that's roughly 1 point per .05 mm. I know it won't work out exactly like that, but that is my point - it is likely to be a rough estimate anyway due to the size of a finger at the touch point.
> 2 votes

---
Tags: sensors
---


# Question
Title: How can I connect multiple MCP23017's to an arduino?
I am working on a project and I am trying to figure out how to connect multiple MCP23017 IO Expanders to one arduino. All of the guides that I have found in my quest for information only explain how to connect one MCP chip or how to address multiple MCP chips. None seem to explain how to connect them physically. BTW, I am talking about the I2C version of the chip.

# Answer
If you know how to connect one chip you know how to connect many chips. One or eight it's the same.

All the SCL pins connect to the SCL pin of the Arduino. All the SDA pins connect to SDA on the Arduino.

Just make sure that each chip is given a unique address using the A0-A2 pins as detailed in the datasheet.
> 3 votes

---
Tags: arduino-uno
---


# Question
Title: Changing ESP-12E NodeMCU to ESP-01S - how to trigger sketch?
I had my sketch up and running with a NodeMCU and a Leonardo Pro Micro and decided I wanted to minimize the footprint of the project and use the smaller ESP-01S board instead.

The ESP-01S is programmed to send a push notification to Pushover and my old code works - the only problem is that I don't know how to trigger it from the Pro Micro.

With the NodeMCU I just setup it up to listen on Pin 2 and I triggered a high/low from my Pro Micro and it sent the push notification - at the moment as soon as I power the ESP-01S up it just sends the push notification over and over and doesn't see the connection from the Pro Micro to stop it doing this.

Here is my current code on the ESP-01S

```
#include <ESP8266WiFi.h>

// Wifi Settings
const char* ssid = "Redacted";
const char* password = "Redacted";
// Pushover settings
char pushoversite[] = "api.pushover.net";
char apitoken[] = "Redacted";
char userkey [] = "Redacted";
int length;
WiFiClient client;
void setup() {
  pinMode(0, OUTPUT);
  digitalWrite(0, LOW);
  pinMode(2, INPUT);
  Serial.begin(9600);
  delay(10);

  // Connect to WiFi network
  Serial.println();
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);

  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.println("WiFi connected");

  // Print the IP address
  Serial.print(WiFi.localIP());

}

void loop()
{
if(digitalRead(5) == 1) pushover("Deployment Completed");
}

byte pushover(char *pushovermessage)
{
 String message = pushovermessage;

 length = 81 + message.length();

if(client.connect(pushoversite,80))
 {
   client.println("POST /1/messages.json HTTP/1.1");
   client.println("Host: api.pushover.net");
   client.println("Connection: close\r\nContent-Type: application/x-www-form-urlencoded");
   client.print("Content-Length: ");
   client.print(length);
   client.println("\r\n");;
   client.print("token=");
   client.print(apitoken);
   client.print("&user=");
   client.print(userkey);
   client.print("&message=");
   client.print(message);
   while(client.connected())
   {
     while(client.available())
     {
       char ch = client.read();
       Serial.write(ch);
     }
   }
   client.stop();
 }
}

```

and my Leonardo Pro Micro code is as follows

```
#include <HID-Project.h>
#include <HID-Settings.h>
int buttonPin;
int buttonPin2;
char chr;   // for incoming serial data, type char is signed 8-bit, -128 to 127, ASCII is char codes. Save 1 byte over type int.

void setup() {
  pinMode(5, OUTPUT);
  pinMode(7, OUTPUT);
  BootKeyboard.begin();
  Keyboard.begin();
  Mouse.begin();
  Serial.begin(115200);
  buttonPin = 4; //White Button
  buttonPin2 = 6; //Black Button
  pinMode(buttonPin, INPUT_PULLUP);
  pinMode(buttonPin2, INPUT_PULLUP);
}

void loop() {
  delay(5000);
  digitalWrite(5, HIGH);
  delay(100);   //short wait time
  digitalWrite(5, LOW);
  }

```

Obviously I want the digital pin 5 of the Pro Micro to trigger the ESP-01 to send a push notification when it's trigger.

Just for the record I'm using a 3.3v Pro Micro btw so there's no issue with the voltage here, before I was using a Logic Converter with a 5v board.

I have the ESP-O1S setup with the 3V3 and EN are connected to the 3v VCC on the Pro Micro, the GND to GND and I tried IO0 and IO2 to Digital Pin 5 on the Pro Micro.

Could someone point me in the right direction?

# Answer
> 1 votes
Use io 0 as the esp-01S pin wired to Micro, but change the logic for pull-up, because esp-01S has a pull-up resistor on io 0 of the esp8266. Use LOW to trigger the action and HIGH as normal state.

On Arduino Micro side set the output pin HIGH before you set it as OUTPUT. This will avoid the LOW state. While the Micro pin is in INPUT state after power-up, the pull-up resistor on esp-01S will pull io 0 HIGH.

---
Tags: esp8266, nodemcu, arduino-leonardo, arduino-pro-micro
---


title: strtoul behavior between C and Arduino

text:
# Question
Title: strtoul behavior between C and Arduino
I have this code C code that compiles OK on my laptop

```
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

unsigned int crc32(const void *m, size_t len) {
  const unsigned char *message = m;
  size_t i;
  int j;
  unsigned int byte, crc, mask;

  i = 0;
  crc = 0xFFFFFFFF;
  while (i < len) {
    byte = message[i];
    crc = crc ^ byte;
    for (j = 7; j >= 0; j--) {
      mask = -(crc & 1);
      crc = (crc >> 1) ^ (0xEDB88320 & mask);
    }
    i = i + 1;
  }
  return ~crc;
}

int main() {
  char str[] =
      "620004";
  size_t len = strlen(str);
  unsigned int crc = crc32(str, len);

  size_t len2 = (len + 1) / 2;
  unsigned char arr2[len2];
  for (size_t i = 0; i < len; i += 2) {
    arr2[i / 2] = strtoul((char[3]) {str[i], str[i + 1], '\0'}, 0, 16);
  }
  crc = crc32(arr2, len2);
  printf("CRC: 0x%X\n", crc);

  return 0;
}

```

And I'm trying to port it to Arduino

```
#include <CRC32.h>

void setup() {
  Serial.begin(115200);
  uint8_t byteBuffer[] = "620004";
  size_t numBytes = sizeof(byteBuffer) - 1;
  size_t len2 = (numBytes + 1) / 2;
  unsigned char arr2[len2];
  CRC32 crc;
  for (size_t i = 0; i < numBytes; i += 2) {
    arr2[i / 2] = strtoul((char[3]) {byteBuffer[i], byteBuffer[i + 1], '\0'}, 0, 16);
  }
  for (size_t i = 0; i < numBytes; i++){
    crc.update(byteBuffer[i]);
  }

  uint32_t checksum = crc.finalize();
  Serial.print("CRC: ");
  Serial

```

But I'm getting a

```
Arduino: 1.8.9 (Linux), Board: "Arduino/Genuino Uno"

/home/nico/Arduino/crc32/crc32.ino: In function 'void setup()':
/home/nico/Arduino/crc32/crc32.ino:11:50: warning: narrowing conversion of 'byteBuffer[i]' from 'uint8_t {aka unsigned char}' to 'char' inside { } [-Wnarrowing]
     arr2[i / 2] = strtoul((char[3]) {byteBuffer[i], byteBuffer[i + 1], '\0'}, 0, 16);
                                                  ^
/home/nico/Arduino/crc32/crc32.ino:11:69: warning: narrowing conversion of 'byteBuffer[(i + 1u)]' from 'uint8_t {aka unsigned char}' to 'char' inside { } [-Wnarrowing]
     arr2[i / 2] = strtoul((char[3]) {byteBuffer[i], byteBuffer[i + 1], '\0'}, 0, 16);
                                                                     ^
crc32:11:84: error: taking address of temporary array
     arr2[i / 2] = strtoul((char[3]) {byteBuffer[i], byteBuffer[i + 1], '\0'}, 0, 16);
                                                                                ^
exit status 1
taking address of temporary array

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

```

And I'm not really understanding what's the issue here with the `strtoul` function and its different behavior on Arduino

# Answer
In some architectures a "char" is an "unsigned byte". In others it's a "signed byte". The AVR specification mandates a signed byte for char. Whatever you are compiling on probably mandates an unsigned char.

You cannot assume one or another. If you are working with an array of characters (a "string") you should be assigning it to a `char` data type. That way the signage of the data type and the "string" content will match.

By using `uint8_t` you are specifically telling it to use an unsigned byte.

`strtoul()` expects a char. Since on AVR char is signed, when you try and squeeze an 8-bit value into a 7-bit + sign space it warns you. Which is good. You potentially lose the 8th bit of your data.

The main error, though, is:

```
error: taking address of temporary array

```

This is caused by you creating a new temporary array within the parameter list of `strtoul`.

```
{byteBuffer[i], byteBuffer[i + 1], '\0'}

```

Then you take the address of that array and pass it to the function. That is not good. Imagine the situation where the function returns something that is dependent on that address. For instance a function that returns a pointer to all but the first character of the string. Once the function returns that returned pointer points to an area of memory that is no longer valid - the temporary array has already been disposed of.

I know that's not the case in your code, but it's a possibility you can conceive.

Yes, temporary arrays like that are perfectly valid in some versions of C++. But those are fairly recent versions, and the Arduino compiler isn't that recent (I don't know which version introduced them as valid off hand, but we're up to GCC version 8 now. Arduino is still down at version 5.something IIRC).

Suffice it to say, don't use temporary arrays like that (which is a shame, because it's damn useful). Instead you have to assign it to a new array and pass the pointer to that array instead:

```
char tempArr[3] = {byteBuffer[i], byteBuffer[i + 1], '\0'};
 arr2[i / 2] = strtoul(tempArr, 0, 16);

```

That way the address you're passing to the function is one that is allocated on the stack and is guaranteed to exist past the lifetime of the function call (right up until the end of the current scope).
> 0 votes

# Answer
Not questioning the language issues that were pointed out, but simple answer to what you asked,

> "... what's the issue here with ... its different behavior on Arduino"

is that these are two different compilers, possibly written to two different standards of the language (the standards evolve over time) and likely run with different error- and warning suppression switches.

And not to be pedantic but to clarify, it hasn't actually run on the Arduino yet, not having compiled successfully in that environment. The differences you see are entirely due to the differences between the two compilers and the error-options they were run with.
> 0 votes

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


# Question
Title: Can you drive a stepper motor without the L293D
Can you drive a stepper motor without L293D.

Don't awnser without giving explanations or saying it will be cheaper to buy the L293D.

Thanks

# Answer
Depending on the type of stepper motor the answer can be "Yes" or "No".

There are two types of stepper motor: Unipolar and Bipolar. Bipolar motors typically have 4 wires and require a H-bridge to drive them.

The L239D is a popular (and cheap), though inefficient, H-bridge that is commonly used. But it is possible to build your own H-bridge from discrete components. There are a lot of caveats and pitfalls when building your own H-bridge though, so people generally don't unless they have a specific requirement that isn't addressed by an integrated one. There are plenty of schematics and descriptions of operation online if you want to learn more about H-bridges.

There are also dedicated bipolar stepper drivers which are easier to work with: you just set the direction and give it a pulse to step in that direction. Much easier to program with, but can be more expensive. However these do tend to be more modern MOSFET based components which are far more efficient and dissipate less heat (or can handle more powerful motors in a similar size package).

Unipolar stepper motors, on the other hand, have more wires (typically 6) and are much simpler to drive. All you need for these is a transistor per coil (typically 4 coils connected as pairs) and you just need to activate them in the right sequence.

The ULN2003 is a popular integrated chip for driving unipolar stepper motors. It's just a bunch of transistors in a single package that is easier to wire up than discrete transistors, though there is no reason why you couldn't do it just with 4 discrete transistors. It's just simpler and tidier to use a single chip.

There are plenty of demonstrations and tutorials online describing driving a unipolar stepper motor with the ULN2003.
> 2 votes

---
Tags: motor, stepper, transistor, l293d
---