body:
I made a small box containing Arduino Pro Mini , DFPlayer Mini player and a 3.7V LiPo battery. Is it possible to power two devices with 3.7 V Battery?
What is the best way to save power for longer time performance?

title: How to power Arduino pro mini and DFPlayer mini togather with 3.7 V LiPo battery?

Answers: 1

body:
Use a buck/boost voltage regulator. Those are high efficiency switching regulators, and can either increase or decrease the input voltage. Feed the output of the regulator directly into the Arudino's 5V (or 3.3V) line, bypassing the on-board voltage regulator.

What input voltages do the 2 devices need? Both 5V? If so, you can use a single voltage regulator to power both devices. If one needs 3.3V and the other needs 5V you may have to have 2 different voltage regulators.

By using a switching regulator you can bypass the fairly inefficient linear regulator in your Arduino supply 3.3V or 5V to it directly (depending on the type of board you have.)

## Edit:

Ok, I looked it up and a DFPlayer Mini player appears to be a shield designed to plug directly into an Arduino. It looks like it can be powered from 3.2 to 5V, so you should be able to use it with either a 3.3V or 5V Arduino Pro Mini. Once you've decided if you're going to use a 3.3V or 5V Arduino, pick a buck/boost voltage regulator with the desired output voltage (or get an adjustable one and set it appropriately.)


body:
I'm trying to make a Python function in the [TCLab package][1] to flash firmware to an Arduino Leonardo (32u4). I can compile the [TCLab ino][2] (firmware) and deploy with the Arduino IDE or with the [Python avryp][3] package. The [Python avr_helpers][4] package looks like a possible solution but is only supported with the older Python 2.7. Forum posts [such as this one][5], https://arduino.stackexchange.com/questions/60599/how-can-i-upload-a-hex-file-to-an-arduino-uno, and others suggest `avrdude` to upload a hex file. However, I need a Python solution that can be used on any platform (MacOS, Windows, Linux, etc) without a requirement to install packages (avrdude, Arduino IDE, etc).

I have the [hex file][6] from a successful Arduino build. Here is an unsuccessful attempt to load the hex file with serial communication:

```python
import serial
import time
import os

# open and close COM8 to activate bootloader
ser = serial.Serial('COM8',baudrate=1200)
print(ser.isOpen()); ser.close()
time.sleep(2)

# load hex file on COM9
filesize = os.path.getsize('tclab_v2.ino.hex')
fid = open('tclab_v2.ino.hex','rb')
offset = 0; MTU = 20
ser2 = serial.Serial('COM9',115200)
while (offset < filesize):
    fid.seek(offset, 0)
    ser2.write(fid.read(MTU))
    offset = offset + MTU
ser2.close()
```

The script is able to activate the bootloader on another port and connect. If I transfer all at once with `ser2.write(fid.read())`, it semi-bricks the Arduino and I recover it by hitting the reset button just before the Arduino IDE installs the firmware. I use a Maximum Transfer Unit (MTU) of 20 but I couldn't verify if there is one for the Leonardo. I can write a Python function to identify the ports and have used `COM8` and `COM9` here just to simply the test. Although the TCLab firmware is preloaded for Python, sometimes users change the firmware to use MATLAB, Octave, or Java and then want to switch back to Python. I'd like to make that as easy as possible without adding more steps or more instructions to the [troubleshooting FAQ][7]. Can I update the firmware like the [MATLAB Arduino Support Package][8] that detects a new device and transfers the firmware automatically with user confirmation?

  [1]: https://pypi.org/project/tclab/
  [2]: https://github.com/APMonitor/arduino/blob/master/0_Test_Device/Python/tclab_v2/tclab_v2.ino
  [3]: https://pypi.org/project/avryp/
  [4]: https://pypi.org/project/avr_helpers/
  [5]: https://forum.arduino.cc/index.php?topic=417659.0
  [6]: https://github.com/APMonitor/arduino/blob/master/0_Test_Device/Python/tclab_v2/tclab_v2.ino.hex
  [7]: https://apmonitor.com/pdc/index.php/Main/ArduinoSetup
  [8]: https://www.mathworks.com/hardware-support/arduino-matlab.html

title: Flash firmware with hex file over serial with Python (no avrdude, Arduino IDE)

Answers: 1

body:
This isn't the exact answer but it helps.

Uploading without avrdude is complicated and generally slow. The best solution to not using the IDE is to open and close a port then use the avrdude command that the ide usually uses.

```python
from serial import Serial
from time import sleep
from subprocess import run

while input('Press enter to upload ') == '':
    Serial('COM5',baudrate=1200).close()
    sleep(1)
    run(["C:\\Progra~2\\Arduino\\hardware\\tools\\avr/bin/avrdude", "-CC:\\Progra~2\\Arduino\\hardware\\tools\\avr/etc/avrdude.conf", "-v", "-patmega32u4", "-cavr109", "-PCOM6", "-b57600", "-D", "-Uflash:w:C:\\Users\\USER\\Desktop\\Python\\tclab_v2/tclab_v2.ino.hex:i"])
```


body:
1. I am using Arduino Mega 2560 and I have written code for my GPS module (Neo-6m-0-001/GY-NEO6MV2) and it is working fine independently.
2. I also have written code for Compass module (QMC5883L) which is also working fine independently and I am displaying the direction on my TFT (made a graphical compass dial on TFT) in real-time which is also working fine and needle varies according to my compass direction.
3. Now I am trying to combine both codes and display the long. and lat. values in graphical TFT fields but it is giving me error.

**GPS code**
```
//Connect with pin 18 and 19
#include <TinyGPS.h>
float lat,lon;
TinyGPS gps; // create gps object

void setup()
{
    Serial.begin(57600); // connect serial
    Serial.println("The GPS Received Signal:");
    Serial1.begin(9600); // connect gps sensor

}

void loop(){
    while(Serial1.available()){ // check for gps data
    if(gps.encode(Serial1.read()))// encode gps data
    {
    gps.f_get_position(&lat,&lon); // get latitude and longitude

    Serial.print("Position: ");

    //Latitude
    Serial.print("Latitude: ");
    Serial.print(lat,6);
    Serial.print(",");

    //Longitude
    Serial.print("Longitude: ");
    Serial.println(lon,6);

   }
  }
}
```
**TFT and Compass Code**

```
#include <stdlib.h>
#include <SPI.h>
#include <Wire.h>      // this is needed even tho we aren't using it
#include "Adafruit_GFX.h"
#include "Adafruit_ILI9341.h"
#include <Adafruit_STMPE610.h>
#include <SoftwareSerial.h>

void Draw_Compass_Rose();
void display_item(int x, int y, String token, int txt_colour, int txt_size);
void arrow(int x2, int y2, int x1, int y1, int alength, int awidth, int colour);

// For the Adafruit TFT shield, these are the default.
#define TFT_DC 9
#define TFT_CS 10

// Use hardware SPI (on Uno, #13, #12, #11) and the above for CS/DC
Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC);

// The STMPE610 uses hardware SPI on the shield, and #8
#define STMPE_CS 8
Adafruit_STMPE610 ts = Adafruit_STMPE610(STMPE_CS);

// This is calibration data for the raw touch data to the screen coordinates
#define TS_MINX 150
#define TS_MINY 130
#define TS_MAXX 3800
#define TS_MAXY 4000

/*** UI details */
#define BUTTON_X 40
#define BUTTON_Y 140
#define BUTTON_W 60
#define BUTTON_H 30
#define BUTTON_SPACING_X 20
#define BUTTON_SPACING_Y 10
#define BUTTON_TEXTSIZE 2

/* Back Button details */
#define BACK_BUTTON_X 40
#define BACK_BUTTON_Y 40

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

// text box where numbers go,position the text box/rectangle
#define TEXT_X 10
#define TEXT_Y 10
#define TEXT_X1 10
#define TEXT_Y1 50
#define TEXT_X2 10
#define TEXT_Y2 90
#define TEXT_W 220
#define TEXT_H 30
#define TEXT_TSIZE 3
#define TEXT_TCOLOR ILI9341_MAGENTA
// the data (phone #) we store in the textfield
#define TEXT_LEN 12
char latitude[TEXT_LEN+1] = "";
char longitude[TEXT_LEN+1] = "";
uint8_t latitude_i=0;
uint8_t longitude_i=0;
char STATUS_X;
char STATUS_Y;
float lat = 0.0;
float lon = 0.0;
float AZMTH = 0.0;
float add;

const int centreX  = 160;
const int centreY  = 120;
const int diameter = 100;
int last_dx, last_dy, dx, dy;

// 0 -> Keypad    1 -> Compass
unsigned int page_state = 0;

// 0 -> latitude     1 -> longitude
unsigned int cursor_state = 0;

/* create 15 buttons, in classic candybar phone style */
char buttonlabels[15][5] = {"ENT", "CLR", "NEXT", "1", "2", "3", "4", "5", "6", "7", "8", "9", "0", ".", ">"};
uint16_t buttoncolors[15] = {ILI9341_DARKGREEN, ILI9341_DARKGREY, ILI9341_RED,
                             ILI9341_BLUE, ILI9341_BLUE, ILI9341_BLUE,
                             ILI9341_BLUE, ILI9341_BLUE, ILI9341_BLUE,
                             ILI9341_BLUE, ILI9341_BLUE, ILI9341_BLUE,
                             ILI9341_BLUE, ILI9341_BLUE, ILI9341_ORANGE};
Adafruit_GFX_Button buttons[15];

char backButtonLable[1][5] = {"Back"};
uint16_t backButtonColors[1] = {ILI9341_DARKGREEN};
Adafruit_GFX_Button backButton[1];

// Print something in the mini status bar with either flashstring
void status(const __FlashStringHelper *msg) {
  tft.fillRect(STATUS_X, STATUS_Y, 240, 8, ILI9341_BLACK);
  tft.setCursor(STATUS_X, STATUS_Y);
  tft.setTextColor(ILI9341_WHITE);
  tft.setTextSize(1);//font size on top of white box
  tft.print(msg);
}
// or charstring
void status(char *msg) {
  tft.fillRect(STATUS_X, STATUS_Y, 240, 8, ILI9341_BLACK);
  tft.setCursor(STATUS_X, STATUS_Y);
  tft.setTextColor(ILI9341_WHITE);
  tft.setTextSize(1);//font size on top of white box
  tft.print(msg);
}

void setup() {
  Serial.begin(9600);
  Serial.println("Arduin-Test-LCD");

  // clear the screen
  tft.begin();
  tft.fillScreen(ILI9341_BLACK);
  tft.setTextColor(ILI9341_MAGENTA);
  tft.print("      WELCOME TO AZIMUTH SYSTEM");
  // eep touchscreen not found?
  if (!ts.begin()) {
    Serial.println("Couldn't start touchscreen controller");
    while (1);
  }
  Serial.println("Touchscreen started");

  // create buttons
  for (uint8_t row=0; row<5; row++) {
    for (uint8_t col=0; col<3; col++) {
      buttons[col + row*3].initButton(&tft, BUTTON_X+col*(BUTTON_W+BUTTON_SPACING_X),
                 BUTTON_Y+row*(BUTTON_H+BUTTON_SPACING_Y),    // x, y, w, h, outline, fill, text
                  BUTTON_W, BUTTON_H, ILI9341_WHITE, buttoncolors[col+row*3], ILI9341_WHITE,
                  buttonlabels[col + row*3], BUTTON_TEXTSIZE);
      buttons[col + row*3].drawButton();
    }
  }

  // create 'text field'
  tft.drawRect(TEXT_X, TEXT_Y, TEXT_W, TEXT_H, ILI9341_WHITE);
  tft.drawRect(TEXT_X1, TEXT_Y1, TEXT_W, TEXT_H, ILI9341_WHITE);
  tft.drawRect(TEXT_X2, TEXT_Y2, TEXT_W, TEXT_H, ILI9341_WHITE);

  tft.setCursor(TEXT_X+2, TEXT_Y+10);
  tft.setTextColor(TEXT_TCOLOR, ILI9341_BLACK);
  tft.setTextSize(2);//font size inside white box
  tft.print(" LAT:");

  tft.setCursor(TEXT_X1 + 2, TEXT_Y1+10);
  tft.setTextColor(TEXT_TCOLOR, ILI9341_BLACK);
  tft.setTextSize(2);//font size inside white box
  tft.print(" LONG:");

  tft.setCursor(TEXT_X2 + 2, TEXT_Y2+10);
  tft.setTextColor(TEXT_TCOLOR, ILI9341_BLACK);
  tft.setTextSize(2);//font size inside white box
  tft.print(" AZMTH:");
}

void loop() {
  TS_Point p;

  if (ts.bufferSize()) {
    p = ts.getPoint();
  } else {
    // this is our way of tracking touch 'release'!
    p.x = p.y = p.z = -1;
  }

  // Scale from ~0->4000 to tft.width using the calibration #'s
  if (p.z != -1) {
    p.x = map(p.x, TS_MINX, TS_MAXX, 0, tft.width());
    p.y = map(p.y, TS_MINY, TS_MAXY, 0, tft.height());
    Serial.print("("); Serial.print(p.x); Serial.print(", ");
    Serial.print(p.y); Serial.print(", ");
    Serial.print(p.z); Serial.println(") ");
  }

  switch(page_state){
    case 0: // Means Keypad
  // go thru all the buttons, checking if they were pressed
  for (uint8_t b=0; b<15; b++) {
    if (buttons[b].contains(p.x, p.y)) {
      //Serial.print("Pressing: "); Serial.println(b);
      buttons[b].press(true);  // tell the button it is pressed
    } else {
      buttons[b].press(false);  // tell the button it is NOT pressed
    }
  }

  // now we can ask the buttons if their state has changed
  for (uint8_t b=0; b<15; b++) {
    if (buttons[b].justReleased()) {
      // Serial.print("Released: "); Serial.println(b);
      buttons[b].drawButton();  // draw normal
    }

    if (buttons[b].justPressed()) {
        buttons[b].drawButton(true);  // draw invert!

        // ENT Button was clicked
        if (b == 0){
          lon = atof(longitude);
          lat = atof(latitude);
          status(F("  Searching and laser start rotating"));
          Serial.println("Searching ");
          Serial.print("Latitude : ");
          Serial.println(String(lat));
          Serial.print("longitude : ");
          Serial.println(String(lon));
          Serial.print("lat + lon = ");
          AZMTH=lat+lon;
          Serial.println(AZMTH);

            // just add this part in this location
          //----- AND REPLACE THE VALUE -----
          tft.setCursor(TEXT_X2 + 90, TEXT_Y2+10);
              tft.setTextColor(TEXT_TCOLOR, ILI9341_BLACK);
              tft.setTextSize(2);//font size inside white box
              tft.print(AZMTH);
              Serial.print(AZMTH);

        }

        // CLR Button was clicked
        else if (b == 1) {
          switch(cursor_state){
            case 0:
              if (latitude > 0) {
                latitude_i--;
                latitude[latitude_i] = ' ';
              }
              break;

            case 1:
              if (longitude > 0) {
                longitude_i--;
                longitude[longitude_i] = ' ';
              }
              break;
          }
        }

        // NEXT Button was clicked
        else if (b == 2){
          page_state = 1;
          tft.fillScreen(BLACK);
          latitude[0]=0x00;
          latitude_i=0;
          longitude[0]=0x00;
          longitude_i=0;
          cursor_state = 0;

          tft.setRotation(1);
          Draw_Compass_Rose();
            double angle= 270; //use heading from compass
            dx = (diameter * cos((angle-90)*3.14/180)) + centreX;    // calculate X position
            dy = (diameter * sin((angle-90)*3.14/180)) + centreY;    // calculate Y position
            arrow(last_dx,last_dy, centreX, centreY, 20, 20,BLACK);  // Erase last arrow
            arrow(dx,dy, centreX, centreY, 20, 20,CYAN);             // Draw arrow in new position
            last_dx = dx;
            last_dy = dy;
          delay(25);
          tft.setRotation(0);

          }

        // '>' Button was clicked
        else if (b == 14){
          /* Toggle between latitude and longitude */
          if (cursor_state == 0){
            cursor_state = 1;
          } else if (cursor_state == 1){
            cursor_state = 0;
          }
        }

        // if a numberpad button, append the relevant # to the textfield
        else if (b >= 3) {
          switch(cursor_state){
            case 0:
              if (latitude_i < TEXT_LEN) {
                latitude[latitude_i] = buttonlabels[b][0];
                latitude_i++;
                latitude[latitude_i] = 0; // zero terminate
                //fona.playDTMF(buttonlabels[b][0]);
              }
              break;
            case 1:
              if (longitude_i < TEXT_LEN) {
                longitude[longitude_i] = buttonlabels[b][0];
                longitude_i++;
                longitude[longitude_i] = 0; // zero terminate
                //fona.playDTMF(buttonlabels[b][0]);
              }
              break;
          }

        }

      switch(cursor_state){
            case 0:
              // update the current latitude
              tft.setCursor(TEXT_X + 90, TEXT_Y+10);//set position of text when user key in the lat angle
              tft.setTextColor(TEXT_TCOLOR, ILI9341_BLACK);
              tft.setTextSize(2);//font size inside white box
              tft.print(latitude);
              Serial.print(latitude);
              break;

              // update the current longitude
            case 1:
              tft.setCursor(TEXT_X1 + 90, TEXT_Y1+10);//set position of text when user key in the long angle
              tft.setTextColor(TEXT_TCOLOR, ILI9341_BLACK);
              tft.setTextSize(2);//font size inside white box
              tft.print(longitude);
              Serial.print(longitude);
              break;
          }

    }
//
      delay(50); // UI debouncing

     }
   }
}

void display_item(int x, int y, String token, int txt_colour, int txt_size) {
    tft.setCursor(x, y);
    tft.setTextColor(txt_colour);
    tft.setTextSize(txt_size);
    tft.print(token);
    tft.setTextSize(2); // Back to default text size
}

void arrow(int x2, int y2, int x1, int y1, int alength, int awidth, int colour) {
  float distance;
  int dx, dy, x2o,y2o,x3,y3,x4,y4,k;
    distance = sqrt(pow((x1 - x2),2) + pow((y1 - y2), 2));
    dx = x2 + (x1 - x2) * alength / distance;
    dy = y2 + (y1 - y2) * alength / distance;
    k = awidth / alength;
    x2o = x2 - dx;
    y2o = dy - y2;
    x3 = y2o * k + dx;
    y3 = x2o * k + dy;
    x4 = dx - y2o * k;
    y4 = dy - x2o * k;
    tft.drawLine(x1, y1, x2, y2, colour);
    tft.drawLine(x1, y1, dx, dy, colour);
    tft.drawLine(x3, y3, x4, y4, colour);
    tft.drawLine(x3, y3, x2, y2, colour);
    tft.drawLine(x2, y2, x4, y4, colour);
}
void Draw_Compass_Rose(){
  int dxo, dyo, dxi, dyi;
    tft.drawCircle(centreX,centreY,diameter,YELLOW);  // Draw compass circle
  for (float i = 0; i <360; i = i + 22.5) {
    dxo = diameter * cos((i-90)*3.14/180);
    dyo = diameter * sin((i-90)*3.14/180);
    dxi = dxo * 0.9;
    dyi = dyo * 0.9;
    tft.drawLine(dxi+centreX,dyi+centreY,dxo+centreX,dyo+centreY,YELLOW);
  }
    display_item((centreX-5),(centreY-85),"N",RED,2);
    display_item((centreX-5),(centreY+70),"S",RED,2);
    display_item((centreX+80),(centreY-5),"E",RED,2);
    display_item((centreX-85),(centreY-5),"W",RED,2);
}

```

**Combine Code**

```
#include <stdlib.h>
#include <SPI.h>
#include <Wire.h>      // this is needed even tho we aren't using it
#include "Adafruit_GFX.h"
#include "Adafruit_ILI9341.h"
#include <Adafruit_STMPE610.h>
#include <SoftwareSerial.h>
#include <TinyGPS.h>

TinyGPS gps; // create gps

void Draw_Compass_Rose();
void display_item(int x, int y, String token, int txt_colour, int txt_size);
void arrow(int x2, int y2, int x1, int y1, int alength, int awidth, int colour);

// For the Adafruit TFT shield, these are the default.
#define TFT_DC 9
#define TFT_CS 10

// Use hardware SPI (on Uno, #13, #12, #11) and the above for CS/DC
Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC);

// The STMPE610 uses hardware SPI on the shield, and #8
#define STMPE_CS 8
Adafruit_STMPE610 ts = Adafruit_STMPE610(STMPE_CS);

// This is calibration data for the raw touch data to the screen coordinates
#define TS_MINX 150
#define TS_MINY 130
#define TS_MAXX 3800
#define TS_MAXY 4000

/*** UI details */
#define BUTTON_X 40
#define BUTTON_Y 140
#define BUTTON_W 60
#define BUTTON_H 30
#define BUTTON_SPACING_X 20
#define BUTTON_SPACING_Y 10
#define BUTTON_TEXTSIZE 2

/* Back Button details */
#define BACK_BUTTON_X 40
#define BACK_BUTTON_Y 40

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

// text box where numbers go,position the text box/rectangle
#define TEXT_X 10
#define TEXT_Y 10
#define TEXT_X1 10
#define TEXT_Y1 50
#define TEXT_X2 10
#define TEXT_Y2 90
#define TEXT_W 220
#define TEXT_H 30
#define TEXT_TSIZE 3
#define TEXT_TCOLOR ILI9341_MAGENTA
// the data (phone #) we store in the textfield
#define TEXT_LEN 12
char latitude[TEXT_LEN+1] = "";
char longitude[TEXT_LEN+1] = "";
uint8_t latitude_i=0;
uint8_t longitude_i=0;
char STATUS_X;
char STATUS_Y;
float lat = 0.0;
float lng = 0.0;
float AZMTH = 0.0;
float add;

const int centreX  = 160;
const int centreY  = 120;
const int diameter = 100;
int last_dx, last_dy, dx, dy;

// 0 -> Keypad    1 -> Compass
unsigned int page_state = 0;

// 0 -> latitude     1 -> longitude
unsigned int cursor_state = 0;

/* create 15 buttons, in classic candybar phone style */
char buttonlabels[15][5] = {"ENT", "CLR", "NEXT", "1", "2", "3", "4", "5", "6", "7", "8", "9", "0", ".", ">"};
uint16_t buttoncolors[15] = {ILI9341_DARKGREEN, ILI9341_DARKGREY, ILI9341_RED,
                             ILI9341_BLUE, ILI9341_BLUE, ILI9341_BLUE,
                             ILI9341_BLUE, ILI9341_BLUE, ILI9341_BLUE,
                             ILI9341_BLUE, ILI9341_BLUE, ILI9341_BLUE,
                             ILI9341_BLUE, ILI9341_BLUE, ILI9341_ORANGE};
Adafruit_GFX_Button buttons[15];

char backButtonLable[1][5] = {"Back"};
uint16_t backButtonColors[1] = {ILI9341_DARKGREEN};
Adafruit_GFX_Button backButton[1];

// Print something in the mini status bar with either flashstring
void status(const __FlashStringHelper *msg) {
  tft.fillRect(STATUS_X, STATUS_Y, 240, 8, ILI9341_BLACK);
  tft.setCursor(STATUS_X, STATUS_Y);
  tft.setTextColor(ILI9341_WHITE);
  tft.setTextSize(1);//font size on top of white box
  tft.print(msg);
}
// or charstring
void status(char *msg) {
  tft.fillRect(STATUS_X, STATUS_Y, 240, 8, ILI9341_BLACK);
  tft.setCursor(STATUS_X, STATUS_Y);
  tft.setTextColor(ILI9341_WHITE);
  tft.setTextSize(1);//font size on top of white box
  tft.print(msg);
}

void setup() {
Serial.begin(57600); // connect serial
Serial.println("The GPS Received Signal:");
Serial1.begin(9600); // connect gps sensor

  // clear the screen
  tft.begin();
  tft.fillScreen(ILI9341_BLACK);
  tft.setTextColor(ILI9341_MAGENTA);
  tft.print("      WELCOME TO AZIMUTH SYSTEM");
  // eep touchscreen not found?
  if (!ts.begin()) {
    Serial.println("Couldn't start touchscreen controller");
    while (1);
  }
  Serial.println("Touchscreen started");

  // create buttons
  for (uint8_t row=0; row<5; row++) {
    for (uint8_t col=0; col<3; col++) {
      buttons[col + row*3].initButton(&tft, BUTTON_X+col*(BUTTON_W+BUTTON_SPACING_X),
                 BUTTON_Y+row*(BUTTON_H+BUTTON_SPACING_Y),    // x, y, w, h, outline, fill, text
                  BUTTON_W, BUTTON_H, ILI9341_WHITE, buttoncolors[col+row*3], ILI9341_WHITE,
                  buttonlabels[col + row*3], BUTTON_TEXTSIZE);
      buttons[col + row*3].drawButton();
    }
  }

  // create 'text field'
  tft.drawRect(TEXT_X, TEXT_Y, TEXT_W, TEXT_H, ILI9341_WHITE);
  tft.drawRect(TEXT_X1, TEXT_Y1, TEXT_W, TEXT_H, ILI9341_WHITE);
  tft.drawRect(TEXT_X2, TEXT_Y2, TEXT_W, TEXT_H, ILI9341_WHITE);

  tft.setCursor(TEXT_X+2, TEXT_Y+10);
  tft.setTextColor(TEXT_TCOLOR, ILI9341_BLACK);
  tft.setTextSize(2);//font size inside white box
  tft.print(" LAT:");

  tft.setCursor(TEXT_X1 + 2, TEXT_Y1+10);
  tft.setTextColor(TEXT_TCOLOR, ILI9341_BLACK);
  tft.setTextSize(2);//font size inside white box
  tft.print(" LONG:");

  tft.setCursor(TEXT_X2 + 2, TEXT_Y2+10);
  tft.setTextColor(TEXT_TCOLOR, ILI9341_BLACK);
  tft.setTextSize(2);//font size inside white box
  tft.print(" AZMTH:");
}

void loop() {
  TS_Point p;
  while(Serial1.available()){ // check for gps data
  if(gps.encode(Serial1.read()))// encode gps data
   Serial.print("Position: ");
  }
  if (ts.bufferSize()) {
    p = ts.getPoint();
  } else {
    // this is our way of tracking touch 'release'!
    p.x = p.y = p.z = -1;
  }

  // Scale from ~0->4000 to tft.width using the calibration #'s
  if (p.z != -1) {
    p.x = map(p.x, TS_MINX, TS_MAXX, 0, tft.width());
    p.y = map(p.y, TS_MINY, TS_MAXY, 0, tft.height());
    Serial.print("("); Serial.print(p.x); Serial.print(", ");
    Serial.print(p.y); Serial.print(", ");
    Serial.print(p.z); Serial.println(") ");
  }

  switch(page_state){
    case 0: // Means Keypad
  // go thru all the buttons, checking if they were pressed
  for (uint8_t b=0; b<15; b++) {
    if (buttons[b].contains(p.x, p.y)) {
      //Serial.print("Pressing: "); Serial.println(b);
      buttons[b].press(true);  // tell the button it is pressed
    } else {
      buttons[b].press(false);  // tell the button it is NOT pressed
    }
  }

  // now we can ask the buttons if their state has changed
  for (uint8_t b=0; b<15; b++) {
    if (buttons[b].justReleased()) {
      // Serial.print("Released: "); Serial.println(b);
      buttons[b].drawButton();  // draw normal
    }

    if (buttons[b].justPressed()) {
        buttons[b].drawButton(true);  // draw invert!

        // ENT Button was clicked
        if (b == 0){
          lng = atof(longitude);
          lat = atof(latitude);
          status(F("  Searching and laser start rotating"));
          Serial.println("Searching ");
          Serial.print("Latitude : ");
          Serial.println(String(lat));
          Serial.print("longitude : ");
          Serial.println(String(lng));
          Serial.print("lat + lng = ");
          AZMTH=lat+lng;
          Serial.println(AZMTH);

            // just add this part in this location
          //----- AND REPLACE THE VALUE -----
          tft.setCursor(TEXT_X2 + 90, TEXT_Y2+10);
              tft.setTextColor(TEXT_TCOLOR, ILI9341_BLACK);
              tft.setTextSize(2);//font size inside white box
              tft.print(AZMTH);
              Serial.print(AZMTH);

        }

        // CLR Button was clicked
        else if (b == 1) {
          switch(cursor_state){
            case 0:
              if (latitude > 0) {
                latitude_i--;
                latitude[latitude_i] = ' ';
              }
              break;

            case 1:
              if (longitude > 0) {
                longitude_i--;
                longitude[longitude_i] = ' ';
              }
              break;
          }
        }

        // NEXT Button was clicked
        else if (b == 2){
          page_state = 1;
          tft.fillScreen(BLACK);
          latitude[0]=0x00;
          latitude_i=0;
          longitude[0]=0x00;
          longitude_i=0;
          cursor_state = 0;

          tft.setRotation(1);
          Draw_Compass_Rose();
            double angle= 270; //use heading from compass
            dx = (diameter * cos((angle-90)*3.14/180)) + centreX;    // calculate X position
            dy = (diameter * sin((angle-90)*3.14/180)) + centreY;    // calculate Y position
            arrow(last_dx,last_dy, centreX, centreY, 20, 20,BLACK);  // Erase last arrow
            arrow(dx,dy, centreX, centreY, 20, 20,CYAN);             // Draw arrow in new position
            last_dx = dx;
            last_dy = dy;
          delay(25);
          tft.setRotation(0);

          }

        // '>' Button was clicked
        else if (b == 14){
          /* Toggle between latitude and longitude */
          if (cursor_state == 0){
            cursor_state = 1;
          } else if (cursor_state == 1){
            cursor_state = 0;
          }
        }

        // if a numberpad button, append the relevant # to the textfield
        else if (b >= 3) {
          switch(cursor_state){
            case 0:
              if (latitude_i < TEXT_LEN) {
                latitude[latitude_i] = buttonlabels[b][0];
                latitude_i++;
                latitude[latitude_i] = 0; // zero terminate
                //fona.playDTMF(buttonlabels[b][0]);
              }
              break;
            case 1:
              if (longitude_i < TEXT_LEN) {
                longitude[longitude_i] = buttonlabels[b][0];
                longitude_i++;
                longitude[longitude_i] = 0; // zero terminate
                //fona.playDTMF(buttonlabels[b][0]);
              }
              break;
          }

        }

      switch(cursor_state){
            case 0:
              // update the current latitude
              tft.setCursor(TEXT_X + 90, TEXT_Y+10);//set position of text when user key in the lat angle
              tft.setTextColor(TEXT_TCOLOR, ILI9341_BLACK);
              tft.setTextSize(2);//font size inside white box
              Serial.print(latitude);
              if (gps.f_get_position(&lat,&lng))
              {
              tft.print(String(gps.f_get_position(&lat));
              double lat=gps.f_get_position(&lat,&lng));
              Serial.print(lat, 6);
              }
              break;

              // update the current longitude
            case 1:
              tft.setCursor(TEXT_X1 + 90, TEXT_Y1+10);//set position of text when user key in the long angle
              tft.setTextColor(TEXT_TCOLOR, ILI9341_BLACK);
              tft.setTextSize(2);//font size inside white box
              Serial.print(longitude);
              if (gps.f_get_position(&lat,&lng))
              {
              tft.print(String(gps.f_get_position(&lng));
              double lng=gps.f_get_position(&lat,&lng));
              Serial.print(lng, 6);
              }
              break;
          }

    }
//
      delay(50); // UI debouncing

     }
   }
}

void display_item(int x, int y, String token, int txt_colour, int txt_size) {
    tft.setCursor(x, y);
    tft.setTextColor(txt_colour);
    tft.setTextSize(txt_size);
    tft.print(token);
    tft.setTextSize(2); // Back to default text size
}

void arrow(int x2, int y2, int x1, int y1, int alength, int awidth, int colour) {
  float distance;
  int dx, dy, x2o,y2o,x3,y3,x4,y4,k;
    distance = sqrt(pow((x1 - x2),2) + pow((y1 - y2), 2));
    dx = x2 + (x1 - x2) * alength / distance;
    dy = y2 + (y1 - y2) * alength / distance;
    k = awidth / alength;
    x2o = x2 - dx;
    y2o = dy - y2;
    x3 = y2o * k + dx;
    y3 = x2o * k + dy;
    x4 = dx - y2o * k;
    y4 = dy - x2o * k;
    tft.drawLine(x1, y1, x2, y2, colour);
    tft.drawLine(x1, y1, dx, dy, colour);
    tft.drawLine(x3, y3, x4, y4, colour);
    tft.drawLine(x3, y3, x2, y2, colour);
    tft.drawLine(x2, y2, x4, y4, colour);
}
void Draw_Compass_Rose(){
  int dxo, dyo, dxi, dyi;
    tft.drawCircle(centreX,centreY,diameter,YELLOW);  // Draw compass circle
  for (float i = 0; i <360; i = i + 22.5) {
    dxo = diameter * cos((i-90)*3.14/180);
    dyo = diameter * sin((i-90)*3.14/180);
    dxi = dxo * 0.9;
    dyi = dyo * 0.9;
    tft.drawLine(dxi+centreX,dyi+centreY,dxo+centreX,dyo+centreY,YELLOW);
  }
    display_item((centreX-5),(centreY-85),"N",RED,2);
    display_item((centreX-5),(centreY+70),"S",RED,2);
    display_item((centreX+80),(centreY-5),"E",RED,2);
    display_item((centreX-85),(centreY-5),"W",RED,2);
}
```
Attached is the image of error line, GUI on TFT with lat. and long. field, TFT, and log errors.
[Errror line][1]

[![GUI][2]][2]

[![TFT][3]][3]

[![error line][4]][4]

[![log error][5]][5]

[![1][6]][6]

  [1]: https://i.stack.imgur.com/MPMg2.jpg
  [2]: https://i.stack.imgur.com/ynJR4.jpg
  [3]: https://i.stack.imgur.com/H2VWU.jpg
  [4]: https://i.stack.imgur.com/TQCyq.jpg
  [5]: https://i.stack.imgur.com/kbk9F.jpg
  [6]: https://i.stack.imgur.com/bFHEm.jpg

title: Display GPS module data to my TFT display

Answers: 0


body:
I've created a custom board that can be programmed using any one of several programmers defined in `programmers.txt`. I would like the user to be able to choose which programmer to use via the "Tools->Programmer" menu options.

I tried using `{protocol}` and `{upload.protocol}` in `platform.txt` to pass the programmer to the upload tool, but neither seem to be defined when the `Upload` button is used to initiate the upload (they are defined if `Upload using programmer` is selected from the menu).

title: How can I make my custom board use the programmer selected in "Tools->Programmer" when the Upload button is pushed?

Answers: 1

body:
Make sure you do not have a `protocol` listed in the `boards.txt` file. If the uploader sees protocol is `null` then it will fall back to using the same code that "Upload using programmer" does.

Relevant code in `SerialUploader.java`:

```
    if (usingProgrammer || prefs.get("upload.protocol") == null) {
      return uploadUsingProgrammer(buildPath, className);
    }
```


body:
I'm trying to write a program for AVR Atmel 328 chip on Arduino Nano board that will allow me to send machine code instructions to the chip over a serial line, run/execute them on the chip, and interrogate the results by reading chip memory and sending the contents back over the serial line.  This is the genesis of the idea: [3-instruction Forth by Frank Sergeant][1].

The remote-store and remote-fetch instructions appear to be working fine, but **I've not been able to get the remote-call instruction (`XCALL()` function) to work.** The approach I've taken is to coerce a 16-bit address into a subroutine by casting it as a function pointer.

Below is the code that is running on the Arduino Nano (compiled in the Arduino IDE and uploaded using the USB cable via the bootloader)

Any insight would be greatly appreciated!  (I can add diassembled code, my remote instructions etc, if that helps).

Thanks in advance!

    // Remote serial development platform for machine coding ArduinoNano/ATmel328, AKE, Jun 9, 2020

    // global variables
    unsigned char byt;                  // command token from host
    unsigned char mem[255];             // memory window under programmatic control
    unsigned char dat;                  // data byte from host
    unsigned char adr_lo;               // address from host, low byte first
    unsigned char adr_hi;
    unsigned short adr;                 // combined 16-bit address
    typedef void (*GeneralFunction)();  // template to call memory address (as a subroutine)

    void setup() {
      Serial.begin(9600);              // Turn UART serial protocol ON for comms with host PC
      Serial.write(0xFF);              // magic number to verify transmission
      Serial.write(0xFE);
      Serial.write((int) mem);         // Informs you of the writeable address space available (LSB, MSB) for tethered memory access
      Serial.write((int) mem>>8);
    }

    char get_byte(void) {
        while (!(Serial.available()>0)) { delay(50); }
        return Serial.read();
    }
    short get_adr(void) {
        adr_lo=get_byte();
        adr_hi=get_byte();
        return ( (short)adr_hi<<8 )   |   (short)adr_lo;
    }
    void xstore() {             // Instruction 1 = xstore(data,adr_lo,adr_hi).  Store byte from host at indicated address in target.
        dat=get_byte();
        adr=get_adr();
        *(char *)adr=dat;
    }
    void xfetch() {             //  Instruction 2 = xfetch(adr_lo,adr_hi).  Read byte from target memory and return to host.
            adr=get_adr();
            dat=*(char *)adr;
            Serial.write(dat);
    }
    void xcall() {              //  Instruction 3 = xcall(adr_lo,adr_hi).  Execute subroutine in target memory from indicated address.
                                //  WARNING!  User must have stored RET instruction to send control back to serial monitor.
            adr=get_adr();
            GeneralFunction fGf=adr;
            fGf;
    }

    void loop() {
        byt = get_byte();               // user specified instruction token (1,2,3)
        if(byt == 0x01 )      { xstore(); }
        else if (byt == 0x02) { xfetch(); }
        else if (byt == 0x3 ) { xcall(); } // else ignore any other serial inputs
    }

  [1]: http://pygmy.utoh.org/3ins4th.html

title: 3-instruction remote machine coding Arduino Atmel chip over a serial line from a tethered (host) PC

Answers: 1

body:
The AVR CPU cannot execute instructions from RAM. It's not a question of what the compiler can do or should be able to do, the physical chip itself cannot do it. There is simply no physical pathway between the RAM and the instruction decoder in the CPU.

Instructions can *only* be executed directly from Flash memory. That is how the chip works. You can only execute code that you send over serial if you first erase a page (or more) of Flash memory then burn the incoming code into that page. You can then call the start of that page's address and your code will execute.

But there is another caveat there: only code running in the bootloader flash area is allowed to modify the flash memory. That means your code can't do it, only the bootloader. That doesn't mean that the bootloader has to be running, but the code that you execute has to reside there.

There is an alternative version of the Optiboot bootloader that can provide flash writing facilities to a user program, but I have no experience using it so can't assist with that.


body:
println() function is being used to send AT commands to GSM module.
```
sim800l.println("AT+CLTS=1");
  delay(3000);
  sim800l.println("AT+COPS=2");
  delay(3000);
  sim800l.println("AT+COPS=0,0");
  delay(3000);
```
But problem is the output -
```
AT+CLTS=1

OK
AT+COP
```
The command AT+COP did not print fully? Why?
Minimal Reproducable Example -
```
#include <SoftwareSerial.h>    //Library required for serial communication
char MYDATA[18];
SoftwareSerial sim800l(3, 2); // RX,TX for Arduino and for the module it's TXD RXD, they should be inverted
void setup() {
  Serial.begin(9600); //Start the serial interface on 9600
  sim800l.begin(9600);
  delay(100);
  // AT command to set sim800l to SMS mode
  sim800l.println("AT+CMGF=1");
  //Serialcom();
  delay(100);
  // Set module to send SMS data to serial out upon receipt
  sim800l.println("AT+CNMI=2,2,0,0,0");
  delay(100);
  sim800l.println("AT+CLTS=1");
  delay(3000);
  sim800l.println("AT+COPS=2");
  delay(3000);
  sim800l.println("AT+COPS=0,0");
  delay(3000);
   sim800l.println("AT+CCLK?");
  Serial.find("+CCLK: \"");
  Serial.readBytesUntil('\+', MYDATA, 17);

}

void loop() {
 Serial.print(MYDATA);
}

title: Serial.print() not fully printing

Answers: 1

body:
You're overflowing the serial receive buffer. There's only a limited amount of space (64 bytes normally, maybe less in SoftwareSerial) for receiving data before you must read it or lose data. Since you are just blindly throwing commands at the SIM800 and not doing anything with its responses until right at the end all that incoming data fills the receive buffer to overflowing.

Your methodology is flawed (not your fault, the examples on the internet are all rubbish and teach you the wrong way of doing things). What you should be doing is issuing a command then receiving the response back and parsing it to see if the command was successful or not, and retrieve any information that the response may include that you would want to know.


body: I have decided to make a simple project so thinked about arduino but that seems very worthy so i decided to use attiny85 ic for my project,but i don't have arduino or avr to program it. Is there any way to program the below ic without arduino or avr?.

title: Attiny85 microcontroller programming without arduino

Answers: 2

body:
> **Is there any way to program [a bare AVR microcontroller] without Arduino [hardware] or AVR [hardware programmer]?**

Programming a *bare* AVR microcontoller like the ATtiny85 *IC* needs either another Arduino board or an AVR programmer device.

---

### Programmer $4-$7

Something like the Pololu AVR Programmer v2.1 can be bought for $7 and used with the free Arduino development software (IDE). I have used this to program an ATtiny85. This is what I would suggest, because a programmer is the most versatile solution.

[![USBAPS][1]][1] Even cheaper, a $4 USBASP

---

### Arduino as ISP $4.50

I have used an old Arduino Duemilanove using the Arduino as ISP sketch as a programmer for an ATtiny85 but any Arduino with inbuilt USB and enough GPIO could be used. There are some low cost ATmega328P or ATmega32u4 based Arduino clones that would be suitable. A Nano v3 clone costs $4.50.

[![Nano][2]][2]

---

### Development Board with USB $3

As others have commented, you can buy a "digispark" (just Google and click "shopping") for three or four dollars. This is essentially a breakout board with an ATtiny85, a USB connector and a soft-USB-capable bootloader pre-loaded onto the ATtiny85. You can program it with the Arduino IDE after using the IDE's board-manager to install Digistump's "core" definitions for the Digispark. It doesn't need another Arduino nor an AVR Programmer. I bought three on Amazon for $9 a month ago.

[![three digisparks][3]][3]

Since it *is* an Arduino-compatible development board, it doesn't really meet your requirement of "without Arduino" - but it might be the closest solution to what you have in mind.

---

Useful resources and inspiration:

- [ATtiny-Based Beginner's Kit](http://www.technoblogy.com/show?NMX)
- [Twelve PWM outputs from an ATtiny85](http://www.technoblogy.com/show?2H0K).

Yes, 12 LEDs individually controlled with just four resistors and four pins of an eight-pin ATtiny85 and and no other components!

I have no affiliation with the above site, I just think it is one anyone new to electronics with an ATtiny85  would find interesting.

  [1]: https://i.stack.imgur.com/VQxJG.png
  [2]: https://i.stack.imgur.com/8j43Z.png
  [3]: https://i.stack.imgur.com/ZXwDP.png

body:
>  **Is there any way to program [a bare AVR microcontroller] without Arduino [IDE software] or AVR [software development toolkit]?**

I believe you can use

- A text editor of your choice to create and edit source code files.
- The GNU compiler [GCC-AVR](https://www.google.com/search?q=gcc+for+avr) to compile source code into machine-code.
- The [avrdude](https://www.nongnu.org/avrdude/) program to install the compiled code onto the microcontroller.

All these can be obtained at zero cost.


body:
I hope you are in a helpful mood, today.

I have run into a little problem with my project. I wanted to mount my camera on a Servocity SPT 400 tilt kit  and control the thing via a bluetooth connection. The setup is as follows I have an Arduino Uno V3 board with an HC - 05 bluetooth module and hooked a Hitec HS-5485HB servo to the board.
Pretty straightforward but I managed to make it work as intended so far.
![Text](https://wieselhead.de/wp-content/uploads/2020/06/thing.jpg)

Here is a picture of how everything is connected, since it partially works I think it's not completely wrong.

The problem starts here though, the Servocity SPT 400 tilt kit comes with an external potentiometer,
The instructions sheet says to cut the internal potentiometer cables that were connected to the servo circuits and solder the three cables (red, yellow and green) to the external potentiometer.

With the coding skills I made the tilt mechanism move a few mm but that was not the desired result.
So what I need is a working code that allows me to control the whole thing via bluetooth.
I don't know how to control a potentiometer into my noobish code.

----------

    #include <SoftwareSerial.h> // TX RX software library for bluetooth

    #include <Servo.h> // servo library
    Servo myservo; // servo name

    int bluetoothTx = 10; // bluetooth tx to 10 pin
    int bluetoothRx = 11; // bluetooth rx to 11 pin

    SoftwareSerial bluetooth(bluetoothTx, bluetoothRx);

    void setup()
    {
      myservo.attach(9); // attach servo signal wire to pin 9
      //Setup usb serial connection to computer
      Serial.begin(9600);

      //Setup Bluetooth serial connection to android
      bluetooth.begin(9600);
    }

    void loop()
    {
      //Read from bluetooth and write to usb serial
      if(bluetooth.available()> 0 ) // receive number from bluetooth
      {
        int servopos = bluetooth.read(); // save the received number to servopos
        Serial.println(servopos); // serial print servopos current number received from bluetooth
        myservo.write(servopos); // roate the servo the angle received from the android app
      }

    }

I really would appreciate some help.

title: little Code problem Servocity SPT 400 tilt kit

Answers: 0


body:
    #include <HCSR04.h>

    int red = 13;
    int green = 12;
    int blue = 11;
    int trigger = 9;
    int echo = 8;
    int halt;

    void setup(){
      pinMode(red, OUTPUT);
      pinMode(green, OUTPUT);
      pinMode(blue, OUTPUT);
      pinMode(trigger, OUTPUT);
      pinMode(echo, INPUT);
      Serial.begin(9600);
    }

    void redLed(){
      rgb(255,0,0);
      delay(200);
    }

    void rgb(int r, int g, int b){
      analogWrite(red, r);
      analogWrite(green, g);
      analogWrite(blue, b);
    }

    void fadeBlu(){

        for (int i=0; i<=255; i+=5){
        rgb(0,0,i);
        delay(40);

        Serial.print("halt in IF is ");
        Serial.println(halt);
        }

        for(int i=255; i>=0; i-=5) {
          rgb(0,0,i);
          delay(40);

          Serial.print("halt ELSE is ");
          Serial.println(halt);
        }
    }

    void human() {

      UltraSonicDistanceSensor distanceSensor(trigger, echo);
      double distance = distanceSensor.measureDistanceCm();
      halt = 0;

      // cover sensor
      if (distance<=30) {
        halt=0;
        redLed();
      }
      // no cover
        halt=-1;
        fadeBlu();
    }

    void loop(){
      human();
    }

I'm looking for a way to exit from "for" loop of fadeBlue() function if the hand is detected in front of sensor. I would like that in any case of fading and if there is hand in front of sensor the led became red. In my code the led doesn't stay red if I had hand in front of the sensor and also the value of "halt" doesn't change. I put some serial.println to make debugging.

title: Exit from for function after detecting obstacles

Answers: 1

body:
First, try to avoid duplication of code, so make a sub function (I slightly changed the print statement, but I assume it's only for debugging):

    void fadeBlu()
    {
        fadeBlueCycle(0, 255, 5);
        fadeBlueCycle(255, 0, -5);
    }

    void fadeBlueCycle(uint8_t start, uint8_t end, int8_t step)
    {
        for (int i = start; i != end; i += step)
        {
            rgb(0, 0, i);
            delay(40);

            Serial.print("halt in step ");
            Serial.print(step);
            Serial.println(halt);
        }
    }

Now to break from the `for`, you can use `break`, or simply `return`. It's not a good practice to have multiple `return` statements in one function, thus put it at the end, and use a `break`. Also, some people don't like a `break` and prefer using a `while. This would look like:

    void fadeBlueCycle(uint8_t start, uint8_t end, int8_t step)
    {
        uint8_t i = start;
        bool condition = true;

        while ((i != end) && condition) // or !condition, depending on what you prefer
        {
            rgb(0, 0, i);
            delay(40);

            Serial.print("halt in step ");
            Serial.print(step);
            Serial.println(halt);

            condition = `some condition`;
            i += step;
        }
    }


body:
## Introduction ##

I am trying to setup a radio communication using the NRF24L01 module because I want to use it to control a tank. The first thing I did when I got the modules was watching some basic tutorials on youtube, for reference I watched HowToMecharonics' video: <https://www.youtube.com/watch?v=7rcVeFFHcFM>

"Arduino Tutorial: Arduino NRF24L01 Wireless Tutorial with Arduino Uno"

At first I tried to rewrite the code myself to see if I got the concept, but all of my attempts failed, so I tried to copy-paste his exact code and use the arduino IDE, but it didn't work.

Later I noticed that the setup only worked if I plugged both arduinos to the PC, they don't work when plugged in a power supply.
The receiver is an arduino MEGA and the transmitter an UNO.
When I unplug the UNO the IDE says "avrdude: ser_drain(): read error: The device does not recognize the command."
## Question ##
If I unplug the receiver it just doesn't work until I plug it back in, but no error pops up.

It seems strange to me that both arduinos have to be plugged yo the computer at al times, am I doing something wrong?
I also noticed that my modules are slightly different from the ones shown in the viedo, mine doesn't have a label below it

## Code ##

TX

```
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>

RF24 radio(7, 8); // CE, CSN
const byte address[6] = "00001";

void setup() {
  radio.begin();
  radio.openWritingPipe(address);
  radio.setPALevel(RF24_PA_MIN);
  radio.stopListening();
}

void loop() {
  const char text[] = "Hello World";
  radio.write(&text, sizeof(text));
  delay(1000);
}
```

RX

```
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>

RF24 radio(7, 8); // CE, CSN
const byte address[6] = "00001";

void setup() {
  pinMode(2, OUTPUT);
  Serial.begin(9600);
  radio.begin();
  radio.openReadingPipe(0, address);
  radio.setPALevel(RF24_PA_MIN);
  radio.startListening();
  Serial.println("working");
}

void loop() {
  if (radio.available()) {
    char text[32] = "";
    radio.read(&text, sizeof(text));
    digitalWrite(2, HIGH);
    delay(100);
    digitalWrite(2, LOW);
  }
}
```

title: Trouble with basic communication between two NRF24L01 modules

Answers: 0


body:
I am working on Arduino UDE board in Ubuntu 18.04. I've followed following link tutorial.

https://www.arduino.cc/en/Guide/ArduinoDue#:~:text=Use your Arduino Due on the Arduino Desktop IDE,the Arduino Boards Manager page.

In Ardiuno IDE I am getting as /dev/ttyS4. Also, I've gone with follwing procedure :
```
sudo usermod -a -G dialout username
sudo chmod a+rw /dev/ttyS4
ls -l /dev/ttyS4
```
This gave the following outpit
```
crw-rw-rw- 1 root dialout 4, 68 Jun 17 17:26 /dev/ttyS4
```
And I am getting following error while uploading sketch though Ardiuno IDE :
```
Sketch uses 11092 bytes (2%) of program storage space. Maximum is 524288 bytes.
Forcing reset using 1200bps open/close on port /dev/ttyS4
/home/user/.arduino15/packages/arduino/tools/bossac/1.6.1-arduino/bossac -i -d --port=ttyS4 -U false -e -w -v -b /tmp/arduino_build_718911/ardiuno_to_python.ino.bin -R
Send auto-baud
No device found on ttyS4
An error occurred while uploading the sketch
Set binary mode
```
I've tried following solution of decreasing baudrate to 1200 by following command line mulitple times till I get output as 1200 :
```
stty -F /dev/ttyS4 speed 1200 cs8 -cstopb -parenb
```
Still I am facing the error while uploading sketch. I've tried pressing reset and erase buttons few seconds but still not getting anything. Can anyone please help

title: Ardiuno DUE board. Sketch uploading Error

Answers: 1

body: The problem is solved. The cable came with my Arduino was charge only , I tried data transfer cable and it worked. This is so dumb. sorry for wasting your time.


body:
I'm trying to run a 3-digit 7-segment using single 74HC595 based on Arduino. But I have a serious problem with `delay()` function. When I want to count from 000 to 999 with `delay(1000)`, this delay function causes all digits to be off! My code is as below and I uploaded a video **[Click Here][1]** to understand my purpose. This problem can affect some applications like reading the temperature of DS12b20 which requires a delay itself.

    //                 2        1         0
    //               ----      ----      ----
    //              |    |    |    |    |    |
    //               ----      ----      ----
    //              |    |    |    |    |    |
    //               ----      ----      ----

    int latch = 8; //74HC595  pin STCP
    int clock = 9; //74HC595  pin SHCP
    int data = 10; //74HC595  pin DS

    // Each annode pin (for those that don't know think of it as an on switch when it's assigned HIGH)
    int dig1 = 2; // digit0
    int dig2 = 3; // digit1
    int dig3 = 4; // digit2
    int digit[4]={dig1, dig2, dig3};

    int timer=3;
    // these are bits to make the 8 bit byte accepted by the segment display the 9th is the demical point
    // 0-9 then invald numbers
    byte table[] = {
      B00111111, B00000110, B01011011, B01001111, B01100110,
      B01101101, B01111101, B00000111, B01111111, B01101111, B01111111
    };

    void setup(){
      pinMode(latch, OUTPUT);
      pinMode(clock, OUTPUT);
      pinMode(data, OUTPUT);
      pinMode(dig1, OUTPUT);
      pinMode(dig2, OUTPUT);
      pinMode(dig3, OUTPUT);
    }

    //this sends the data to the digit
    void RunNum(int num, int SelectDigit){
      digitalWrite(latch, LOW);
      shiftOut(data, clock, MSBFIRST, table[num]);
      digitalWrite(latch, HIGH);
      digitalWrite(digit[SelectDigit], LOW);
      delay(timer);
      digitalWrite(digit[SelectDigit], HIGH);

    }

    //main program
    void loop() {
      for (int i=0; i<10; i++){
        for (int j=0; j<10; j++){
          for (int k=0; k<10; k++){
            RunNum(k, 0);
            RunNum(j, 1);
            RunNum(i, 2);
            delay(1000);  //  <====    This line affects the project
          }
        }
      }
    }

 I updated my code (only `void loop()`) as below using `millis()`. You can watch the results (**[Click Here][2]**). But, the delay problem has not been solved so far!

    const long interval = 1000;   //  1000 ms = 1 s
    long previousMillis = 0;
    unsigned long currentMillis=0;

    //main program
    void loop() {
      for (int i=0; i<10; i++){
        for (int j=0; j<10; j++){
          for (int k=0; k<10; k++){
            while (currentMillis - previousMillis < interval){
              currentMillis=millis();
              RunNum(k, 0);
              RunNum(j, 1);
              RunNum(i, 2);
            }
            previousMillis = currentMillis;
          }
        }
      }
    }

  [1]: http://s12.picofile.com/file/8400330784/VID_20200617_212526.mp4.html
  [2]: http://s12.picofile.com/file/8400414976/VID_20200618_195832.mp4.html

title: delay() problem for 74HC595 and 7-segment

Answers: 2

body:
With the displays which use shift register to light multiple seven segment digit blocks, the register lights up only one digit at a time. The illusion of multiple digits lit is created by fast switching the digits in round. Small delays in this cause the number to look dim, larger delays create flickering and long delays show only one digit lit. So a sketch handling this type of display must run without delays.

In this type of sketch, everything must be handled without delays, so if some sensor requires a delay, start the reading and a millis timer and after the elapsed time read the result.

There are displays using specialized chips, for example TM1637D, which handle the seven segments even if your sketch stops in delay.

----------

adoption of the [BlinkWithoutDelay][1] basic example for your algorithm:

    unsigned long previousMillis = 0;
    const long interval = 1000;
    int i, j, k;

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

    void loop() {
      unsigned long currentMillis = millis();

      if (currentMillis - previousMillis >= interval) {
        previousMillis = currentMillis;
        k++;
        if ( k == 10) {
          k = 0;
          j++;
          if (j == 10) {
            j = 0;
            i++;
            if (i == 10) {
              i = 0;
            }
          }
        }
        Serial.print(i);
        Serial.print(j);
        Serial.println(k);
      }
    }

  [1]: https://www.arduino.cc/en/Tutorial/BlinkWithoutDelay

body:
<strike>In `loop()` as you've shown it in your code, you can move `RunNum(i,2);` down to outside of the 'j' and 'k' loops. Likewise you can move `RunNum(j,1);` down to outside of the 'k' loop. This won't fix your problem but it will speed up each update of the display.</strike>

Then, know that you can tell one (or all) of your DS18B20 sensors to start a temperature conversion *without waiting for the conversion to finish*. Then you use millis() to tell you when the conversion is done, and you can get the result very quickly. Some libraries provide the amount of time you need to wait for the conversion; some provide some kind of an "is it done yet?" boolean function. Either one of those will let you remove the 'wait til done' delay.

Update:

> This strategy doesn't work properly!...

Sorry if I missed something - it looked like there were opportunities to optimize there.

> About temperature sensor, I should say that reading the temperature takes about 750 ms itself. In other words, it acts as a delay and causes turning off the display for 750 ms.

It is temperature measurement and conversion to a 12-bit result - which takes place *entirely within the DS18B20* sensor itself - that takes 750ms. *The Arduino is not involved in that process* and could be doing other tasks such as maintaining your display during that time.

*Reading* the temperatures, once the conversion is done, is much quicker.  If your library doesn't provide the ability to start a conversion and return, without waiting for the results, and separate entry to read the results, look for a library that does.

Update:
[Miles Burton's Arduino-Temperature-Control-Library][1] provides a 'wait for conversion' flag that you can set false so ::requestsTemperatures() will return immediately, and an ::isConversionComplete() call to check whether the data is ready. (Of course, knowing that the device takes 750ms
for a 12-bit conversion, you could just as well use millis() to decide that.)

  [1]: https://github.com/milesburton/Arduino-Temperature-Control-Library


body:
Can i use pin RX TX on Arduino Uno as reguler pin ? .
For input and output pin , because two digital pin on my board doesn’t work . Thank’s

title: Using RX TX pin

Answers: 1

body: Yes, you can use those pins like regular digital pins on the Uno. They are numbered 0 and 1. That is... provided you do not try to use `Serial`.


body:
I'm pretty new to C++ / Arduino code, please bear with me. Following code currently gives me a `Exception (28): epc1=0x40201287 epc2=0x00000000 epc3=0x00000000 excvaddr=0x00000000 depc=0x00000000`.

I *suspect* that this is because I'm trying to use the pointer to a local variable `char parsedString` in `drawMenu()` which is probably destroyed after running `renderMenu()` and therefor I get a memory related exception(?). Is that correct?

Secondly, if that is true, I'm wondering if I'm just simply trying too hard to avoid global variables, I already got a ton. And creating for every single parsing variable in a function sounds like overkill. What would be the most efficient way to render my menu?

    void drawMenu () {

      char* lines;
      renderMenu(lines);

      for (int i = 0; i < menuMaxLines; i++) {
        Serial.println(lines[i]);
      }
    }

    void renderMenu(char* &output) {

      // Get current menu items
      MenuItem * menuCurrentItems = getMenuItems();

      // Loop out the menu items at the current position (menuPosition), don't exceed the count of menuitems (menuCurrentItemCount) and don't exceed more then the desired lines (menuMaxLines)
      for (int i = menuPosition; i < menuCurrentItemCount && i < menuPosition + menuMaxLines; i++) {

        MenuItem menuItem = menuCurrentItems[i];
        char parsedString[menuMaxLines];

        // Prefix for the menulabel, when focussed
        if (menuFocussedItem == i) {
          strcat(parsedString, "> ");
        }
        else {
          strcat(parsedString, "  ");
        }

        char output[i - menuPosition][menuMaxWidth];
        strcpy(output[i - menuPosition], parsedString);
      }
    }

title: Construct char arrays within function

Answers: 0


body:
This may sound like a simple question but I have tried to find the right solution but all I find is the usual make an led blink and even I can code that nugget
I am quite new to programming arduino but am a dab hand with a soldering iron.
What I would like to do is combine the attributes of an LDR to allow a lighting sketch to run if it is dark and go off in daylight, but all I seem to find is turn a pin high or low, this is no good as I already have a sketch I would like to run

I am using WS2811 led nodes housed in pinspot style housings so the sketch would need to check the light level and if it is below a set value run the rest of the sketch then check every hour to see if the light level has changed to be above a set level  if it is go into a check loop until the light level falls again to below the set value can anyone point me in the right direction I would be grateful for any assistance

Thanks
Dave

title: Use an LDR to run a sketch

Answers: 2

body:
You're unlikely to find exactly what you want as existing code example. Break it into parts and solve it in parts.

You can't "Run a sketch" based on reading a value of an LDR. You can write a new sketch that reads an LDR, and calls a function if it's dark, or a different function if it is light. You will need to refactor your code from your other sketch into functions that you can integrate into your new combined sketch that uses the LDR. That means doing some original programming, not "finding the right solution" ready-made on the internet.

First, how do you use an LDR to determine if it's light or dark? Answer, use an analog input. Build a voltage divider with the LDR and a similar sized resistor, and feed the output into an analog pin. Say the LDR is between +5V and the pin, so more light results in higher voltage, hence a larger value.

Log the output of the LDR to the console in a loop, and decide on your threshold values for light and dark. Make the threshold value a constant. Let's call it DARK.

Now write a loop function. It might look something like this:

    int lightValue;
    #define ldr_pin xxx //your pin number
    #define threshold xxx //your threshold value

    void setup() {
       //set the ldr pin as an analog input
    }

    void loop() {
       lightValue = analogRead(ldr_pin);
       if (lightValue <= threshold) {
          doNightStuff();
       } else {
          stopDoingStuff();
       }
    }

## Edit:

As mentioned by Edgar, the code above will be subject to "jitter", where it will rapidly switch back and forth between the dark and light states.

The solution is to add a buffer range where once it's in one state, it doesn't change states until it leaves the buffer range.

The if statement might look like this:

    #define buffer 5

    if ((lightValue +buffer) <= threshold)
        doNightStuff();
    else if ((lightValue -buffer) >= threshold)
        stopDoingStuff();

body:
@ Duncan C

think i have a solution not sure if it's your way but it does work so not bad for a newbie lol

    //
    //  "Pacifica"
    //  Gentle, blue-green ocean waves.
    //  December 2019, Mark Kriegsman and Mary Corey March.
    //  For Dan.
    //  Thanks for the sketch i have added a daylight sensor so they now go off in daylight Dave Cowell June 2020

    int lightValue;  //new code dc

    #define FASTLED_ALLOW_INTERRUPTS 0
    #include <FastLED.h>
    FASTLED_USING_NAMESPACE

    #define ldr_pin             A0   //new dc
    #define Threshold_dark      100  //new dc
    #define Threshold_light     1000  //new dc
    #define DATA_PIN            7
    #define NUM_LEDS            28
    #define MAX_POWER_MILLIAMPS 500
    #define LED_TYPE            WS2811
    #define COLOR_ORDER         RGB

    //////////////////////////////////////////////////////////////////////////

    CRGB leds[NUM_LEDS];

    void setup() {

      analogRead (A0);  //new dc

      delay( 3000); // 3 second delay for boot recovery, and a moment of silence
      FastLED.addLeds<LED_TYPE,DATA_PIN,COLOR_ORDER>(leds, NUM_LEDS)
            .setCorrection( TypicalLEDStrip );
      FastLED.setMaxPowerInVoltsAndMilliamps( 5, MAX_POWER_MILLIAMPS);
    }

    void loop(){

     lightValue = analogRead (ldr_pin);  //new dc

     if (lightValue <= Threshold_dark){    // new dc

        EVERY_N_MILLISECONDS(20)
        pacifica_loop();
        FastLED.show();

     }else { (lightValue = Threshold_light);  // New dc

     {                                         // New dc

     for (int i = 0; i <NUM_LEDS;i++){         // New dc

          memset (leds,0,NUM_LEDS*3);          // New dc

                    FastLED.show();             // New dc

                    FastLED.delay (100);         // New dc

     }         // New dc
      }        // New dc
       }       // New dc
        }      // New dc

    //////////////////////////////////////////////////////////////////////////
    //
    // The code for this animation is more complicated than other examples, and
    // while it is "ready to run", and documented in general, it is probably not
    // the best starting point for learning.  Nevertheless, it does illustrate some
    // useful techniques.
    //
    //////////////////////////////////////////////////////////////////////////
    //
    // In this animation, there are four "layers" of waves of light.
    //
    // Each layer moves independently, and each is scaled separately.
    //
    // All four wave layers are added together on top of each other, and then
    // another filter is applied that adds "whitecaps" of brightness where the
    // waves line up with each other more.  Finally, another pass is taken
    // over the led array to 'deepen' (dim) the blues and greens.
    //
    // The speed and scale and motion each layer varies slowly within independent
    // hand-chosen ranges, which is why the code has a lot of low-speed 'beatsin8' functions
    // with a lot of oddly specific numeric ranges.
    //
    // These three custom blue-green color palettes were inspired by the colors found in
    // the waters off the southern coast of California, https://goo.gl/maps/QQgd97jjHesHZVxQ7
    //
    CRGBPalette16 pacifica_palette_1 =
        { 0x000507, 0x000409, 0x00030B, 0x00030D, 0x000210, 0x000212, 0x000114, 0x000117,
          0x000019, 0x00001C, 0x000026, 0x000031, 0x00003B, 0x000046, 0x14554B, 0x28AA50 };
    CRGBPalette16 pacifica_palette_2 =
        { 0x000507, 0x000409, 0x00030B, 0x00030D, 0x000210, 0x000212, 0x000114, 0x000117,
          0x000019, 0x00001C, 0x000026, 0x000031, 0x00003B, 0x000046, 0x0C5F52, 0x19BE5F };
    CRGBPalette16 pacifica_palette_3 =
        { 0x000208, 0x00030E, 0x000514, 0x00061A, 0x000820, 0x000927, 0x000B2D, 0x000C33,
          0x000E39, 0x001040, 0x001450, 0x001860, 0x001C70, 0x002080, 0x1040BF, 0x2060FF };

    void pacifica_loop()
    {
      // Increment the four "color index start" counters, one for each wave layer.
      // Each is incremented at a different speed, and the speeds vary over time.
      static uint16_t sCIStart1, sCIStart2, sCIStart3, sCIStart4;
      static uint32_t sLastms = 0;
      uint32_t ms = GET_MILLIS();
      uint32_t deltams = ms - sLastms;
      sLastms = ms;
      uint16_t speedfactor1 = beatsin16(3, 179, 269);
      uint16_t speedfactor2 = beatsin16(4, 179, 269);
      uint32_t deltams1 = (deltams * speedfactor1) / 256;
      uint32_t deltams2 = (deltams * speedfactor2) / 256;
      uint32_t deltams21 = (deltams1 + deltams2) / 2;
      sCIStart1 += (deltams1 * beatsin88(1011,10,13));
      sCIStart2 -= (deltams21 * beatsin88(777,8,11));
      sCIStart3 -= (deltams1 * beatsin88(501,5,7));
      sCIStart4 -= (deltams2 * beatsin88(257,4,6));

      // Clear out the LED array to a dim background blue-green
      fill_solid( leds, NUM_LEDS, CRGB( 2, 6, 10));

      // Render each of four layers, with different scales and speeds, that vary over time
      pacifica_one_layer( pacifica_palette_1, sCIStart1, beatsin16( 3, 11 * 256, 14 * 256), beatsin8( 10, 70, 130), 0-beat16( 301) );
      pacifica_one_layer( pacifica_palette_2, sCIStart2, beatsin16( 4,  6 * 256,  9 * 256), beatsin8( 17, 40,  80), beat16( 401) );
      pacifica_one_layer( pacifica_palette_3, sCIStart3, 6 * 256, beatsin8( 9, 10,38), 0-beat16(503));
      pacifica_one_layer( pacifica_palette_3, sCIStart4, 5 * 256, beatsin8( 8, 10,28), beat16(601));

      // Add brighter 'whitecaps' where the waves lines up more
      pacifica_add_whitecaps();

      // Deepen the blues and greens a bit
      pacifica_deepen_colors();
    }

    // Add one layer of waves into the led array
    void pacifica_one_layer( CRGBPalette16 & p, uint16_t cistart, uint16_t wavescale, uint8_t bri, uint16_t ioff)
    {
      uint16_t ci = cistart;
      uint16_t waveangle = ioff;
      uint16_t wavescale_half = (wavescale / 2) + 20;
      for( uint16_t i = 0; i < NUM_LEDS; i++) {
        waveangle += 250;
        uint16_t s16 = sin16( waveangle ) + 32768;
        uint16_t cs = scale16( s16 , wavescale_half ) + wavescale_half;
        ci += cs;
        uint16_t sindex16 = sin16( ci) + 32768;
        uint8_t sindex8 = scale16( sindex16, 240);
        CRGB c = ColorFromPalette( p, sindex8, bri, LINEARBLEND);
        leds[i] += c;
      }
    }

    // Add extra 'white' to areas where the four layers of light have lined up brightly
    void pacifica_add_whitecaps()
    {
      uint8_t basethreshold = beatsin8( 9, 55, 65);
      uint8_t wave = beat8( 7 );

      for( uint16_t i = 0; i < NUM_LEDS; i++) {
        uint8_t threshold = scale8( sin8( wave), 20) + basethreshold;
        wave += 7;
        uint8_t l = leds[i].getAverageLight();
        if( l > threshold) {
          uint8_t overage = l - threshold;
          uint8_t overage2 = qadd8( overage, overage);
          leds[i] += CRGB( overage, overage2, qadd8( overage2, overage2));
        }
      }
    }

    // Deepen the blues and greens
    void pacifica_deepen_colors()
    {
      for( uint16_t i = 0; i < NUM_LEDS; i++) {
        leds[i].blue = scale8( leds[i].blue,  145);
        leds[i].green= scale8( leds[i].green, 200);
        leds[i] |= CRGB( 2, 5, 7);
      }
      {

      }
    }


body: This is a basic level lazer alarm project. When anyone crosed or kept their hands on the lazer. buzzer starts working but when they took their hand from lazer light buzzer stops. But i want even after taking hands my buzzer should work for few (15-30) seconds .so please help me by giving idea..

title: How to run my buzzer for few more seconds after switching off

Answers: 1

body:
If you are using a digital buzzer, you can do:
```
digitalWrite(buzzerPin,HIGH);
delay(1000);
digitalWrite(buzzerPin,LOW);


body:
I am sending specific **UDP** packets with my **esp8266** every 5s, I have added an **OTA update** command, and added the update_progress callback aiming to send it back to my laptop, using a serial terminal I noticed that regular packets, as well as the progress packet, are not sent during the update, everything gets back after. Is the esp able to send and receive packets simultaneously?, is there any interference or the **OTA update** process causes an interruption?

*Hardware: ESP8266MOD Nodemcu*

*Software: VS code with portable Arduino 1.8.9, espcore 2.6.3*

title: Unable to send UDP packets while performing OTA update on the esp8266

Answers: 1

body:
esp8266 ArduinoOTA library has
```cpp
  WiFiUDP::stopAll();
  WiFiClient::stopAll();
```
to ensure undisturbed OTA upload


body:
Due to some curiosity, I was trying to use some assembly with my Arduino MEGA 2560.
I am not able to invoke a function from a c++ function pointer array.

When I uncomment the call function, `func_a` runs. However, when I almost reproduce the assembly, it doesnt work.

Example:

    extern "C" void __attribute__ ((used, noinline, noreturn)) func_a();

    typedef void (*volatile func_ptr)();

    func_ptr tasks[MAX_TASKS] = {&func_a};

    extern "C"
    void __attribute__ ((used, noinline)) call(func_ptr *ptr) {
        (*ptr)();
    }

    void __attribute__ ((noreturn, used)) setup() {

        // call(tasks);

        asm volatile (
        "lds r26, (tasks)\n"
        "lds r27, (tasks + 1)\n"

        "ld r30, X+\n"
        "ld r31, X\n"

        "eijmp\n"
        );
    }

Generated assembly recovered from avr-objdump

    000001c6 <setup>:
     1c6: a0 91 00 02  lds r26, 0x0200 ; 0x800200 <tasks>
     1ca: b0 91 01 02  lds r27, 0x0201 ; 0x800201 <tasks+0x1>
     1ce: ed 91        ld r30, X+
     1d0: fc 91        ld r31, X
     1d2: 19 94        eijmp
     1d4: 08 95        ret

    000001d6 <call>:
     1d6: dc 01        movw r26, r24
     1d8: ed 91        ld r30, X+
     1da: fc 91        ld r31, X
     1dc: 19 94        eijmp

An specific resources I should refer for things like this?

If it matters, I'm using platformio on a linux system for compilation.

title: Am not able to call C++ function pointers from inline assembly

Answers: 2

body:
I will start off by saying that I am no expert in AVR assembly, so I have no idea if any of this is actually correct. However from reading the various [documents](http://ww1.microchip.com/downloads/en/devicedoc/atmel-0856-avr-instruction-set-manual.pdf) on the subject I have gleaned:

* On the ATMega2560 `EIJMP` uses a combination of both the Z register *and* the `EIND` register to form a full address.

That means that as well as setting up the Z register for the lower 16 bits of the address you also have to set up the `EIND` register for the upper 5 bits of the address.

> Indirect jump to the address pointed to by the Z (16 bits) Pointer Register in the Register File and the EIND Register in the I/O space. This instruction allows for indirect jumps to the entire 4M (words) Program memory space.

It then goes on to show an example:

```
ldi r16,$05 ; Set up EIND and Z-pointer
out EIND,r16
ldi r30,$00
ldi r31,$10
eijmp ; Jump to $051000
```

How you determine what the EIND register should be? Well, in general you don't. You wouldn't use EIJMP. From what I understand for functions outside the lower 64kwords of address space the compiler builds a "jump table" which is stored in the lower area of memory. You jump to the entry in that table with `IJMP` and that table then jumps to the final destination with `EIJMP` for you.

Doing this kind of jumping in assembly isn't really a nice thing to try and figure out. It's messy. Better to let the compiler do it for you and use C rather than assembly.  The AVR-GCC guys put a lot of work into making function pointers work correctly (from what I have read it wasn't easy even for them), and you're just re-inventing the wheel.

At the very least you should implement your code 100% in C to begin with then look at the compiled output to see how the compiler thinks it should be done.

body:
It seems you got confused by the pointer indirections, which is
confounded by the _implicit_ indirections made by the compiler.

Here:

```c++
extern "C"
void __attribute__ ((used, noinline)) call(func_ptr *ptr) {
    (*ptr)();
}
```

The parameter `ptr` is _not_ a function pointer: it's a pointer to a
function pointer. You have to dereference it _twice_ in order to get the
function: `(**ptr)();`. Note that the compiler implicitly dereferences a
function pointer if you call it like a function: that's why you get no
error by explicitly dereferencing the pointer only once. In the
generated assembly, the lines

```lisp
ld  r30, X+
ld  r31, X
```

dereference `ptr` in order to get the address of the function to call.

You probably wanted to write

```c++
extern "C"
void __attribute__ ((used, noinline)) call(func_ptr ptr) {
    ptr();
}
```

And then use it as:

```c++
call(tasks[0]);
```

If you just `call(tasks)`, the array identifier decays to pointer, and
the compiler handles this as a shortcut for `call(&tasks[0]);`, which
turns out to be compatible with your initial implementation of `call()`.

Now, in your inline assembly you have

```lisp
lds r26, (tasks)
lds r27, (tasks + 1)
```

The assembly treats `tasks` as a _symbol_ representing the address of
the `tasks` array. The linker replaces those symbols by the actual
address (`0x0200`). Those instructions read the RAM at this and the
following address. These slots of RAM hold the first item of the array,
namely `&func_a`. So now you have this address in the X register pair.
No need to read RAM again: you can `movw r30, r26` and do the indirect
jump. Or, better yet, load into Z to begin with:

```list
lds r30, (tasks)
lds r31, (tasks + 1)
eijmp
```

See also Majenko's answer: here I am assuming `EIND` is somehow
correctly set up to begin with. On an Uno, you would just use `ijmp`
instead of `eijmp` and not worry about `EIND`.


body:
I am using ESP8266 NodeMCU with MAX7219 and a DS3231 teal time clock. I want to display the time and some text. The display is made of 4 FC16 modules which are made of 4 8x8 MAX7219 led matrix modules so it would be a 32x32 led matrix diplay divided in 4 rows.
I am displaying the time hh:mm on the last row and text on the first 3 rows.

With ESP8266 I connected to my wi-fi and I created a web server which says "Hello World!"

So my question is: how do I upload my code to the web server so I can change the text remotely?

I found this tutorial [https://maker.pro/esp8266/tutorial/how-to-build-an-led-matrix-display-with-a-nodemcu-esp8266][1] that shows how to change the text on one row of display but I don't want something that fancy. I just want my code uploaded and to be able to change in the code.

```
#include "RTClib.h"
#include <MD_Parola.h>
#include <MD_MAX72xx.h>
#include <SPI.h>
#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>

ESP8266WebServer server;

// Define the number of devices we have in the chain and the hardware interface
// NOTE: These pin numbers will probably not work with your hardware and may
// need to be adapted
#define HARDWARE_TYPE MD_MAX72XX::FC16_HW
#define MAX_DEVICES 12
#define NUM_ZONES 3

int CS_PIN = D4;
int CLK_PIN = D5;
int DATA_PIN = D7;

// Hardware SPI connection
MD_Parola P = MD_Parola(HARDWARE_TYPE, CS_PIN, MAX_DEVICES);
// Arbitrary output pins
// MD_Parola P = MD_Parola(HARDWARE_TYPE, DATA_PIN, CLK_PIN, CS_PIN, MAX_DEVICES);

RTC_DS3231 rtc;
#define SPEED_TIME  25
#define PAUSE_TIME  1000

uint8_t lastUpdateMin = 0;
uint8_t lastUpdateHour = 0;

// Global variable
const char  *pc[NUM_ZONES] =
{
  "TIME", //0
  "ROOM", //1
  "SUBJECT", //2
  //"GRADE",//3
};

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

  WiFi.begin("ssid", "password");

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

  Serial.print("Connected, IP address: ");
  Serial.println(WiFi.localIP());
  server.on("/", []() {
    server.send(200, "text/plain", "Hello World!");
  });
  server.begin();

  P.begin();
  if (! rtc.begin()) {
    Serial.println("Couldn't find RTC");
    while (1);
  }

  if (rtc.lostPower()) {
    Serial.println("RTC lost power, lets set the time!");
    //     If the RTC have lost power it will set the RTC to the date & time this sketch was compiled in the following line
    rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
  }

  P.begin(3);
  P.setZone(0, 0, 3); // Modules 0-3 in zone 0
  P.setZone(1, 4, 7); // Modules 4-7 in zone 1
  P.setZone(2, 8, 11); // Modules 8-11 in zone 2
  // P.setZone(3, 12, 15); // Modules 12-15 in zone 3
}

void loop(void)
{
  server.handleClient();
  DateTime now = rtc.now();
  if (lastUpdateMin != now.minute()) { // change every minute
    lastUpdateMin = now.minute();
    char buffer[] = "hh:mm";  // hours and minutes
    P.displayZoneText(0, now.toString(buffer), PA_CENTER, 0, 0, PA_PRINT, PA_NO_EFFECT);
  }
  if (lastUpdateHour != now.hour()) {   // change every hour
    lastUpdateHour = now.hour();
    P.displayZoneText(1, pc[1], PA_CENTER, 0, 0, PA_PRINT, PA_NO_EFFECT);  // 2nd row
    P.displayZoneText(2, pc[2], PA_CENTER, 0, 0, PA_PRINT, PA_NO_EFFECT);   // 3rd row
    //   P.displayZoneText(3, pc[3], PA_CENTER, 0, 0, PA_PRINT, PA_NO_EFFECT); // 4th row
  }
  P.displayAnimate();
}
```

  [1]: https://maker.pro/esp8266/tutorial/how-to-build-an-led-matrix-display-with-a-nodemcu-esp8266

title: ESP8266 NODEMCU V3 web server with MAX7219 and DS3231 RTC

Answers: 0


body:
Continuing a [Question asked few days ago][1], answered by Edgar, a new question has rised:

My goal was using a **past** `time_t` value, and convert it into a `struct tm` variable in order to  use it, part as a `Char` to print a readable text and some for logic queries.

At start NTP is configured as:

    void myIOT32::startNTP(const int gmtOffset_sec = 2 * 3600, const int daylightOffset_sec = 3600, const char *ntpServer = "pool.ntp.org")
    {
      configTime(gmtOffset_sec, daylightOffset_sec, ntpServer);
    }

and every-time I need to get epoch and or `struct tm` of **current** time I call this function

    void myIOT32::getTime()
    {
      int a = 0;
      while (a < 3)
      {
        if (getLocalTime(&timeinfo))
        {
          delay(100);
          time(&epoch_time);
        }
        a++;
      }

BUT, when using the following function I get not GMT (+3) reference as needed :

    struct tm *myIOT32::convEpoch(time_t in_time)
    {
      struct tm *convTime = gmtime(&in_time);
      //char time_char[40];
      //sprintf(time_char, "d-d-d d:d:d", convTime->tm_year + 1900, convTime->tm_mon + 1, convTime->tm_mday,
              convTime->tm_hour, convTime->tm_min, convTime->tm_sec);
      return convTime;
    }

Meaning I get to correct epoch time, but `strcut tm` is 3 hrs earlier ( and no, I do not want to hard-code `+3`... )

  [1]: https://arduino.stackexchange.com/questions/76290/error-passing-a-time-t-and-struct-tm-esp32

title: Fail to convert time_T from past to tm struct

Answers: 1

body:
replacing `gmtime(&timeinfo)` with `localtime(&timeinfo)` in `myIOT32::convEpoch` passes definition of time-zone as needed.

for more information [in this cpluspls site][1]

  [1]: http://www.cplusplus.com/reference/ctime/gmtime/


body:
in my code, I was using string class to make an array to store my menu items
~~~~~~~~~~~~~~~~~~~~~~~~
String menu[2] = {{"Menu 1"}, {"Menu2"}};
~~~~~~~~~~~~~~~~~~~~~~~~
How do I convert this into char arrays and how do I call them?
~~~~~~~~~~~~~~~~~~~~~~~
Example:
Serial.println(menu[0]);

title: Having trouble with sprintf function and string class

Answers: 1

body:
Create them as char arrays like this:

    const char* menu[2] = {"Menu 1", "Menu 2"};

and use them like this:

    Serial.println(menu[0]);


body:
I am using teensy 2.0 as DAC. I am trying to write signals on rudder and throttle of the ship via relay. How can I write these analog signals? Should I specify voltage for every pin?

Here is my code:

    int Rudder_p= 21; //Digital Write
    int Rudder_s= 20; //Digital Write
    int Throttle_p= 19; //Analog write
    int Throttle_s= 18; //Analog write
    int Throttle_T= 17; //Digital Write

    void setup() {
      Serial.begin(9600);
      pinMode(Realy1,OUTPUT);
      pinMode(Rudder_p,INPUT);
      pinMode(Rudder_s,INPUT);
      pinMode(Throttle_p,OUTPUT);
      pinMode(Throttle_s,OUTPUT);
      pinMode(Throttle_T,INPUT);

      if (Serial.available() > 0) {
        incomingByte = Serial.read();
      }
    }

    // the loop routine runs over and over again forever:
    void loop() {

      //Relay
      digitalWrite(Relay1,HIGH);
      delay(500);
      digitalWrite(Relay1,LOW);
      delay(500);

       //I am missing logic here:

      // read the input on analog pin 21
      int Value = analogWrite(F0);
      delay(1);        // delay in between reads for stability
    }

title: How to write analog signals to control throttle of the ship?

Answers: 0


body:
[![enter image description here][1]][1]
I am working on a power meter project with ZMPT101B and SCT013. I want to see the phase difference between voltage and current in the serial plotter but the results are like this? Why do you think the current reading is not a sine like a voltage wave?]
[2]][2]

  [1]: https://i.stack.imgur.com/Yn2Pq.png
  [2]: https://i.stack.imgur.com/NWgnT.png

Answers: 0