body:
I am having an issue in my 1.8" TFT LCD module with SPI interface in Arduino Nano. I keep seeing the white screen on my tft.

I have made the following connections using Jumper cables:

 - 1. RST  --- connected to D8 (on Nano)
 - 2. CE/CS --- Connected to D10
 - 3. DC ----  Connected to D9
 - 4. DIN (MOSI) -- connected to D11
 - 5. CLK --- connected to D13
 - 6. VCC --- connected to 5V
 - 7. BL ---- Connected to 3.3 V
 - 8. GND -- connected to GND

Sorry i am new to this world, so dont know how i can provide you the wiring connections i have made and so jotted it down in this post.

I am using the Adafruit ST7735 GraphicsTest with the code modified according to the above pin:

    /**************************************************************************
      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
      The 1.14" TFT breakout
      ----> https://www.adafruit.com/product/4383
      The 1.3" TFT breakout
      ----> https://www.adafruit.com/product/4313
      The 1.54" TFT breakout
        ----> https://www.adafruit.com/product/3787
      The 2.0" TFT breakout
        ----> https://www.adafruit.com/product/4311
      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>

    #if defined(ARDUINO_FEATHER_ESP32) // Feather Huzzah32
      #define TFT_CS         14
      #define TFT_RST        15
      #define TFT_DC         32

    #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        8 // Or set to -1 and connect to Arduino RESET pin
      #define TFT_DC         9
    #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 use:
    // Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_RST);

    // For 1.14", 1.3", 1.54", and 2.0" 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

    // For ST7735-based displays, we will use this call
    Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_MOSI, TFT_SCLK, TFT_RST);

    // OR for the ST7789-based displays, we will use this call
    //Adafruit_ST7789 tft = Adafruit_ST7789(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"));

      // Use this initializer if using a 1.8" TFT screen:
      tft.initR(INITR_BLACKTAB);      // Init ST7735S chip, black tab

      // OR use this initializer if using a 1.8" TFT screen with offset such as WaveShare:
      // tft.initR(INITR_GREENTAB);      // Init ST7735S chip, green 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" 160x80 TFT:
      //tft.initR(INITR_MINI160x80);  // Init ST7735S mini display

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

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

      // OR use this initializer (uncomment) if using a 1.14" 240x135 TFT:
      //tft.init(135, 240);           // Init ST7789 240x135

      // SPI speed defaults to SPI_DEFAULT_FREQ defined in the library, you can override it here
      // Note that speed allowable depends on chip and quality of wiring, if you go too fast, you
      // may end up with a black screen some times, or all the time.
      //tft.setSPISpeed(40000000);

      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);
      uint16_t 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);
      uint16_t 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);
    }

The Output of this code on serial output:

    01:16:16.840 -> Hello! ST77xx TFT TestInitialized
    01:16:19.829 -> 1876
    01:17:44.911 -> done

I have tried many things from past two days but no luck on this issue.
I have seen the following posts and implemented but effort gone in just accumulating knowledge but unable to resolve the issues:

https://arduino.stackexchange.com/questions/62308/what-am-i-missing-st7735-tft-white-screen
https://arduino.stackexchange.com/questions/65997/why-am-i-only-seeing-white-screen-in-tft-1-44-st7735/66002#66002

Kindly please let me know in case anyone resolves this issue.

title: ST7735s 1.8" SPI 128x160 TFT Module - White Screen

Answers: 1

body:
I have a 1.44' SPI 128x128 V2.0 [Blueish (teal) PCB, Green Tab Screen].

I was having the same problem. I had connected the VCC pin to 3.3V.

Solution: connect VCC to the 5V pin

The white screen is gone. I hope it helps.


body: I have used sim900 in my project but it isn't fast, I don't know if it is because it is on 2G or what, I wanna know if I can get something good that can send SMS messages immediately and doesn't take time to send multiple messages, if I switch to something that supports 3g can that solve my problem?

title: Fastest sim module available?

Answers: 0


body:
There is an external FLASH memory ([W25Q80DV][1]) that I want to use with the Arduino.
This memory has 4096 pages of 256 bytes each.

I want to make multiple writes per page to use memory evenly and erase less.

Test code:

    #include <SPI.h>

    #define readStatusReg_1 0x05
    #define readArrayReg 0x0B
    #define writeEnableReg 0x06
    #define pageProgramStatusReg 0x02

    #define FLASH_SELECT_CHIP 33

    // # Select / Unselect chip
    void selectChip(bool state) {
      switch (state) {
        case true:
         digitalWrite(FLASH_SELECT_CHIP, HIGH);
         digitalWrite(FLASH_SELECT_CHIP, LOW);
          break;
        case false:
         digitalWrite(FLASH_SELECT_CHIP, HIGH);
          break;
      }
    }

    // # Wait flash ready state
    void notBusy() {
      uint16_t whileCounter;
      selectChip(true);
      SPI.transfer(readStatusReg_1);
      while((SPI.transfer(0) & 1) && whileCounter < 45000) { whileCounter++; }
      selectChip(false);
    }

    // # Send command and address
    void sendCommandAndAddress(const byte command, const unsigned long address) {
      SPI.transfer(command);
      SPI.transfer((address >> 16) & 0xFF);
      SPI.transfer((address >> 8) & 0xFF);
      SPI.transfer(address & 0xFF);
    }

    // # Write enable
    void writeEnable() {
      notBusy();
      selectChip(true);
      SPI.transfer(writeEnableReg);
      selectChip(false);
    }

    // # Write FLASH page
    bool writeFlashData(const unsigned long address, byte * data) {
      writeEnable();
      selectChip(true);
      sendCommandAndAddress(pageProgramStatusReg, address);
      uint16_t len = sizeof(data);
      for(uint16_t i = 0; i < len; i++) {
        SPI.transfer(*data++);
      }
      selectChip(false);
      notBusy();
      return true;
    }

    void setup() {
      // SPI
      pinMode(FLASH_SELECT_CHIP, OUTPUT);
      digitalWrite(FLASH_SELECT_CHIP, HIGH);
      SPI.begin();
      SPI.setDataMode(0);
      SPI.setBitOrder(MSBFIRST);

      // Write FLASH
      #define TESTADDRESS 0x1000
      byte msgData[] = "Hi all!";
      writeFlashData(TESTADDRESS, msgData);
    }

    void loop() {}

Here, the address **#define TESTADDRESS 0x1000** (4096) is specified for writing data.

I'm not clear if this is the page address or the byte address from which I will start recording?

I would like to actually split one page into multiple blocks and write data for them separately.

  [1]: https://www.winbond.com/resource-files/w25q80dv_revg_07212015.pdf

title: How are locations in FLASH memory addressed?

Answers: 1

body:
> I'm not clear if this is the page address or the byte address from which I will start recording?

That is the byte address.  As the data sheet in section 8.5.13 says:

> If an entire 256 byte page is to be programmed, the last address byte (the 8 least significant address bits) should be set to 0. If the last address byte is not zero, and the number of clocks exceed the remaining page length, the addressing will wrap to the beginning of the page.

In other words: if you want to write an entire page then start at the beginning of the page. If you don't and you write more than there is room left in the page you will wrap round back to the beginning of the page again.

So if you write two bytes starting with address 0x10FF you will actually write one at 0x10FF and the second at 0x1000, not 0x1100, since you wrap at the page boundary.


body:
Any help would be greatly appreciated!
```
/*
   Jebediah's Launch Control System for Kerbal Space Program
   Alpha Build 2.00
   An Open-Source Project by John Seong
*/

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

const byte ROWS = 4;
const byte COLS = 3;

const int buzzer = A3;

const int ledAbort = 5;
const int ledStage = A5;

const int buttonAbort = 4;
const int buttonStage = A4;

int ledAbortState = LOW;
int ledStageState = LOW;

char keys[ROWS][COLS] = {
  {'1', '2', '3'},
  {'4', '5', '6'},
  {'7', '8', '9'},
  {'*', '0', '#'}
};

byte rowPins[ROWS] = {12, 11, 10, 9};
byte colPins[COLS] = {8, 7, 6};

Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS);

LiquidCrystal_I2C lcd(0x3F, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);

unsigned long previousMillis = 0;

const long interval = 1000;

// Show a two-line message on the LCD.
void lcdShow(const char *line0, const char *line1) {
  lcd.clear();
  lcd.print(line0);
  lcd.setCursor(0, 1);
  lcd.print(line1);
}

void lcdShowResult(float result) {
  lcd.print(result);
}

void setup() {
  pinMode(buzzer, OUTPUT);

  pinMode(ledAbort, OUTPUT);
  pinMode(ledStage, OUTPUT);

  pinMode(buttonAbort, INPUT_PULLUP);
  pinMode(buttonStage, INPUT_PULLUP);

  pinMode(buzzer, OUTPUT);
  Serial.begin(9600);
  lcd.begin(16, 2);
  lcdShow("  JEB'S LAUNCH", " CONTROL SYSTEM");
  delay(3000);
  lcdShow("ALPHA BUILD 2.00", " STUDIO HORIZON");
  delay(3000);
  lcdShow("WELCOME, KERMAN.", "PRESS ANY KEY...");
  while (!keypad.getKey()) ;  // wait for key press
}

void loop() {
  static enum {START, MENU, SET_COUNT, COUNT_DOWN, LAUNCH, SET_THRUST, SET_WEIGHT, TWR_COMPUTE} state = START;
  static uint32_t last_second;  // millis() value on last full second
  static int count;
  static float thrust, weight, ratio;

  char key = keypad.getKey();

  switch (state) {
    case START:  // transitional state
      lcdShow("1. LAUNCH SEQ", "2. TWR CALC");
      state = MENU;
    /* fallthrough */

    case MENU:
      if (key == '1') {  // Countdown
        lcdShow("COUNTDOWN TIMER", "SECONDS: ");
        count = 0;
        state = SET_COUNT;
      } else if (key == '2') {  // TWR
        lcdShow("TWR CALCULATOR", "THRUST: ");
        thrust = 0, weight = 0, ratio = 0;
        state = SET_THRUST;
      }
      break;

    case SET_COUNT:
      if (key >= '0' && key <= '9' && count <= 99) {
        lcd.print(key);
        count = 10 * count + (key - '0');
      } else if (key == '#') {
        lcdShow("    T-MINUS", "     SECONDS");
        // Force a refresh on entering COUNT_DOWN:
        last_second = millis() - 1000;
        count++;
        state = COUNT_DOWN;
      } else if (key == '*') {
        state = START;
      }
      break;

    case COUNT_DOWN:
      if (millis() - last_second >= 1000) {
        last_second += 1000;
        count--;
        if (count <= 10) {
          tone(buzzer, 500);
          delay(500);
          noTone(buzzer);
        }
        if (count == 0) {
          Serial.println("Lift off!");
        } else if (count < 0) {
          state = LAUNCH;
          break;
        }
        lcd.setCursor(1, 1);
        lcd.print(count < 10 ? "  " : count < 100 ? " " : ""); // pad
        lcd.print(count);
      } else if (key == '*') {
        state = START;
      }
      break;

    case LAUNCH:
      tone(buzzer, 3000);

      int stageConfirm = digitalRead(buttonStage);
      int abortConfirm = digitalRead(buttonAbort);

      unsigned long currentMillis = millis;

      if (currentMillis - previousMillis >= interval) {
        previousMillis = currentMillis;

        if (ledAbortState == LOW) {
          ledAbortState = HIGH;
          lcdShow(" T-ZERO WARNING", "CONFIRM IGNITION");
        } else if (ledAbortState == HIGH) {
          ledAbortState = LOW;
          lcd.clear();
        }

        if (ledStageState == LOW) {
          ledAbortState = HIGH;
        } else if (ledAbortState == HIGH) {
          ledAbortState = LOW;
        }
        digitalWrite(ledAbort, ledAbortState);
        digitalWrite(ledStage, ledStageState);
      }
      break;

    case SET_THRUST:
      if (key >= '0' && key <= '9' && thrust <= 9999) {
        lcd.print(key);
        thrust = 10 * thrust + (key - '0');
      } else if (key == '#') {
        lcdShow("TWR CALCULATOR", "WEIGHT: ");
        state = SET_WEIGHT;
      } else if (key == '*') {
        state = START;
      }
      break;

    case SET_WEIGHT:
      if (key >= '0' && key <= '9' && weight <= 9999) {
        lcd.print(key);
        weight = 10 * weight + (key - '0');
      } else if (key == '#') {
        lcdShow("THRUST-TO-WEIGHT", "RATIO: ");
        if (thrust != 0 || weight != 0) {
          ratio = thrust / weight;
          lcdShowResult(ratio);
        }
      } else if (key == '*') {
        state = START;
      }
      break;
  }
}
```

title: Arduino Micro: Followed the BlinkWithoutDelay instructions, but somehow it's not working in my code

Answers: 0


body:
I am counting rotations of a shaft and timing events that occur during that rotation.  I wish to display
the event timing as a percentage of ~1/4 of the rotation timing.  This would involve recording the rotation time, dividing that number by 3.6 and dividing that number by the value of the event timer, then displaying that percentage on an LCD array.

title: Can it time between blips, store the time between blips, subtract one time from the other and divide one time by another and display it?

Answers: 1

body:
What you are looking for is the millis() function.
It returns the time that passed in milliseconds since the board power up.

With this function you can find the time delta, and achieve all the described calculations.

[For more information][1]

  [1]: https://www.arduino.cc/reference/en/language/functions/time/millis/


body:
I have a project and i need to convert string (contain numbers and letters) to array

    String name = "s111, s222, bbbb,cccc ";
and i want

    array[0] = s111;
    array[1] = s222;
    array[2] = bbbb;
    array[3] = cccc;

here is the code :

     String name = "s111, s222, bbbb,cccc ";
     int array[50];
     int r=0,t=0;

     for(int i=0;i<name.length();i++){
          if(name.charAt(i) == ','){
              array[t] = name.substring(r,i);
              r = (i+1);
              t++;
             }
     for(int k=0 ;k<=t ;k++){
       Serial.println(array[k]);
      }

When I compile I get just zeros like :

    array[0] = 0;
    array[1] = 0;
    array[2] = 0;
    array[3] = 0;

title: Convert string to array

Answers: 1

body:
When you declare `int array[50];` you declare an array of numbers so only numbers can be stored inside it. If you really want an array of strings then declare an array of strings like `String array[50];` There was also a a problem that sometime you split the `name` by comma, sometime by space, and sometime by comma+space. Also your code was missing closing bracket.

The algorithm has to split both by comma and my space and then take only values that have length more than one to avoid inserting empty strings.

```c++
String name = "s111, s222, bbbb,cccc ";
String array[50];
int r=0,t=0;

for(int i=0;i<name.length();i++)
{
  if(name[i] == ' ' || name[i] == ',')
  {
    if (i-r > 1)
    {
      array[t] = name.substring(r,i);
      t++;
    }
    r = (i+1);
  }
}

for(int k=0 ;k<=t ;k++)
{
  Serial.println(array[k]);
}
```


body:
[![enter image description here][1]][1][![IC Component][2]][2]

What is the using purpose of this chip?

  [1]: https://i.stack.imgur.com/r8b0o.jpg
  [2]: https://i.stack.imgur.com/GFFvu.png

title: What is the name of this chip on Arduino Mega ? I am not finding its datasheet 56 TI MSP?

Answers: 1

body:
There is only one 8-pin SMD IC on the top side of the [Arduino Mega 2560](https://store.arduino.cc/arduino-mega-2560-rev3).

[![Arduino Mega 2560][1]][1]

From the [schematic](https://content.arduino.cc/assets/MEGA2560_Rev3e_sch.pdf)
 it appears to be the "LMV358IDGKR" a TI dual op-amp used for two separate functions on the Mega.

- Selecting power source - VIN vs USB.
- Illuminating the built-in "L" LED (on D13) without loading PB7

  [1]: https://i.stack.imgur.com/y7MS6.jpg


body:
This is not a question for beginners.

I am implementing a functional interface to an asynchronous serial device connected to the Serial1 port on a mega.

To ensure clarity, I want to implement a series of functions thus:

```
    {param} CallInterface({param1},{param2},...) {
        sendRequestPacket();
        ....{await Response or timeout}....
        return Response;
     }
```

Obviously, when "awaiting Response" we are blocking the operational thread and have to allow an additional thread processor access in order to retrieve and parse the response.

On a multithreaded platform, this would be trivial to implement using semaphores and other multi-threading techniques, but on Arduino,AVR the solution is possibly less obvious, or not.

So, the question is, what is the best and most effective way to implement a pattern such as this on the Arduino platform?

title: What are the correct techniques for implementing functional client access to an asynchronous serial interface?

Answers: 1

body:
The typical way I handle this kind of thing is to have one "master" function that controls everything using a finite state machine in a non-blocking way.

That function *could* contain all the logic to do things, or it could be simpler and just handle the basic communication and then pass details on to a callback function that is specified in the action function call.

So the flow could be:

1. You call a function that just sets up things:
  * It stores details of the request to be made
  * It records the address of a "callback" function
2. You execute your "run" function repeatedly from `loop()`
  * It sends the command to the target
  * It receives and parses the response storing it internally somewhere
  * When the response is complete it executes the callback function passing it the response

Not all of 2 would happen each iteration of `loop()`, so write it in a non-blocking way (using `.available()` etc) and only call the callback when everything is complete.

So in that way you can set up a chain of things to happen:

1. You submit request 1 with callback A.
2. Callback A submits request 2 with callback B.
3. Callback B submits request 3 with callback C.

... etc ...

As an example this is how a modem control could look:

```
Modem.command("AT+CREG?", testRegistration);
>>> send         AT+CREG?
<<< store        +CREG: 0,2
<<< store
<<< identify     OK
--- Execute testRegistration(true, "+CREG: 0,2\n\n");
```

Or maybe if it goes wrong:

```
Modem.command("AT+CROG?", testRegistration); // Oops, made a typo...
>>> send         AT+CROG?
<<< identify     ERR
--- Execute testRegistration(false, "");
```


body:
I can't get to work a circuit that doesn't look that hard to copy.

This circuit was done for an Arduino extension of my DSC HS2032 system. I was trying the example "Status" on the Arduino's library DSC Keybus Interface v1.2.0.

On the example, we can see this circuit:

     *      DSC Aux(+) --- Arduino Vin pin
     *
     *      DSC Aux(-) --- Arduino Ground
     *
     *                                         +--- dscClockPin (Arduino Uno: 2,3)
     *      DSC Yellow --- 15k ohm resistor ---|
     *                                         +--- 10k ohm resistor --- Ground
     *
     *                                         +--- dscReadPin (Arduino Uno: 2-12)
     *      DSC Green ---- 15k ohm resistor ---|
     *                                         +--- 10k ohm resistor --- Ground

Here on the photos, I'm showing what I have done.

[![enter image description here][1]][1]

[![DSC Panel wired][2]][2]

This is the HS2032 panel where (on the YEL and GRN) I connect the Arduino. I changed the Arduino's power source to be from my laptop so I could easily test it on the Serial Monitor. YEL->White/Green wire and GRN->Green wire

Now goes the Arduino's wiring.

[![Arduino wired][3]][3]

Remember from the panel, the yellow is the white/green and the green is the green (they are coming from the right). First, each of both wires goes directly to 15kOhm resistor. Secondly, it splits between a 10kOhm resistor which then ends up into Arduino's ground, or it goes directly to the Arduino's pin 3 or 5, depending on the cable.

**Results**

The Serial Monitor shows "DSC Keybus Interface is online" and over.

If I connect green and white directly to 3 and 5, it will say sometimes "Keybus disconnected" and "Keybus connected" without any additional messages ever.

So my question is, am I missing something here? Why is the Serial Monitor not responding or what can I do to check where is the problem?

**EDIT**

This are the serial monitor readings, nothing from the Panel. I had to connect without resistances to get this output, otherwise, the only output would be "DSC Keybus Interface is online."

    08:26:32.359 ->
    08:26:32.359 -> DSC Keybus Interface is online.
    08:26:35.345 -> Keybus disconnected
    08:26:42.722 -> Keybus connected
    08:26:47.838 -> Keybus disconnected
    08:26:51.131 -> Keybus connected
    08:26:54.937 -> Keybus disconnected
    08:27:12.661 -> Keybus connected
    08:27:17.122 -> Keybus disconnected
    08:27:34.218 -> Keybus connected
    08:27:41.697 -> Keybus disconnected
    08:28:19.509 -> Keybus connected
    08:28:22.487 -> Keybus disconnected
    08:28:25.068 -> Keybus connected
    08:28:28.053 -> Keybus disconnected
    08:29:23.692 -> Keybus disconnected
    08:29:31.175 -> Keybus disconnected
    08:29:33.990 -> Keybus connected
    08:29:37.005 -> Keybus disconnected

  [1]: https://i.stack.imgur.com/NSyln.jpg
  [2]: https://i.stack.imgur.com/j2Bk1.jpg
  [3]: https://i.stack.imgur.com/aExNH.jpg

title: Is this circuit properly made?

Answers: 1

body:
> **Is this circuit properly made?**

No.

A lot of the problem is that you don't have a well-drawn schematic. I think that what you have is a couple of voltage dividers to interface a 5V arduino with a higher voltage device. I suspect a voltage divider isn't the best solution but presumably it works for someone else. So what you need is ...

<!-- Begin schematic: In order to preserve an editable schematic, please
     don't edit this section directly.
     Click the "edit" link below the image in the preview instead. -->

![schematic](https://i.stack.imgur.com/FTdlb.png)

<!-- End schematic -->

If I were you I'd pull your existing wiring apart completely and start again, arranging the components and wires so that they match this schematic as closely as possible in terms of position and orientation. Then trace the connections through carefully to make sure everything matches.


body:
Hi I bought some atmega328 chips (not to be confused with atmega328p). They are very similar but the atmega328p chips are just more power efficient, so I've read. Anyways, my goal is to burn the arduino bootloader onto these chips so that I can make some breadboard arduinos. I used the arduino ISP sketch and hooked up everything like so ->

[![enter image description here][1]][1]

  [1]: https://i.stack.imgur.com/fP9Ra.png

I was following instructions from the following link ->

https://www.arduino.cc/en/Tutorial/ArduinoToBreadboard

However, when I press the Burn Bootloader button under Tools, it keeps telling me that it can't verify that my chip is an atmega328p. Well it is not atmega328p but everywhere online says it does not matter since they are the same architecture. The error also tells me that I can override by typing -F, but it doesn't tell me where to input this. I'm pretty sure that may fix the issue, but I am not sure where I'm supposed to put the -F.

Also I saw another post that was similar to this one but the answer said that the problem is the atmega328 chip itself. Is it even possible to add the bootloader to these chips??? Other sources said it is, but I can't seem to do it.

title: How can I burn the bootloader onto atmega328 (not atmega328p)?

Answers: 1

body:
> **How can I burn the bootloader onto ATmega328 (not ATmega328*P*)?**

As Juarj commented, For a variety of standalone AVR microcontrollers you can add new "cores" to the Arduino IDE using it's board manager.

This provides the Arduino IDE with information about your specific chip and this means the IDE can instruct the `avrdude` program appropriately and select a bootloader image that was written to support your specific chip

The [Minicore documentation](https://github.com/MCUdude/MiniCore#supported-microcontrollers) says it supports all variants of ATmega328

Other well-known examples of cores for bare AVR microcontroller chips  include [ATtinycore](https://github.com/SpenceKonde/ATTinyCore) which supports a wide range of ATtiny microcontroller chips like the popular ATtiny85.


body:
As I been learning Arduino (micro controllers, c++, etc) I have learned that memory is very limited. I already understand how memory works when it comes to variables. But I do not understand how memory works when it comes to functions. Since I am a backed developer I try to stay away from interrupts and instead use callback functions. Another reason why I prefer to use callback functions is because I love the visual studio IDE. I create my core functionality of whatever project I am building on a c++ project targeted for Windows. Once my algorithms/logic works the way I want it I reference those libraries on Arduino.

Anyways I am using lambdas to pass functions to my helper libraries. That way I do not use the delay function to wait for a response and I am always listening for events. **Basically my question is if it is correct to have code like this (function SendEvent):**

    /* MyRadioLibrary.h */
    // I am not including all the code of `MyRadioLibrary` because that makes it hard to
    // understand what I am asking. Instead I will try to use a lot of pseudo-code. Let me
    // know if you want me to post the code as an edit.

    class MyRadioLibrary
    {

    public:

        static void SendEvent(int typeOfEvent, void(*onEventCompleted)(bool x))
     {
      // I have an array of pointers to functions
            void(*onEventCompletedBuffer[10])(bool x);

            // I enqueue that event with a queue helper class

            // Send event ....

            // DO NOW WAIT FOR RESPONSE SINCE CALL BACK IS ALREADY SAVED
     }

        static void loop() {

             // listen for radio messages
             if(radio.available()){
                    // get response
                    // dequeue pointer to call back
                    // execute call back
              }

        }
    };

And my arduino sketch contains this code:

    #include <MyRadioLibrary.h>

    void setup()  {
        // setup pins etc..
    }

    void loop()
    {

        if (isButton1Pressed())
     {
      MyRadioLibrary::SendEvent(1, [](bool didEventCompletedSuccessfully) {

       if (didEventCompletedSuccessfully)
       {
        // turn on green LED
       }
       else {

        // turn on red led
       }

      });
     }
        else if (isButton2Pressed())
     {
      MyRadioLibrary::SendEvent(2, [](bool didEventCompletedSuccessfully) {

                 // call back function

      });
     }

        MyRadioLibrary::loop(); // listen for response events. When we get one fire call back.
    }

Now the question
------

When I call the `SendEvent` function I am passing 2 things (1) an integer and (2) a pointer to a function that is the call back. The integer (1) is passed as value and that will be part of the stack of the `SendEvent` function. The pointer (2) will be stored on an array of pointers. **But what about the lambda function?** where will that be stored? Instead of using a lambda function should I declare those functions in global scope and pass the global function instead of a lambda? **Will I run the risk of the pointer (2) pointing to a function that no longer exists if I use this way of coding?**

title: Use callbacks in Arduino with pointers to functions (will functions persist in memory?)

Answers: 1

body:
Your functions won't cease to exist. All of the code in your compiled and linked code image gets loaded into code-memory (Flash) and it stays there throughout the run, through resets, and through power-cycles, until another image is loaded over it.

Are you confusing pointers to functions with pointers to a function's local variables which occupy RAM memory, specifically within the function's stack-frame which *is* transient, being created and "destroyed" as the function gets called and returns - and successive stack-frames won't necessarily be created in the same place.


body:
i recently started using Arduino uno , but to my despair , the ground pin , without which i cant do any project (or can i ) , so i thought of a possible solution , what if i could program the board to make a pin act as a ground , so what to do
straight 2 questions , what to do to convert any pin into ground
or can i ignore using the provided ground pin .
i have already tried fixing the pin but it cant be fixed because a detached pin has got stuck into it

title: can i convert a pin into ground

Answers: 1

body:
> **Can I convert any pin into ground**

Any of the digital outputs can be set LOW but there is a limit on how much current they can sink,

This makes this approach unsuitable for most use cases other than charlieplexing LEDs and similar low-current applications.

It would be better to

- use any of the other ground connections.
  - two between `Vin` and `5V`
  - one between `Aref` and `13`
  - one on the 2x3-pin `ICSP` header for the 328
  - one on the unlabelled 2x3-pin ICSP header for the 16U2
  - one in the power jack
- replace the damaged header using solder-wick and a soldering-iron.
- solder a wire from a suitable ground pad on the PCB
  - e.g. from the ground pad for the 2.1mm power connector.

---

The ATmega328P data sheet says

> Although each I/O port can sink more than the test conditions (20mA at VCC = 5V, 10mA at VCC = 3V) under steady
state conditions (non-transient), the following must be observed:
> ATmega328P:
1] The sum of all IOL, for ports C0 - C5, should not exceed 100mA.
2] The sum of all IOL, for ports B0 - B5, D5 - D7, XTAL1, XTAL2 should not exceed 100mA.
3] The sum of all IOL, for ports D0 - D4, should not exceed 100mA.
If IOL exceeds the test condition, VOL may exceed the related specification. Pins are not guaranteed to sink current greater than the listed test condition

So no more than 20mA from or into any single pin over a long time. And no more than a total of 100 mA from or into a group of pins.


body:
I want to print a single line including the variable "val" only once rather than looping or repeating of the same line and within it the val will change according to the reading. Is it possible? If so, how?

 ![enter image description here](https://i.stack.imgur.com/FQGjo.jpg)

```cpp
#define trigPin 5
#define echoPin 6

float distance(uint8_t T, uint8_t H);

void setup()
{
    pinMode(trigPin, OUTPUT);
    pinMode(echoPin, INPUT);
    Serial.begin(9600);
    Serial.print("The object is: ");
}

void loop()
{
    float val = distance(32, 68);
    Serial.print(val);
    Serial.println(" cm away");
    delay(500);
}
```

title: How do I serial print a constant single string and a changing variable within it?

Answers: 1

body:
> within it [the already printed line] the val will change according to
> the reading

This “within it” makes little sense. “Printing” is just sending bytes
through the serial port, and you don't choose where these bytes are
going: you just send them one at a time. The program you use as a
“serial port monitor” then displays those bytes in whatever manner it
sees fit. You cannot control from the Arduino where things get
displayed.

Or maybe you can...

If your monitor program can emulate an [old school terminal][term], then
it can understand special control sequences, including [escape codes][],
that instruct it to perform specific actions, such as moving the cursor
or erasing part of the screen. Suitable terminal emulators include
[screen][] on Linux and MacOS, and [Putty][] on Windows. You may find
something appropriate for your mobile platform. Notably, the Arduino
serial monitor is _not_ a terminal emulator, and doesn't interpret those
control sequences.

Assuming you are using a suitable terminal emulator, the simplest
solution to your problem is to just repeat the whole sentence “The
object is: xx.xx cm away” for every measurement, but do so by
overwriting the current line instead of moving to the next one. You thus
replace `Serial.println()` by `Serial.print()`, and precede each
sentence by a carriage return character (ASCII CR = `0x0d` = `'\r'`),
which is interpreted as the command “move the cursor to the start of the
line”:

```cpp
void loop() {
    float val = distance(32, 68);
    Serial.print("\rThe object is: ");  // note the '\r'
    Serial.print(val);
    Serial.print(" cm away");  // no println()
    delay(500);
}
```

There is a caveat here. If you overwrite a sentence (say “The object is:
10.07 cm away”) by a shorter one (“The object is: 9.92 cm away”, one
character less), the previous sentence will not be completely
overwritten, so you may end up with “awayy” showing on the display. This
can be overcome by ensuring a fixed-length formatting of the numbers
displayed, by padding with spaces, or by sending an “erase current line”
command to the terminal.

As a side note, what `Serial.println()` does is print what you
requested, followed by a CR character, and then a line feed character
(ASCII LF = `0x0a` = `'\n'`). The line feed is interpreted by the
terminal as the command “move the cursor to the next line, without
changing its horizontal position”.

If you find it annoying to repeatedly print “The object is:”, you can
instead use more advanced control sequences. For instance:

* “\<ESC\>[16G” means “move the cursor to column 16”
* “\<ESC\>[K” means “clear from the cursor to the end of the line”

where \<ESC\> is the escape character:

```cpp
void loop() {
    float val = distance(32, 68);
    Serial.print("\x1b[16G\x1b[K");  // "\x1b" is the escape character
    Serial.print(val);
    Serial.print(" cm away");
    delay(500);
}
```

[term]: https://en.wikipedia.org/wiki/Computer_terminal
[escape codes]: https://en.wikipedia.org/wiki/ANSI_escape_code
[screen]: https://www.gnu.org/software/screen/
[Putty]: https://www.putty.org/


body:
Well I am trying make an application with arduino leonardo and GSM Shield. There are conditions if, else if, else .. etc

      if (smsMetni.indexOf("DURUM") != -1) {
        Serial.println("SMS income");
        String temp= String(analogRead(LM35_pin) * 0.48828125);
        String temp2 = "Hava " + temp + " derece.";
        char tempSMS2[] = "";
        temp2.toCharArray(tempSMS2, 30);
        Serial.println(tempSMS2);
        Kapadokya.smsGonder(gonderilecekTelNumarasi, tempSMS2);
      }

After the last line "*Kapadokya.smsGonder(gonderilecekTelNumarasi, tempSMS2);*" program stopping I watching serial monitor there is no notification or error. just stopping.

If I change those lines and remove **String(analogRead(LM35_pin) * 0.48828125)** :

        String temp= String(analogRead(LM35_pin) * 0.48828125);
        String temp2 = "Hava " + temp + " derece.";

and just write like this, it works very well.

    String temp2 = "Hava  derece.";

maybe you think there is a problem with LM35, even if I change it **String(analogRead(LM35_pin) * 0.48828125);** with **String(30);**, it doesn't work again. after the last line it is not continue.

only one sollution I've found if add **delay(500)** after each line it works but my codes looks ugly with this. are there any solution.

title: String(int) function stopping the Arduino

Answers: 1

body:
You should avoid String on the Arduino. It will cause random crashes. However that's not your issue. Your issue is trying to copy the data into an array that is too small.

    char tempSMS2[] = "";

That creates a one byte array which contains just a `\0`. You then try and squeeze your String data into it and it of course overflows all over the rest of your variables and data.

A better solution is to work directly in char arrays. It is a little trickier though:

First convert your float to a string:

    char tempFloat[8];
    dtostrf(analogRead(LM35_pin) * 0.48828125, -7, 3, tempFloat);

Then build up your string:

    char tempSMS2[30];
    strcpy_P(tempSMS2, PSTR("Hava "));
    strcat(tempSMS2, tempFloat);
    strcat_P(tempSMS2, PSTR(" derece."));


body:
I'm working on a project where there is no external 5V voltage regulator available but only 6V. I can not power it through the power jack because via this way I do not have enough current and get thermal shutdown.

Can I power it via 6V over USB? at the moment I'm trying this out and it works but what are the long term risks I'm prone to?

title: Is it bad to power a arduino mega with 6V via USB?

Answers: 2

body:
The Absolute Maximum Operating Voltage of the ATMega2560 is 6.0V. The same applies to the ATMega8u2 that does the USB to Serial on the Arduino Mega board.

Recommended maximum voltage is 5.5V

So yes, you can run it at 6 Volts, but you are right on the edge, so **I wouldn't recommend it**.

Possible risks are a decreased lifespan of the Arduino, and there might be some stability issues.

If the application isn't safety critical, and you don't mind having to replace the board after it failed in, say, two year of operation, it could be an acceptable risk (if there are no easily available alternatives)

PS you might want to measure you power supply. It may say it's 6V but could give out 6.2V. The output voltage of some supplies also vary with the load that's across it.

body:
> **Is it bad to power a arduino mega with 6V via USB?**

Yes, the Arduino Mega is not designed to be powered that way and you are probably abusing the USB specifications. USB can supply higher voltages than 5V but only if it is properly negotiated with the device.

The [schematics (see Documentation tab)](https://store.arduino.cc/arduino-mega-2560-rev3) show a 5V regulator powered from the 2.1 mm Power-connector or from the "Vin" header pin. If the regulator specs say it can work from 6V, you should probably use that instead. However although the 1870_LD1117S50CTR seems to be a low-dropout (LDO) regulator, it has a dropout voltage of 1V. So I wouldn't power it from a 6V source - that seems equally marginal.

In short, I think you really need to find a more suitable power source.


body:
I am sorry to ask this question as I think it has more to do with my mediocre C++ programming skill than with the arduino.
I do have a project where I want to use an RTC DS2131. I started out by using all the separate examples of the modules I need and put them together. But the RTC give me a headache :-(

The example ran fine where it just output the date to the serial port. Somthing along this:

    Serial.print(RTC.getDay());
    Serial.print("-");
    Serial.print(RTC.getMonth());
Now I want these values in different variables because I want to save them on an SD card as well.

Thus I came up with this simple test program:

    #include <Wire.h>
    #include <RTC.h>

    static DS3231 RTC;

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

    void loop()
    {
    int yearNow;
    int monthNow, dateNow, hourNow, minuteNow, secondNow, weekNow;

    if (RTC.isRunning())
      {
        yearNow=RTC.getYear();
        monthNow =RTC.getMonth();
        dateNow=RTC.getDay();
        weekNow=RTC.getWeek();
        hourNow=RTC.getHours();
        minuteNow=RTC.getMinutes();
        secondNow=RTC.getSeconds();

        Serial.print("Weekday: ");
        Serial.print(weekNow);
        Serial.print('  Time:');
        // Finally the hour, minute, and second
        Serial.print(hourNow);
        Serial.print('-');
        Serial.print(minuteNow);
        Serial.print('-');
        Serial.print(secondNow);
        Serial.print(" ##  ");
        Serial.print("Date: ");
        Serial.print(yearNow);
        Serial.print('/');
        Serial.print(monthNow);
        Serial.print('/');
        Serial.println(dateNow);

      }
    }

Now I would expect this output:
Weekday: 4  Time:16-10-36 ##  Date: 2020/7/28

But this is what I get:
Weekday: 42591416-10-36 ##  Date: 2020/7/28

As a sidenote the variables in this sketch are declared as "int". After having looked into the header files of the library I tried uint8_t resp. uint16_t for the year.
But nothing changed.

I am sorry but I have no clue as what beginner mistake I am achieving this time?? :-(

Thanks for your help.

title: Weird RTC DS3231 Output only when saving the dates to variables

Answers: 1

body:
You used single quotes instead of double quotes. Single quotes are for single characters. Double quotes are for strings (or character arrays).

    Serial.print('  Time:');

should be

    Serial.print("  Time:");


body:
have a wierd bug behavior..
i have an ATX power supply witch powers an long WS2812B 5v strip witch is controlled by the https://www.aliexpress.com/item/4000766948879.html Esp 01 and the board...

NOW the bug happens only when i connect the data pin to the strip. The ESP wont start after i restart the ATX PSU. And if it does it just crashes after some time....

Here is the SPOOKY part: when i start the esp WITHOUT the pin connected and plug it in after it starts it will keeep working for days... but sometimes it just decides it will go bananas... W T F! any ideas why?????

i suspected voltage drops.. but nope. i tried a battery, a second adapter and a usb power... none helped. same behavior as soon you connect the strip and hit restart/update it goes bananas...

title: ESP01 wont boot when connected to the led strip

Answers: 0


body:
I am searched over the internet and found out a few similar questions, but non of them were helpfull, so I decided to open a new quetion.

I tried both SD and Adafruit_SSD1306 libraries and they both worked fine when they were separated - in different codes. The error came when I used them in one code.

In my programme I try to init SD card, write to it and then init dispaly (everything works fine). After that I do another write cycle into the SD, but I get an error in opening a file:

    error opening test.txt

In other words I cant write anything into the SD card after oled display is initialized (display works then without any problems).

Here is my code:

    #include <Wire.h>
    #include <Adafruit_GFX.h>
    #include <Adafruit_SSD1306.h>

    #include <SPI.h>
    #include <SD.h>

    #define SCREEN_WIDTH 128
    #define SCREEN_HEIGHT 32

    TwoWire Wire1(PB9, PB8);// Use STM32 I2C2
    Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire1, -1);

    const int chipSelect = PA15;

    void setup() {

        Serial1.begin(9600);
       if (!SD.begin(chipSelect)) {
        Serial1.println("Card failed, or not present");
        // don't do anything more:
        while (1);
      }
      Serial1.println("card initialized.");

     for (int i = 0; i < 10; i++)
      {
      File dataFile = SD.open("test.txt", FILE_WRITE);

      if (dataFile) {
        dataFile.println("Test");
        dataFile.close();

        Serial1.println("Test");
      }
      else {
        Serial1.println("error opening test.txt");
      }
    delay(30);
      }

      delay(2000);

     // SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally
     if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Address 0x3C for 128x32
        Serial1.println(F("SSD1306 allocation failed"));
      }

      delay(500);

      for (int i = 0; i < 10; i++)
      {
      File dataFile = SD.open("dat_test.txt", FILE_WRITE);

      if (dataFile) {
        dataFile.println("Test");
        dataFile.close();

        Serial1.println("Test");
      }
      else {
        Serial1.println("error opening test.txt");  //here is the error I get
      }
    delay(30);
      }
    }

    void loop() {
    }

Here is the output:

    card initialized.
    Test
    Test
    Test
    Test
    Test
    Test
    Test
    Test
    Test
    Test
    error opening test.txt
    error opening test.txt
    error opening test.txt
    error opening test.txt
    error opening test.txt
    error opening test.txt
    error opening test.txt
    error opening test.txt
    error opening test.txt
    error opening test.txt

I am using STM32F103CB.

title: Problem with using SD and Adafruit_SSD1306 libraries at the same time

Answers: 0


body:
I'm searching for a way to flash an esp8266 *programmatically*, i.e, without user interaction (and especially without Arduino IDE)?

Assuming I can put the program to be flashed on the SPIFFS filesystem, is there a way to flash the esp with that file?

title: Flash esp8266 from SPIFFS filesystem

Answers: 1

body:
Yes, it is (or at least WAS possible a few years ago) to have an ESP8266 self-program if you can get the file onto the file system, by using the `Update` core that is used by OTA and httpUpdate. This was a example program to do it, but I don't know if it still works. I would also suggest that you look at using LittleFS instead of SPIFFS as the latter has been depreciated.

    #include <ESP8266WiFi.h>
    #include <WiFiClient.h>
    #include <ESP8266WebServer.h>
    #include <FS.h>

    void setup() {
      Serial.begin(115200);
      Serial.println();

      SPIFFS.begin();
      Dir dir = SPIFFS.openDir("/");

      pinMode(BUILTIN_LED, OUTPUT);
      digitalWrite(BUILTIN_LED, LOW);

      File file = SPIFFS.open("/firmware-update.bin", "r");

      uint32_t maxSketchSpace = (ESP.getFreeSketchSpace() - 0x1000) & 0xFFFFF000;
      if (!Update.begin(maxSketchSpace, U_FLASH)) { //start with max available size
        Update.printError(Serial);
        Serial.println("ERROR");
      }

      while (file.available()) {
        uint8_t ibuffer[128];
        file.read((uint8_t *)ibuffer, 128);
        Serial.println((char *)ibuffer);
        Update.write(ibuffer, sizeof(ibuffer));
      }

      Serial.print(Update.end(true));
      digitalWrite(BUILTIN_LED, HIGH);
      file.close();
    }

    void loop() {
    }


body:
I recently designed a board for an LED project. I am using WS2812B as the LED, and an ATMEGA328P-AU as the microcontroller. I also am using an arduino nano as my ISP and using "flash with programmer". When I flashed the FastLED blink example (Code below) the LED lit up as white and stayed white when it was supposed to flash red. I tried various examples and they all had the same outcome, just white. Am I missing a crucial component in my circuit (aside from some decoupling capacitors)? Is it a software problem?

    #include <FastLED.h>

    #define NUM_LEDS 1
    #define DATA_PIN 5

    // Define the array of leds
    CRGB leds[NUM_LEDS];

    void setup() {
         FastLED.addLeds<WS2812B, DATA_PIN, GRB>(leds, NUM_LEDS);  // GRB ordering is typical
    }

    void loop() {
      // Turn the LED on, then pause
      leds[0] = CRGB::Red;
      FastLED.show();
      delay(500);
      // Now turn the LED off, then pause
      leds[0] = CRGB::Black;
      FastLED.show();
      delay(500);
    }
[![enter image description here][1]][1]

  [1]: https://i.stack.imgur.com/q9uNY.jpg

title: WS2812B are only white on custom board

Answers: 1

body:
The WS2812B chips are very sensitive to timing. They rely on pulses being just the right length for things to work.

It is common if the timing is off that you just end up with white.

Since you have a blank chip that you have never put a bootloader on the fuses will be set wrongly for your configuration. By default a chip comes configured for the internal 8MHz oscillator. That means that everything will be running at half the speed.

You need to set the fuses to use the 16MHz crystal so that it matches the `F_CPU` setting of 16000000 in the board configuration. Either that or use a board configuration that expects to run at 8MHz.


body:
I made a pool monitor with ORP + pH + temp sensor. I had everything working (apart from ORP sensor causing interference with pH sensor, but that is a different topic...) for the past couple days in a temporary enclosure. Today I moved the device into a new enclosure. After rewiring it stopped sending out the probe data via MQTT and I'm struggling figuring out why..

If I open the serial monitor for the NodeMCU I can see the data from the Arduino coming through -

```
{"ph":"11.44","orp":"-23411","temp":"-196.60"}
...
```

So, it would appear the serial link is working since I'm getting the data. When listening on my MQTT topic, I get a "hello world", so my MQTT and wifi connections appear to be okay. If I type something in the serial console, it DOES get picked up by the MQTT topic. It seems like there is something wrong with the loop sending out the data, but this is the same loop I had and same loop as other sketches? I've even tried a different sketch on the NodeMCU with no luck. I'm really having trouble understanding what went wrong here. Is there something incredibly obvious that I am just spacing out on here?

Arduino Host w/ probes

```
int id=99;
#include <SoftwareSerial.h>
#include "orp_grav.h"
#include <OneWire.h>
#include <DallasTemperature.h>

//ph configs
#define SensorPin 0            //pH meter Analog output to Arduino Analog Input 0
#define Offset -2.0            //deviation compensate
unsigned long int avgValue;     //Store the average value of the sensor feedback

//orp configs
Gravity_ORP ORP = Gravity_ORP(A1);
unsigned long int ORPavgValue;     //Store the average value of the sensor feedback

//TEMP CONFIGS, using 2.2k pull-up resistor
#define ONE_WIRE_BUS 5 // Data wire is plugged into digital pin 5 on the Arduino
OneWire oneWire(ONE_WIRE_BUS); // Setup a oneWire instance to communicate with any OneWire device
DallasTemperature sensors(&oneWire); // Pass oneWire reference to DallasTemperature library

//NodeMCU serial comm
SoftwareSerial sw(2, 3); // RX, TX

void setup() {
 Serial.begin(9600);
 Serial.println("Interfacfing arduino with nodemcu");
 sw.begin(9600);
 if(ORP.begin()){
    Serial.println("Loaded EEPROM");
  }
 sensors.begin();
}

void loop() {
  /////////////  PH LOOP /////////////
  int buf[10];                //buffer for read analog
  for(int i=0;i<10;i++)       //Get 10 sample value from the sensor for smooth the value
  {
    buf[i]=1024-analogRead(SensorPin);
    delay(10);
  }

  for(int i=0;i<9;i++)        //sort the analog from small to large
  {
    for(int j=i+1;j<10;j++)
    {
      if(buf[i]>buf[j])
      {
        int temp=buf[i];
        buf[i]=buf[j];
        buf[j]=temp;
      }
    }
  }
  avgValue=0;
  for(int i=2;i<8;i++)                      //take the average value of 6 center sample
    avgValue+=buf[i];

  float phValue=(float)avgValue*5.0/1024/6; //convert the analog into millivolt
  phValue=3.5*phValue+Offset;                      //convert the millivolt into pH value
////////////////////////////////////////////

  /////////// ORP LOOP ///////////
  int orpValue;
  int orp_buf[10];                //orp_buffer for read analog

  for(int i=0;i<10;i++)       //Get 10 sample value from the sensor for smooth the value
  {
    orp_buf[i]=(int)ORP.read_orp();
    delay(10);
  }

  for(int i=0;i<9;i++)        //sort the analog from small to large
  {
    for(int j=i+1;j<10;j++)
    {
      if(orp_buf[i]>orp_buf[j])
      {
        int temp=orp_buf[i];
        orp_buf[i]=orp_buf[j];
        orp_buf[j]=temp;
      }
    }
  }
  ORPavgValue=0;
  for(int i=2;i<8;i++)                      //take the average value of 6 center sample
    ORPavgValue+=orp_buf[i];
  orpValue = ORPavgValue/6;
 //////////////////////

 ///////////TEMP///////////
 sensors.requestTemperatures();
 float tempValue = (sensors.getTempCByIndex(0) * 9.0) / 5.0 + 32.0;
 //////////////////////

 //Console debug
 Serial.print(phValue);//offset
 Serial.print("\t");//
 Serial.print((orpValue));
 Serial.print("\t");//
 Serial.println((tempValue));

 sw.print("{");
 //
 sw.print("\"ph\":\"");
 sw.print(phValue);//offset
 sw.print("\",");

 sw.print("\"orp\":\"");
 sw.print(orpValue);//offset
 sw.print("\",");

 sw.print("\"temp\":\"");
 sw.print(tempValue);//offset
 //
 sw.print("\"}");
 delay(5000);
}
```

NodeMCU MQTT code
```
#include <ESP8266WiFi.h>
#include <PubSubClient.h>

// Update these with values suitable for your network.
const char* ssid = "SSID";
const char* password = "Password";
const char* mqtt_server = "192.168.1.208";
#define mqtt_port 1883
#define MQTT_USER "user"
#define MQTT_PASSWORD "password"
#define MQTT_SERIAL_PUBLISH_CH "hass/sensor/pool"

WiFiClient wifiClient;

PubSubClient client(wifiClient);

void setup_wifi() {
    delay(10);
    // We start by connecting to a WiFi network
    Serial.println();
    Serial.print("Connecting to ");
    Serial.println(ssid);
    WiFi.begin(ssid, password);
    while (WiFi.status() != WL_CONNECTED) {
      delay(500);
      Serial.print(".");
    }
    randomSeed(micros());
    Serial.println("");
    Serial.println("WiFi connected");
    Serial.println("IP address: ");
    Serial.println(WiFi.localIP());
}

void reconnect() {
  // Loop until we're reconnected
  while (!client.connected()) {
    Serial.print("Attempting MQTT connection...");
    client.publish("outTopic", "hello world");
    // Create a random client ID
    String clientId = "NodeMCUClient-";
    clientId += String(random(0xffff), HEX);
    // Attempt to connect
    if (client.connect(clientId.c_str(),MQTT_USER,MQTT_PASSWORD)) {
      Serial.println("connected");
      //Once connected, publish an announcement...
      client.publish("hass/sensor/pool", "hello world");
    } else {
      Serial.print("failed, rc=");
      Serial.print(client.state());
      Serial.println(" try again in 5 seconds");
      // Wait 5 seconds before retrying
      delay(5000);
    }
  }
}
void setup() {
  Serial.begin(9600);
  Serial.setTimeout(500);// Set time out for
  setup_wifi();
  client.setServer(mqtt_server, mqtt_port);
  reconnect();
}

void publishSerialData(char *serialData){
  if (!client.connected()) {
    reconnect();
  }
  client.publish(MQTT_SERIAL_PUBLISH_CH, serialData);
}
void loop() {
   client.loop();
   if (Serial.available() > 0) {
     char bfr[101];
     memset(bfr,0, 101);
     Serial.readBytesUntil( '\n',bfr,100);
     publishSerialData(bfr);
   }
 }

```

title: Arduino Uno + NodeMCU serial to MQTT

Answers: 0


body:
I am making a multi-file arduino project, but the compiler can't recognize a function.
I am using the arduino-cli version 0.10.0

This is the error I received

`undefined reference to pin_init()
collect2.exe: error: ld returned 1 exit status
Error during build: exit status 1`

This is the command:

    arduino-cli compile -b arduino:avr:uno C:\Users\Cioccarelli\Desktop\transmitterCopy\main

main.ino:

    #include "C:\Users\Cioccarelli\Desktop\transmitter\automation\automation.h"

    void setup() {
        pin_init();
    }

    void loop() {}

automation.h:

    #pragma once

    // This is where the components input pins are stored, they are put here by the add_pin function
    byte pinSetup[0];
    byte pinSetupSize = 0;

    // This function is called in the setup() and it initializes every pin listed in pinSetup[] as input
    void pin_init();

automation.cpp:

    #include "C:\Users\Cioccarelli\Desktop\transmitter\automation\automation.h"

    extern pinSetup;
    extern pinSetupSize;

    void pin_init() {
        for (int i = 0; i < pinSetupSize; i++)
            pinMode(i, INPUT);
    }

I think this issue might have to do with the fact that I don't completely understand file inclusion, but I haven't found anything useful in my research

[![On the left is the file setup][1]][1]

**Update**: today I rebuilt the project with different names and I cut everything which wasn't related to the problem, in hope to identify it.

new main:

    #include "C:\Arduino\transmitter\nightmare\nightmare.h"

    void setup() {
        pin_init();
    }

    void loop() {}

new automation.h (nightmare.h):

    #pragma once

    // This function is called in the setup() and it initializes every pin listed
    //in pinSetup[] as input
    void pin_init();

new automation.cpp (nightmare.cpp):

    #include "C:\Arduino\transmitter\nightmare\nightmare.h"

    void pin_init() {}

new file structure:

[![enter image description here][2]][2]

  [1]: https://i.stack.imgur.com/NTgR2.png
  [2]: https://i.stack.imgur.com/SH8OV.png

I also made a copy and made some changes so it could become a C++ file
(substituting the setup() with main() and replace every "byte" type with "int")

I then put it in Visual studio, it compiled perfectly.
The arduino IDE gives the same error

title: Function declared in another file not recognized (undefined reference to)

Answers: 2

body:
The compiler didn't have a problem; the linker did. That is, once your main function was compiled (correctly) to call pin_init(), the loader tried to put together all of the compiled modules and link up calls that were not satisfied locally - within the same file - to functions defined in another module. That is when this message got generated. No such function *definition* was found, despite the *declaration* of it in main.ino.

If you can compile this with the Arduino IDE, watch what it does: It will compile *each* of your source-code modules, one at a time. Then link *all* of your modules' compiled versions together to produce the .hex file (that will eventually get uploaded to the Arduino). You need to mimic that when you're compiling & loading from the command line.

Update:

> today I rebuilt the project with different names

Is your .cpp file in the same folder as your .ino file? Or in another folder, such as the folder containing your .h file? I suspect it's the latter. When I built your project it in the Arduino IDE, it succeeded when the .ino and the .h were in the same folder, failed exactly as you described when I moved the .cpp file to where the .h file is.

The solution goes back to what I suggested earlier; that no *definition* of pin_input() was found, as the .cpp file containing it wasn't seen by the IDE (or your command-line compiler) and therefore not compiled and linked. Each of your files needs to be compiled and all of them together need to be linked, for the external calls to be satisfied.

With the IDE, put your project's .ino and .cpp files in the same folder so the IDE will see and compile each of them and know what to files to link. The IDE won't give you much flexibility for locating your .cpp files.

With the command line compiler, you can put your files wherever you will, make a separate[1] compile only run for each of them, then make another run of the linker component[2] naming all of the compiled units (the IDE names them as <whatever>.d) and provide the path to your library folder(s).

[1] I'm not familiar with the command-line compiler's command-line syntax; maybe you're able to specify a number of compiles with one command.<br>
[2] Again, IDK whether you need invoke the linker with the same command but with a link-only option switch, or you'll need to invoke the linker yourself, on the command line.

body:
The Arduino IDE (and I guess arduino-cli behaves the same) will try to
link into your project every source file that lives _in the same
forlder_ as the main .ino file.

Try this: get rid of the “automation” and “main” subfolders, put
everything at the root of the project, and try to build again. If you
end up with too much stuff in the root, you may consider the possibility
of creating your own libraries, but that's for another day...


body:
I'm new to programming and hardware so be gentle.

I've used this tutorial [Arduino Ultra Mega Timers](https://www.instructables.com/id/Arduino-Ultra-Mega-Timers/) to create a time on/off circuit.

I'm attempting to connect some adafruit neopixel led strips to a 5v relay. I've been trying to read up on how exactly relays work and what wires would go from **GND**, **5V**, and **Dout** to **NO** and **NC** but I've hit a brick wall because all of the schematics I've found show light bulbs connecting to the relays. A detailed explanation of exactly how to connect the LED strip to the relay and why it works would be great as I am trying to learn!

title: Connecting a time on/off circuit and my adafruit neopixel light strip

Answers: 1

body:
You cannot find a tutorial for controlling neopixel strips with a relay, because that just does not make any sense. You don't need a relay to control the strip.

The Neopixels consist not only of the LEDs themselves, but also of one LED driver chip per LED (WS2811 and it's siblings). These driver chips control the LEDs based on the data, that you send through the data pin. Actually one Neopixel LED consists of 3 LEDs inside a single package, one LED each for the colors red, green and blue (so that you can create all the other colors with a combination of them). The driver chip controlls the brightness of all three colors.

Thus you only need to connect your 5V power source to the strip (5V and ground) - Be sure to connect the power lines directly to your power supply, so that the LED current does not flow through the Arduino (because that can fry your Arduino) - and the data In pin of the strip to a fitting digital pin of the Arduino. You can use the Adafruit Neopixel library or the FastLED library for controlling them.

To turn the strip on, you set the needed pixels to the wanted color and then call the show method of the library (which sends out the color data through the data pin). To turn the strip off, you simply clear all the pixels (the libraries have extra functions for that), which basically means setting all pixel to black (red, green and blue components all zero).

So forget about the relay and just use the strip directly. Also Adafruit has a very good [guide on how to use the Neopixels][1].

  [1]: https://learn.adafruit.com/adafruit-neopixel-uberguide/the-magic-of-neopixels


body:
I have a error.The error is showing as:

exit status 1
Error compiling for board Arduino Mega or Mega 2560.

The Code is:
```
#include <Wire.h>

#include <LCD.h>

#include <LiquidCrystal_I2C.h>

#include <SoftwareSerial.h>

LiquidCrystal_I2C lcd(0x27,2,1,0,4,5,6,7);

SoftwareSerial BT(10,11); //Tx and Rx pins for BT communication const int temp_sensor = 0; //pin A0 (temperature sensor) const int fan = 22; //pin D2 (fan) float temp; //temperature value

int threshold = 21; //temperature threshold

const int LDRsensor = 1; //pin A1 (lighting sensor)

const int LED1 = 6; //pin D6 (LED 1)

const int LED2 = 7; //pin D7 (LED 2)

const int LED3 = 8; //pin D8 (LED 3)

const int LED4 = 9; //pin D9 (LED 4)

int LDRvalue; //natural light value

const int WL_sensor = 15; //pin A15 (water level sensor)

const int Wpump = 13; //pin D13 (water pump)

float water_level; //water level value

const int mov_sensor = 3; //pin D3 (movement sensor)

const int LEDalrm = 4; //pin D4 (alarm LED)

const int buzzer = 5; //pin D5 (buzzer)

int mov_value; //movement value (true or false)

char state; //data sent from App

char mode; //mode selected according to "state" value char order; //order to actuators according to "state" value
void setup() //this function is only executed one time

{

lcd.begin (16,2);

lcd.setBacklightPin(3,POSITIVE);

lcd.setBacklight(HIGH);

lcd.setCursor(0,0);

lcd.print("TFG");

lcd.setCursor(0,1);

lcd.print("Anna Merino");

delay(4000);

lcd.clear();

pinMode(temp_sensor, INPUT); //temperature sensor Mode

pinMode(fan, OUTPUT) ; //fan Mode

pinMode(LDRsensor, INPUT); //lighting sensor Mode

pinMode(LED1, OUTPUT); //LED1 Mode

pinMode(LED2, OUTPUT); //LED2 Mode

pinMode(LED3, OUTPUT); //LED3 Mode

pinMode(LED4, OUTPUT); //LED4 Mode

pinMode(WL_sensor, INPUT) ; //water level sensor Mode

pinMode(Wpump, OUTPUT); //water pump Mode

pinMode(mov_sensor, INPUT); //movement sensor Mode

pinMode(LEDalrm, OUTPUT); //alarm LED Mode

pinMode(buzzer, OUTPUT); //buzzer Mode

BT.begin(9600); //set data rate in bits per second (baud) for data transmission }
void loop() //function loop – continuously executed

{

if(BT.available()>0)

{

state = BT.read(); //transfer data sent by App to a local variable

}

if (state == 'Y')

{

mode = 'A';

}

else

if (state == 'Z')

{

mode = 'R';

}

else

if (state == 'X')

{

mode = 'D';

}

if (mode == 'A')

{

automaticmode(); //execute automatic function

}

else

if (mode == 'R')

{

remotemode(); //execute remote function

}

else

if (mode == 'D')

{

alarmmode(); //execute alarm function

}

}
void alarmmode() // alarm function

{

water_level = analogRead(WL_sensor); //data of water level sensor transmission to a local variable

if (digitalRead(mov_sensor)) //evaluate movement captured {

digitalWrite(LEDalrm, HIGH);

digitalWrite(buzzer, HIGH);

}

else

{

digitalWrite(LEDalrm, LOW);

digitalWrite(buzzer, LOW);

}

if (water_level > 100) //water level control

{

digitalWrite(Wpump, HIGH);

}

else

{

digitalWrite(Wpump, LOW);

}

}
void automaticmode() // automatic function

{

LDRvalue = analogRead(LDRsensor); //data of natural light transmission to a local variable water_level = analogRead(WL_sensor); //data of water level sensor transmission to a local variable

temp = analogRead(temp_sensor); //data of temperature sensor transmission to a local variable temp = temp*0.4883; //adjustment of temperature value digitalWrite(LEDalrm, LOW);

digitalWrite(buzzer, LOW);

lcd.setCursor(0,0);

lcd.print("Temperature");

lcd.setCursor(0,1);

lcd.print(temp); //LCD display – shows temperature value

lcd.setCursor(7,1);

lcd.print("ºC");

if (water_level > 100) //water level control

{

digitalWrite(Wpump, HIGH);

}

else

{

digitalWrite(Wpump, LOW);

}

if ((LDRvalue < 1023) & (LDRvalue >= 822)) //light control {

digitalWrite(LED1, LOW);

digitalWrite(LED2, LOW);

digitalWrite(LED3, LOW);

digitalWrite(LED4, LOW);

}

else if ((LDRvalue < 821)& (LDRvalue >= 617))

{

digitalWrite(LED1, HIGH);

digitalWrite(LED2, LOW);

digitalWrite(LED3, LOW);
digitalWrite(LED4, LOW);

}

else if ((LDRvalue < 616)& (LDRvalue >= 412))

{

digitalWrite(LED1, HIGH);

digitalWrite(LED2, HIGH);

digitalWrite(LED3, LOW);

digitalWrite(LED4, LOW);

}

else if ((LDRvalue < 411)& (LDRvalue >= 206))

{

digitalWrite(LED1, HIGH);

digitalWrite(LED2, HIGH);

digitalWrite(LED3, HIGH);

digitalWrite(LED4, LOW);

}

else if (LDRvalue < 205)

{

digitalWrite(LED1, HIGH);

digitalWrite(LED2, HIGH);

digitalWrite(LED3, HIGH);

digitalWrite(LED4, HIGH);

}

if (temp >= threshold) //temperature control

{

digitalWrite(fan, HIGH);

}

else if (temp < threshold)

{

digitalWrite(fan, LOW);

}

}

void remotemode() // remote function

{

digitalWrite(LED1, LOW);

digitalWrite(LED2, LOW);

digitalWrite(LED3, LOW);

digitalWrite(LED4, LOW);

digitalWrite(fan, LOW);

digitalWrite(Wpump, LOW);

digitalWrite(LEDalrm, LOW);

digitalWrite(buzzer, LOW);

if(BT.available()>0)

{

state = BT.read(); //transfer data sent by App to a local variable

}

if (state == 'D') //actuators operation according to orders received {

digitalWrite(LED1, LOW);

}

else

if (state == 'C')

{

digitalWrite(LED1, HIGH);

}

else

if (state == 'F')

{

digitalWrite(LED2, LOW);

}

else

if (state == 'E')

{

digitalWrite(LED2, HIGH);

}

else

if (state == 'H')
{

digitalWrite(LED3, LOW);

}

else

if (state == 'G')

{

digitalWrite(LED3, HIGH);

}

else

if (state == 'J')

{

digitalWrite(LED4, LOW);

}

else

if (state == 'I')

{

digitalWrite(LED4, HIGH);

}

else

if (state == 'L')

{

digitalWrite(fan, LOW);

}

else

if (state == 'K')

{

digitalWrite(fan, HIGH);

}

else

if (state == 'N')

{

digitalWrite(Wpump, LOW);

}

else

if (state == 'M')

{

digitalWrite(Wpump, HIGH);

}
if (state == 'O')

{

digitalWrite(LED1, HIGH);

digitalWrite(LED2, HIGH);

digitalWrite(LED3, HIGH);

digitalWrite(LED4, HIGH);

}

else

if (state == 'P')

{

digitalWrite(LED1, LOW);

digitalWrite(LED2, LOW);

digitalWrite(LED3, LOW);

digitalWrite(LED4, LOW);

}

}
```

title: Compiling error at ATmega2560

Answers: 1

body:
The main issue with your code is the formatting. It seems that you have managed to 'comment out' some of the necessary `{` or `}` for some of the functions and/or if/else blocks, hence the failure to compile.

e.g.

```
BT.begin(9600); //set data rate in bits per second (baud) for data transmission }
```

The `}` at the end of that particular line is the closing brace for the `void setup()` function... but because it's after the `//` for the comment, the compiler won't see it, so it is effectively missing.

This code *should* now compile on your system... once all the missing `{` and `}` were un-commented.

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

LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7);
SoftwareSerial BT(10, 11); //Tx and Rx pins for BT communication const int temp_sensor = 0; //pin A0 (temperature sensor) const int fan = 22; //pin D2 (fan) float temp; //temperature value

int threshold = 21; //temperature threshold

const int LDRsensor = 1; //pin A1 (lighting sensor)
const int LED1 = 6; //pin D6 (LED 1)
const int LED2 = 7; //pin D7 (LED 2)
const int LED3 = 8; //pin D8 (LED 3)
const int LED4 = 9; //pin D9 (LED 4)
const int WL_sensor = 15; //pin A15 (water level sensor)
const int Wpump = 13; //pin D13 (water pump)
const int mov_sensor = 3; //pin D3 (movement sensor)
const int LEDalrm = 4; //pin D4 (alarm LED)
const int buzzer = 5; //pin D5 (buzzer)

int LDRvalue; //natural light value
float water_level; //water level value
int mov_value; //movement value (true or false)

char state; //data sent from App
char mode;   //mode selected according to "state" value char order; //order to actuators according to "state" value

void setup() //this function is only executed one time
{
    lcd.begin(16, 2);
    lcd.setBacklightPin(3, POSITIVE);
    lcd.setBacklight(HIGH);

    lcd.setCursor(0, 0);
    lcd.print("TFG");
    lcd.setCursor(0, 1);
    lcd.print("Anna Merino");

    delay(4000);

    lcd.clear();

    pinMode(temp_sensor, INPUT); //temperature sensor Mode
    pinMode(fan, OUTPUT); //fan Mode
    pinMode(LDRsensor, INPUT); //lighting sensor Mode
    pinMode(LED1, OUTPUT); //LED1 Mode
    pinMode(LED2, OUTPUT); //LED2 Mode
    pinMode(LED3, OUTPUT); //LED3 Mode
    pinMode(LED4, OUTPUT); //LED4 Mode
    pinMode(WL_sensor, INPUT); //water level sensor Mode
    pinMode(Wpump, OUTPUT); //water pump Mode
    pinMode(mov_sensor, INPUT); //movement sensor Mode
    pinMode(LEDalrm, OUTPUT); //alarm LED Mode
    pinMode(buzzer, OUTPUT); //buzzer Mode

    BT.begin(9600); //set data rate in bits per second (baud) for data transmission
}

void loop() //function loop – continuously executed
{
    if (BT.available() > 0)
    {
        state = BT.read(); //transfer data sent by App to a local variable
    }

    if (state == 'Y')
    {
        mode = 'A';
    }
    else if (state == 'Z')
    {
        mode = 'R';
    }
    else if (state == 'X')
    {
        mode = 'D';
    }

    if (mode == 'A')
    {
        automaticmode(); //execute automatic function
    }
    else if (mode == 'R')
    {
        remotemode(); //execute remote function
    }
    else if (mode == 'D')
    {
        alarmmode(); //execute alarm function
    }
}

void alarmmode() // alarm function
{
    water_level = analogRead(WL_sensor); //data of water level sensor transmission to a local variable

    if (digitalRead(mov_sensor)) //evaluate movement captured
    {
        digitalWrite(LEDalrm, HIGH);
        digitalWrite(buzzer, HIGH);
    }
    else
    {
        digitalWrite(LEDalrm, LOW);
        digitalWrite(buzzer, LOW);
    }
    if (water_level > 100) //water level control
    {
        digitalWrite(Wpump, HIGH);
    }
    else
    {
        digitalWrite(Wpump, LOW);
    }
}

void automaticmode() // automatic function
{
    LDRvalue = analogRead(LDRsensor); //data of natural light transmission to a local variable water_level = analogRead(WL_sensor); //data of water level sensor transmission to a local variable
    temp = analogRead(temp_sensor); //data of temperature sensor transmission to a local variable temp = temp*0.4883; //adjustment of temperature value digitalWrite(LEDalrm, LOW);

    digitalWrite(buzzer, LOW);

    lcd.setCursor(0, 0);
    lcd.print("Temperature");

    lcd.setCursor(0, 1);
    lcd.print(temp); //LCD display – shows temperature value

    lcd.setCursor(7, 1);
    lcd.print("ºC");

    if (water_level > 100) //water level control
    {
        digitalWrite(Wpump, HIGH);
    }
    else
    {
        digitalWrite(Wpump, LOW);
    }

    if ((LDRvalue < 1023) & (LDRvalue >= 822)) //light control
    {
        digitalWrite(LED1, LOW);
        digitalWrite(LED2, LOW);
        digitalWrite(LED3, LOW);
        digitalWrite(LED4, LOW);
    }
    else if ((LDRvalue < 821) & (LDRvalue >= 617))
    {
        digitalWrite(LED1, HIGH);
        digitalWrite(LED2, LOW);
        digitalWrite(LED3, LOW);
        digitalWrite(LED4, LOW);
    }
    else if ((LDRvalue < 616) & (LDRvalue >= 412))
    {
        digitalWrite(LED1, HIGH);
        digitalWrite(LED2, HIGH);
        digitalWrite(LED3, LOW);
        digitalWrite(LED4, LOW);
    }
    else if ((LDRvalue < 411) & (LDRvalue >= 206))
    {
        digitalWrite(LED1, HIGH);
        digitalWrite(LED2, HIGH);
        digitalWrite(LED3, HIGH);
        digitalWrite(LED4, LOW);
    }
    else if (LDRvalue < 205)
    {
        digitalWrite(LED1, HIGH);
        digitalWrite(LED2, HIGH);
        digitalWrite(LED3, HIGH);
        digitalWrite(LED4, HIGH);
    }

    if (temp >= threshold) //temperature control
    {
        digitalWrite(fan, HIGH);
    }
    else if (temp < threshold)
    {
        digitalWrite(fan, LOW);
    }
}

void remotemode() // remote function
{
    digitalWrite(LED1, LOW);
    digitalWrite(LED2, LOW);
    digitalWrite(LED3, LOW);
    digitalWrite(LED4, LOW);

    digitalWrite(fan, LOW);
    digitalWrite(Wpump, LOW);
    digitalWrite(LEDalrm, LOW);
    digitalWrite(buzzer, LOW);

    if (BT.available() > 0)
    {
        state = BT.read(); //transfer data sent by App to a local variable
    }

    if (state == 'D') //actuators operation according to orders received
    {
        digitalWrite(LED1, LOW);
    }
    else if (state == 'C')
    {
        digitalWrite(LED1, HIGH);
    }
    else if (state == 'F')
    {
        digitalWrite(LED2, LOW);
    }
    else if (state == 'E')
    {
        digitalWrite(LED2, HIGH);
    }
    else if (state == 'H')
    {
        digitalWrite(LED3, LOW);
    }
    else if (state == 'G')
    {
        digitalWrite(LED3, HIGH);
    }
    else if (state == 'J')
    {
        digitalWrite(LED4, LOW);
    }
    else if (state == 'I')
    {
        digitalWrite(LED4, HIGH);
    }
    else if (state == 'L')
    {
        digitalWrite(fan, LOW);
    }
    else if (state == 'K')
    {
        digitalWrite(fan, HIGH);
    }
    else if (state == 'N')
    {
        digitalWrite(Wpump, LOW);
    }
    else if (state == 'M')
    {
        digitalWrite(Wpump, HIGH);
    }

    if (state == 'O')
    {
        digitalWrite(LED1, HIGH);
        digitalWrite(LED2, HIGH);
        digitalWrite(LED3, HIGH);
        digitalWrite(LED4, HIGH);
    }
    else if (state == 'P')
    {
        digitalWrite(LED1, LOW);
        digitalWrite(LED2, LOW);
        digitalWrite(LED3, LOW);
        digitalWrite(LED4, LOW);
    }
}

```

In future, when posting a question, please also list *WHICH* libraries you are using. e.g. there is more than one `LiquidCrystal_I2C` library... and probably only one right one. Also, that will only be part of the error message. Give the entire message - as the end bit isn't of much use!


body: I want to send pushbutton status from the nrf24l01 module to the app named nrfConnect. I could only find libraries that allow me to send float values. How could I send String values to the app? Thank You!

title: Sending Strings from NRF24L01 to app

Answers: 1

body:
[nRF Connect](https://play.google.com/store/apps/details?id=no.nordicsemi.android.mcp) is for Bluetooth LE devices, the nRF24L01+ is really not a Bluetooth Low Energy transceiver.

The best the nRF24L01+ can do is make a few Bluetooth LE advertisements but that's very finicky. Here's a long description how: https://dmitry.gr/index.php?r=05.Projects&proj=15&proj=11. Bluetooth LE fakery


body:
EDIT: Alright I'm stupid, I had the 2012 library installed somehow, maybe when I downloaded it indirectly from another old tutorial site. Thanks a ton to Peter Freerick for pointing that out! It finally compiled now

So I'm currently doing a little project where I have an ATTiny85 controlling some (neopixel) RGB addressable LEDs, which is controlled over i2c from an Arduino UNO Master. The goal is to make an Attiny85 into an i2c slave that receives a simple command (such as a single digit int) and decide which premade LED display program to use.

I'm using ATTinyCore, TinyWireS, and Adafruit's tinyNeopixel library for the tiny, and programming it using an Arduino UNO as ISP.

My issue is this: The led code requires a delay to change the speed of the light show. But I see in the TinyWireS example [here][1] that I should be using tws_delay instead of the normal delay.

Various googling attempts have left me nowhere to learn how to use tws_delay, what it is, or how to even declare it. I get a declaration error when I try to use the delay with the TinyWireS library included.

I would like to find a resource for learning how to declare and use this delay. Thank you for reading this far

EDIT: I have now added my code and error below, you can find the tws_delay in void loop near the bottom

```
// NeoPixel Ring simple sketch (c) 2013 Shae Erisson
// released under the GPLv3 license to match the rest of the AdaFruit NeoPixel library

#if (F_CPU>7370000) //neopixel library required 7.37MHz minimum clock speed; this line is used to skip this sketch in internal testing. It is not needed in your sketches.
#include <tinyNeoPixel.h>
#include <TinyWireS.h>
// Which pin on the Arduino is connected to the NeoPixels?
#define PIN            3

// How many NeoPixels are attached to the Arduino?
#define NUMPIXELS      8

// When we setup the NeoPixel library, we tell it how many pixels, and which pin to use to send signals.
// Note that for older NeoPixel strips you might need to change the third parameter--see the strandtest
// example for more information on possible values.
tinyNeoPixel pixels = tinyNeoPixel(NUMPIXELS, PIN, NEO_RGB + NEO_KHZ800);

int delayval = 500; // delay for half a second

void setup() {

  pixels.begin(); // This initializes the NeoPixel library.
}

void loop() {

  // For a set of NeoPixels the first NeoPixel is 0, second is 1, all the way up to the count of pixels minus one.

  for(int i=0;i<NUMPIXELS;i++){

    // pixels.Color takes RGB values, from 0,0,0 up to 255,255,255
    pixels.setPixelColor(i, pixels.Color(0,150,0)); // Moderately bright green color.

    pixels.show(); // This sends the updated pixel color to the hardware.

    tws_delay(delayval); // Delay for a period of time (in milliseconds).

  }
}
#else //neopixel library required 7.37MHz minimum clock speed; these and following lines are used to skip this sketch in internal testing. It is not needed in your sketches.
#warning "Neopixel control requires F_CPU > 7.37MHz"
void setup() {}
void loop() {}
#endif
```

And the error:

```
C:\Users\Dean\AppData\Local\Temp\arduino_modified_sketch_145294\simple.ino: In function 'void loop()':

simple:36:5: error: 'tws_delay' was not declared in this scope

     tws_delay(delayval); // Delay for a period of time (in milliseconds).

     ^~~~~~~~~

C:\Users\Dean\AppData\Local\Temp\arduino_modified_sketch_145294\simple.ino:36:5: note: suggested alternative: 'delay'

     tws_delay(delayval); // Delay for a period of time (in milliseconds).

     ^~~~~~~~~

     delay

Multiple libraries were found for "tinyNeoPixel.h"
 Used: C:\Users\Dean\AppData\Local\Arduino15\packages\ATTinyCore\hardware\avr\1.3.2\libraries\tinyNeoPixel
Multiple libraries were found for "TinyWireS.h"
 Used: C:\Users\Dean\Documents\Arduino\libraries\TinyWireS
exit status 1
'tws_delay' was not declared in this scope
```

  [1]: https://github.com/rambo/TinyWire/blob/master/TinyWireS/examples/attiny85_i2c_slave_task/attiny85_i2c_slave_task.ino

title: What is "tws_delay" and how can I use it? (with an ATTiny85)

Answers: 2

body:
`tws_delay()` is a function provided by the TinyWireS library [here][1]. As you can see from the declaration - `void tws_delay(unsigned long);` - it accepts a parameter of `unsigned long`, just like `delay()` does.

In fact, the comment on the line above that declaration says...

```// Implement a delay loop that checks for the stop bit (basically direct copy of the stock arduino implementation from wiring.c)```

... so, it's safe to say that wherever you would have used `delay()`, you can use `tws_delay()`.

So there should be no need to declare or define it. But to simply use it. If using `tws_delay()` in code that includes `TinyWireS.h` doesn't work, I would be checking that you have a version of the library that declares/defines it. Which you should, given the example you linked, as that repo has had the function since 2012!

  [1]: https://github.com/rambo/TinyWire/blob/f9e0e5a5ffcb9b90691fb2214c7aa39e9cbcfd3e/TinyWireS/TinyWireS.h#L59

body: Answer: Make sure you install the right library :P


body:
 I am trying to make it so I can pull the time so that they open at 8 am and close at 10 pm. The loop is already set up to open and close the blinds completely.

    #include <CheapStepper.h>

    CheapStepper stepper;

    boolean moveClockwise = true;
    int motorPostion = 10;
    boolean up = true;
    boolean down = false;

    void setup() {
      Serial.begin (9600);
      Serial.println ("Ready to start moving");
    }

    void loop() {

        for (int i = 1; i < 16384; i++)
          {
          stepper.step (moveClockwise);
          Serial.println (i);
          int nStep = stepper.getStep();

          if (nStep@96==0) {
            Serial.println ("Moved full rotation Clockwise");
            }
         }

        for (int i = 16384; i > 0; i--)
          {
          stepper.step (!moveClockwise);
          Serial.println (i);
          int nStep = stepper.getStep();

          if (nStep@96==0) {
            Serial.println ("Moved full rotation Counter Clockwise");
          }
        }
      }

title: I am making my blinds automatic, but I don't want to use a delay

Answers: 0


body:
Here's what I want my code to do: This is part of a tea infusing project that would automate the steeping of tea, part of this is initially having a selection of either Black/Herbal tea or White/Green tea, this will then set off several other factors down the timeline.
I want my LCD screen to display and scroll "Please select a tea" while still being able to take in pushbutton input.

I've been doing this all day, and I've tried several things. I firstly tried using a normal delay function so my text could scroll properly, but the problem with that is that it halts all the code and doesn't allow for any other input, so I quickly found millis() was likely what I needed to use. However, when I try to apply it to this specific example, it just scrolls all my text extremely quickly through the LCD.
Perhaps I'm being stupid and ignoring something obvious, but please let me know.

```

#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd = LiquidCrystal_I2C(0x27, 16, 2);

const int black_herbal_osb = 2;

int black_select;

//Timing
unsigned long prev_millis;
unsigned long current_millis;
const unsigned long LCD_delay = 500;

void setup() {

  //Tea selection buttons
  pinMode(black_herbal_osb, INPUT);

  //LCD screen setup
  lcd.init();
  lcd.backlight();

}

void loop() {

  lcd.autoscroll();
  lcd.setCursor(16, 0);
  lcd.print("Please");

  current_millis = millis();

  black_select = digitalRead(black_herbal_osb);

  if (black_select != HIGH) {

    if (current_millis - prev_millis >= LCD_delay) {
      lcd.print(" select ");
      prev_millis = current_millis;
    }
    if (current_millis - prev_millis >= LCD_delay * 2) {
      lcd.print("a ");
      prev_millis = current_millis;
    }
    if (current_millis - prev_millis >= LCD_delay * 3) {
      lcd.print("tea ");
      prev_millis = current_millis;
    }
  }

  else if (black_select == HIGH) {
    lcd.clear();
    lcd.autoscroll();
    lcd.setCursor(16, 0);
    lcd.print("Black/Herbal ");
    delay(500);
    lcd.print("tea ");
    delay(500);
    lcd.print("selected");
    delay(2000);
    lcd.noAutoscroll();
    lcd.clear();
  }

}

title: How do I make my LCD screen scroll text while allowing for button input?

Answers: 2

body:
See [my answer to a similar question][1] - about motors but the idea is the same. You call a function for each piece of the job that needs to be done. The function itself decides whether it needs to be done yet, and if so, does it and returns, otherwise it just returns. The loop() function just calls all your other action functions and *does nothing else* -- all of the real work takes place in those functions.

Looking at your scrolling code, I think one function could print successive pieces of the message by remembering what did last. Another could read and debounce the button(s) and save its/their state.

And once you get to controlling the infusing process, one (or maybe more) functions could be used to control that.

  [1]: https://arduino.stackexchange.com/questions/60759/how-to-rotate-two-or-more-steppers-simultaneously-by-giving-array-of-angles/66380#66380

body:
I figured it out. I was thinking about it all wrong, I just needed to figure out how the scrolling worked for the LCD and the rest was much easier. Only current issue with my code is that on the initial scroll of "Please select a tea" right after the "Booting..." process, it doesn't seem to start at (16,0) but nearer to the front which makes it not super easy to read initially but it corrects itself after a single scroll.

Here's the code for those interested:

```
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd = LiquidCrystal_I2C(0x27, 16, 2);

const int black_herbal_pin = 2;
const int white_green_pin = 3;
const int LCD_scroll = 200;

int black_select;
int white_select;

unsigned long current_millis = 0;    // stores the value of millis() in each iteration of loop()
unsigned long previous_scroll_millis = 0;

void setup() {
  Serial.begin(9600);
  //Tea selection buttons
  pinMode(black_herbal_pin, INPUT);
  pinMode(white_green_pin, INPUT);

  //LCD screen setup
  lcd.init();
  lcd.backlight();

}

void loop() {

  if (current_millis == 0) {
    lcd.setCursor (0, 0);
    lcd.print("Booting");
    delay(500);
    lcd.print(".");
    delay(500);
    lcd.print(".");
    delay(500);
    lcd.print(".");
    delay(1000);
    lcd.clear();
  }

  lcd.setCursor(16, 0);
  lcd.print("Please select a tea ");

  current_millis = millis();
  for (int position_counter = 0; position_counter < 16; position_counter++) {

    if (current_millis - previous_scroll_millis >= LCD_scroll) {
      lcd.scrollDisplayLeft();

      previous_scroll_millis += LCD_scroll;
    }
  }

  if (digitalRead(black_herbal_pin) == HIGH) {
    lcd.clear();
    lcd.setCursor (16, 0);
    lcd.print("Black/Herbal tea selecte");
    for (int position_counter = 0; position_counter < 26; position_counter++) {
      lcd.setCursor (0, 0); //This part is likely not necessary for you as it seems to be a bug within my own LCD
      lcd.print("d"); // without this it prints "d" on the second row
      lcd.scrollDisplayLeft();
      delay (150);
    }

    delay(2000);
    lcd.clear();
  }

  if (digitalRead(white_green_pin) == HIGH) {
    lcd.clear();
    lcd.setCursor (16, 0);
    lcd.print("White/Green tea selected");
    for (int position_counter = 0; position_counter < 26; position_counter++) {
      lcd.scrollDisplayLeft();
      delay (150);
    }

    delay(2000);
    lcd.clear();
  }

}