text:
Arduino Raspberry RadioHead node sends sensor data with sendtowait (ReliableDatagram) raspberry receives but node gets no ack
I have a configuration like following:
An Arduino and a raspberry both running with RadioHead library
Arduino with sensor sends data to a raspberry gateway using RHReliableDatagram with the sendtoWait method. Raspberry receives data and processes it with success. But Arduino receives no ack from raspberry. Have you any hint what the problem could be?
Arduino code
#include <RH_RF95.h>
#include <RHReliableDatagram.h>
#include <CayenneLPP.h>

///////////////////////////////////////////////////////////////////
// START CONFIGURATION
///////////////////////////////////////////////////////////////////

/* COMMENT FOR PRODUCTION USE */
#define DEBUG

// SELECT FREQUENCY APPROPRIATE TO YOUR COUNTRY
#define RF_FREQUENCY 868.0

// CHANGE HERE THE NODE ADDRESS
#define SERVER_ADDRESS 2
// GIVE EACH NODE A UNIQUE ID
#define NODE_ADDR 31

/* SELECT THE USED SENSOR TYPE */
// ONLY ONE OF THE FOLLOWING MUST BE DEFINED, IF ANY
#define ADAFRUIT_SI7021
//#define ADAFRUIT_SHT31

/* UNCOMMENT IF USING OLED DISPLAY */
//#define OLED
///////////////////////////////////////////////////////////////////
// CONFIGURATION
///////////////////////////////////////////////////////////////////

#ifdef ADAFRUIT_SI7021
#include <Adafruit_Si7021.h>
#elif defined ADAFRUIT_SHT31
#include <Adafruit_SHT31.h>
#endif

// Singleton instance of the radio driver
RH_RF95 rf95;
//RH_RF95 rf95(5, 2); // Rocket Scream Mini Ultra Pro with the RFM95W
//RH_RF95 rf95(8, 3); // Adafruit Feather M0 with RFM95

// Class to manage message delivery and receipt, using the driver declared above
RHReliableDatagram manager(rf95, NODE_ADDR);

CayenneLPP lpp(51);

#ifdef ADAFRUIT_SI7021
Adafruit_Si7021 si7021 = Adafruit_Si7021();
#elif defined ADAFRUIT_SHT31
Adafruit_SHT31 sht31 = Adafruit_SHT31();
#endif

const long InternalReferenceVoltage = 1062;  // Adjust this value to your board's specific internal BG voltage

int donePin = 4;
#ifdef ADAFRUIT_SI7021 || ADAFRUIT_SHT31
double tmp;
double hum;
#endif
double bat;
char msg[128];

// Need this on Arduino Zero with SerialUSB port (eg RocketScream Mini Ultra Pro)
//#define Serial SerialUSB

char *ftoa(char *a, double f, int precision)
{
 long p[] = {0,10,100,1000,10000,100000,1000000,10000000,100000000};

 char *ret = a;
 long heiltal = (long)f;
 itoa(heiltal, a, 10);
 while (*a != '\0') a++;
 *a++ = '.';
 long desimal = abs((long)((f - heiltal) * p[precision]));
 if (desimal < p[precision-1]) {
  *a++ = '0';
 }
 itoa(desimal, a, 10);
 return ret;
}

//read internal voltage
double readVcc() {
  long result;
  // Read 1.1V reference against AVcc
  ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
  delay(2); // Wait for Vref to settle
  ADCSRA |= _BV(ADSC); // Convert
  while (bit_is_set(ADCSRA, ADSC));
  result = ADCL;
  result |= ADCH << 8;
  result = 1126400L / result; // Back-calculate AVcc in mV
  return double(result) / 1000;
}

void setup()
{
  // Rocket Scream Mini Ultra Pro with the RFM95W only:
  // Ensure serial flash is not interfering with radio communication on SPI bus
//  pinMode(4, OUTPUT);
//  digitalWrite(4, HIGH);

#ifdef DEBUG
  Serial.begin(9600);
  Serial.println("Started");
#endif

  pinMode(donePin, OUTPUT);

#ifdef ADAFRUIT_SI7021
  if (!si7021.begin()) {
#ifdef DEBUG
    Serial.println("Did not find Si7021 sensor!");
#endif
    while (true);
  }
#elif defined ADAFRUIT_SHT31
  if (!sht31.begin(0x44)) {
#ifdef DEBUG
    Serial.println("Did not find Si7021 sensor!");
#endif
    while (true);
  }
#endif

  if (!rf95.init())
#ifdef DEBUG
    Serial.println("init failed");
#endif

  // Defaults after init are 434.0MHz, 13dBm, Bw = 125 kHz, Cr = 4/5, Sf = 128chips/symbol, CRC on
  rf95.setFrequency(RF_FREQUENCY);
  rf95.setModeTx();
  rf95.setTxPower(14, false); // values between 5 to 23
  manager.setThisAddress(NODE_ADDR);
  manager.setHeaderFrom(NODE_ADDR);
}

void loop()
{

#ifdef DEBUG
  Serial.print("Sending to gateway ");
  Serial.println(SERVER_ADDRESS);
#endif

  int i = 0;
  lpp.reset();

#ifdef ADAFRUIT_SI7021
  tmp = si7021.readTemperature();
  lpp.addTemperature(1, tmp);
#ifdef DEBUG
  Serial.print("Temperature Si7021: ");
  Serial.println(tmp);
#endif
  hum = si7021.readHumidity();
  lpp.addRelativeHumidity(2, hum);
#ifdef DEBUG
  Serial.print("Humidity Si7021: ");
  Serial.println(hum);
#endif
#elif defined ADAFRUIT_SHT31
  tmp = sht31.readTemperature();
  lpp.addTemperature(1, tmp);
#ifdef DEBUG
  Serial.print("Temperature SHT31: ");
  Serial.println(tmp);
#endif
  hum = sht31.readHumidity();
  lpp.addRelativeHumidity(2, hum);
#ifdef DEBUG
  Serial.print("Humidity SHT31: ");
  Serial.println(hum);
#endif
#endif

  bat = readVcc();
  if (!isnan(bat))
  {
    lpp.addVoltage(3, bat);
#ifdef DEBUG
    Serial.print("Voltage: ");
    Serial.println(bat);
#endif
  }

#ifdef DEBUG
  Serial.print("Send data: ");
#endif

//  if (manager.sendtoWaitTimeout(lpp.getBuffer(), lpp.getSize(), SERVER_ADDRESS))
  if (manager.sendtoWait(lpp.getBuffer(), lpp.getSize(), SERVER_ADDRESS))
  {
#ifdef DEBUG
    Serial.println("OK");
#endif
  }
  else
  {
#ifdef DEBUG
    Serial.println("Failed (no reply, is server running)?");
#endif
  }

  digitalWrite(donePin, LOW);
  digitalWrite(donePin, HIGH);

#ifdef DEBUG
  delay(10000);
#endif
}

Raspberry Code:
// rf95_server.cpp
//
// Example program showing how to use RH_RF95 on Raspberry Pi
// Uses the bcm2835 library to access the GPIO pins to drive the RFM95 module
// Requires bcm2835 library to be already installed
// http://www.airspayce.com/mikem/bcm2835/
// Use the Makefile in this directory:
// cd example/raspi/rf95
// make
// sudo ./rf95_server
//
// Contributed by Charles-Henri Hallard based on sample RH_NRF24 by Mike Poublon

#include <bcm2835.h>
#include <stdio.h>
#include <signal.h>
#include <unistd.h>

#include "RadioHead/RH_RF69.h"
#include "RadioHead/RH_RF95.h"
#include "RadioHead/RHReliableDatagram.h"

#include <MQTTClient.h>
#include "SimpleIni/SimpleIni.h"

// define hardware used change to fit your need
// Uncomment the board you have, if not listed
// uncommment custom board and set wiring tin custom section

// LoRasPi board
// see https://github.com/hallard/LoRasPI
//#define BOARD_LORASPI

// iC880A and LinkLab Lora Gateway Shield (if RF module plugged into)
// see https://github.com/ch2i/iC880A-Raspberry-PI
//#define BOARD_IC880A_PLATE

// Raspberri PI Lora Gateway for multiple modules
// see https://github.com/hallard/RPI-Lora-Gateway
//#define BOARD_PI_LORA_GATEWAY

// Dragino Raspberry PI hat
// see https://github.com/dragino/Lora
#define BOARD_DRAGINO_PIHAT

// Now we include RasPi_Boards.h so this will expose defined
// constants with CS/IRQ/RESET/on board LED pins definition
#include "../RasPiBoards.h"

// Our RFM95 Configuration
#define RF_FREQUENCY  868.00
//#define RF_NODE_ID    1  replaced by gateway_id in rf95_server.ini

// Create an instance of a driver
RH_RF95 rf95(RF_CS_PIN, RF_IRQ_PIN);
//RH_RF95 rf95(RF_CS_PIN);

// Ini file
CSimpleIniA ini;

// Our MQTT Client Configuration
#define TIMEOUT 10000L
int rc;

//Flag for Ctrl-C
volatile sig_atomic_t force_exit = false;

void sig_handler(int sig)
{
  printf("\n%s Break received, exiting!\n", __BASEFILE__);
  force_exit=true;
}

int reconnect(MQTTClient client, const char* dest_addr, MQTTClient_connectOptions conn_opts)
{
  while (!MQTTClient_isConnected(client))
  {
    printf("Connect to MQTT broker on %s\n", dest_addr);
    if ((rc = MQTTClient_connect(client, &conn_opts)) == MQTTCLIENT_SUCCESS)
    {
      break;
    }
    else
    {
      fprintf(stderr, "Could not connect to MQTT broker: %d\n", rc);
      for (int i = 0; i < 10; i++)
      {
        fprintf(stderr, ".");
        delay(500);
      }
      fprintf(stderr, "\n");
    }
  }
  return 0;
}

//Main Function
int main (int argc, const char* argv[] )
{
  unsigned long led_blink = 0;

  signal(SIGINT, sig_handler);
  printf( "Starting %s\n", __BASEFILE__);

  ini.SetUnicode();
  if (ini.LoadFile("rf95_server.ini") < 0) {
    printf("Error occurred while trying to open ini file. Please provide a valid ini file\n");
    return 1;
  }
  printf("Content of rf95_server.ini\n");
  const char *project = ini.GetValue("common", "project", NULL);
  printf("project=%s\n", project);
  const char *dest_addr = ini.GetValue("common", "dest_addr", NULL);
  printf("dest_addr=%s\n", dest_addr);
  const char *client_id = ini.GetValue("common", "client_id", NULL);
  printf("client_id=%s\n\n", client_id);
  const char *gateway_id = ini.GetValue("common", "gateway_id", NULL);
  printf("gateway_id=%s\n\n", gateway_id);

  if (!bcm2835_init()) {
    fprintf( stderr, "%s bcm2835_init() Failed\n\n", __BASEFILE__ );
    return 1;
  }

  printf( "RF95 CS=GPIO%d", RF_CS_PIN);

#ifdef RF_LED_PIN
  pinMode(RF_LED_PIN, OUTPUT);
  digitalWrite(RF_LED_PIN, HIGH );
#endif

#ifdef RF_IRQ_PIN
  printf( ", IRQ=GPIO%d", RF_IRQ_PIN );
  // IRQ Pin input/pull down
  pinMode(RF_IRQ_PIN, INPUT);
  bcm2835_gpio_set_pud(RF_IRQ_PIN, BCM2835_GPIO_PUD_DOWN);
  // Now we can enable Rising edge detection
  bcm2835_gpio_ren(RF_IRQ_PIN);
#endif

#ifdef RF_RST_PIN
  printf( ", RST=GPIO%d", RF_RST_PIN );
  // Pulse a reset on module
  pinMode(RF_RST_PIN, OUTPUT);
  digitalWrite(RF_RST_PIN, LOW );
  bcm2835_delay(150);
  digitalWrite(RF_RST_PIN, HIGH );
  bcm2835_delay(100);
#endif

#ifdef RF_LED_PIN
  printf( ", LED=GPIO%d", RF_LED_PIN );
  digitalWrite(RF_LED_PIN, LOW );
#endif

  printf( " OK NodeID=%d @ %3.2fMHz\n", *gateway_id, RF_FREQUENCY );

  MQTTClient client;
  MQTTClient_connectOptions conn_opts = MQTTClient_connectOptions_initializer;
  MQTTClient_message pubmsg = MQTTClient_message_initializer;
  MQTTClient_deliveryToken token;
  char topic[128];

  printf("Create MQTT client\n");
  if ((MQTTClient_create(&client, dest_addr, client_id, MQTTCLIENT_PERSISTENCE_NONE, NULL)) != MQTTCLIENT_SUCCESS) {
    fprintf(stderr, "Creation of MQTT client failed \n");
    return 1;
  }
  conn_opts.keepAliveInterval = 20;
  conn_opts.cleansession = 1;
  reconnect(client, dest_addr, conn_opts);

  printf("Init RF95 module");
  RHReliableDatagram manager(rf95, *gateway_id);
  if (!manager.init()) {
    fprintf( stderr, "\nRF95 module init failed, Please verify wiring/module\n" );
  } else {
    // Defaults after init are 434.0MHz, 13dBm, Bw = 125 kHz, Cr = 4/5, Sf = 128chips/symbol, CRC on

    // The default transmitter power is 13dBm, using PA_BOOST.
    // If you are using RFM95/96/97/98 modules which uses the PA_BOOST transmitter pin, then
    // you can set transmitter powers from 5 to 23 dBm:
    //  driver.setTxPower(23, false);
    // If you are using Modtronix inAir4 or inAir9,or any other module which uses the
    // transmitter RFO pins and not the PA_BOOST pins
    // then you can configure the power transmitter power for -1 to 14 dBm and with useRFO true.
    // Failure to do that will result in extremely low transmit powers.
    // rf95.setTxPower(14, true);

    // RF95 Modules don't have RFO pin connected, so just use PA_BOOST
    // check your country max power useable, in EU it's +14dB
    rf95.setTxPower(14, false);

    // You can optionally require this module to wait until Channel Activity
    // Detection shows no activity on the channel before transmitting by setting
    // the CAD timeout to non-zero:
    //rf95.setCADTimeout(10000);

    // Adjust Frequency
    printf("set lora frequency to %d", RF_FREQUENCY);
    rf95.setFrequency(RF_FREQUENCY);

    // If we need to send something
    manager.setThisAddress(*gateway_id);
    manager.setHeaderFrom(*gateway_id);

    // Be sure to grab all node packet
    // we're sniffing to display, it's a demo
    rf95.setPromiscuous(true);

    // We're ready to listen for incoming message
    printf("set receive mode");
    rf95.setModeRx();

    //Begin the main body of code
    while (!force_exit) {

#ifdef RF_IRQ_PIN
      // We have a IRQ pin ,pool it instead reading
      // Modules IRQ registers from SPI in each loop

      // Rising edge fired ?
      if (bcm2835_gpio_eds(RF_IRQ_PIN)) {
        // Now clear the eds flag by setting it to 1
        bcm2835_gpio_set_eds(RF_IRQ_PIN);
        //printf("Packet Received, Rising event detect for pin GPIO%d\n", RF_IRQ_PIN);
#endif

        printf( "Listening...\n" );

        if (rf95.available()) {
#ifdef RF_LED_PIN
          led_blink = millis();
          digitalWrite(RF_LED_PIN, HIGH);
#endif
          // Should be a message for us now
          uint8_t buf[RH_RF95_MAX_MESSAGE_LEN];
          uint8_t len  = sizeof(buf);
          uint16_t from = manager.headerFrom();
          uint8_t to   = manager.headerTo();
          uint8_t id   = manager.headerId();
          uint8_t flags= manager.headerFlags();;
          int8_t rssi  = rf95.lastRssi();

          if (manager.recvfromAck(buf, &len)) {
            printf("Packet[%02d] #%d => #%d %ddB:\n", len, from, to, rssi);
            printbuffer(buf, len);
            printf("\n");

            pubmsg.payload = &buf;
            pubmsg.payloadlen = len;
            pubmsg.qos = 2;
            pubmsg.retained = 0;
            sprintf(topic, "%s/%s/%d", project, client_id, from);

            reconnect(client, dest_addr, conn_opts);
            if ((rc = MQTTClient_publishMessage(client, topic, &pubmsg, &token)) != MQTTCLIENT_SUCCESS) {
              fprintf(stderr, "Publish failed: %d\n", rc);
              force_exit = 1;
            } else {
              if ((rc = MQTTClient_waitForCompletion(client, token, TIMEOUT)) == MQTTCLIENT_SUCCESS) {
                printf("Message with token %d delivered successfully\n", token);
              }
            }
          } else {
            Serial.print("receive failed\n");
          }
        }

#ifdef RF_IRQ_PIN
      }
#endif

#ifdef RF_LED_PIN
      // Led blink timer expiration ?
      if (led_blink && millis()-led_blink>200) {
        led_blink = 0;
        digitalWrite(RF_LED_PIN, LOW);
      }
#endif
      // Let OS doing other tasks
      // For timed critical appliation you can reduce or delete
      // this delay, but this will charge CPU usage, take care and monitor
      bcm2835_delay(5);
    }
  }
  MQTTClient_disconnect(client, 10000);
  MQTTClient_destroy(&client);

#ifdef RF_LED_PIN
  digitalWrite(RF_LED_PIN, LOW );
#endif
  printf( "\n%s ending\n", __BASEFILE__ );
  bcm2835_gpio_clr_ren(RF_IRQ_PIN);
  bcm2835_close();
  return 0;
}

Thank you!
Regards
Christian


text:
Int64_t aka long long acts as int32_t and overflows at 2^31
I have an int64_t variable. When I add another int64_t variable
and convert it to a double to print it on the serial monitor, it acts as if it was a int32_t variable. This is the program:
int64_t a = 1 << 31;
double b = static_cast<double>(a);
Serial.println(b);

The output on the serial monitor is -2147483648.00.
What is going on?

1 << 31 is interpreted by the compiler as (int)1 << (int)32.
See the implicit types of integer literals. The
rules of usual arithmetic conversions state that no implicit conversion
is performed in this case. The result is then computed as an int, and
it overflows. Note that this is undefined behavior. The assignment
int64_t a = ... converts the (already overflowed) result to the wider
type, without changing its value.
You probably want to write something like:
int64_t a = 1LL << 31;

even  uint32_t a = 1UL << 31; would do the trick to interpret 0x80000000 as a positive number.  BTW, on a real arduino, where the native int is an int16_t you get 1<<31 == 0

source: Stack Exchange

license: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/4.0/

sort: votes


text:
Teensy 2.0 MIDI: Number of notes in a chord limited to 6?
I am using the Teensy 2.0 with USBMidi in a project that allows musicians to use retro computers as "instruments" (https://github.com/fredlcore/midijoy). So far, all these computers had no more than four voices, so the problem I am encoutering now has not arisen so far.
When I now want to play a chord with more than six notes simultaneously, only the first six notes are received and played. However, if I release two from, let's say, eight notes, the remaining two notes are subsequently being played if these keys are still kept pressed.
Here is a script reduced to the bare minimum, when you press eight keys on the MIDI device one after another, you'll see that it stops after the sixth key, and when you then subsequently keep all keys pressed and release one after the other, you'll see that the "remaining" keys/notes will be received then:
void setup() {
  Serial.begin(38400);
  usbMIDI.setHandleNoteOn(doNote);
  usbMIDI.setHandleNoteOff(doNoteOff);
}

void loop() {
  usbMIDI.read();
}

void doNote(byte channel, byte pitch, byte velocity) {
  Serial.println(channel);
  Serial.println(pitch);
}

void doNoteOff(byte channel, byte pitch, byte velocity) {
  Serial.println(channel);
  Serial.println(pitch);
}

You have to configure the Teensy as a MIDI device so that the USBMidi libraries will be found.
Is there a hardware limit in the Teensy 2.0 that will prevent it from processing more than six notes at a time? Or is this a constraint within the library?

MIDI has no concept of chords. It's more likely whatever it is you're using to send the MIDI messages that can't cope with more than 6 note polyphony.

Connect the keyboard to a PC and run a MIDI monitor. I guess that you will see the same problem.

@Majenko pointed me to the root cause of the problem: I was sending MIDI notes via Ableton's feature of using the computer's keyboard. It seems that the OS (or the keyboard) cannot send/receive more than six simultaneous keystrokes.

It's OK to accept your own answer as the solution to the problem. You may have to wait for 48 hours before you can accept it.

That's a feature of USB keyboards. They have "N-key rollover" where N=6. I.e., the HID report has space for 6 keys in it.

@Majenko: Yes, that makes sense. Do you want to write up an answer yourself so I can accept it as a solution?

No, yours is good enough. Accept your own when the system lets you.

Ok, will do....

all_licenses: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/4.0/


text:
How to power Arduino pro mini and DFPlayer mini togather with 3.7 V LiPo battery?
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?

Just remember that a LiPo has 4.3V when it is full and ~3.0V when it is emty. If you have the 3.3V Arduino, you can connect it as it has an internal voltage regulator. the DFPlayer can work up to 5V. So you can connect both. What do you mean with longer time performance? 1 hour? 1 day? 1 week? Stand By? Power Off? When running? And last question: do you have also speakers connected on it (over the same LiPo?). You have to be more specific.

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.)


text:
Flash firmware with hex file over serial with Python (no avrdude, Arduino IDE)
I'm trying to make a Python function in the TCLab package to flash firmware to an Arduino Leonardo (32u4). I can compile the TCLab ino (firmware) and deploy with the Arduino IDE or with the Python avryp package. The Python avr_helpers package looks like a possible solution but is only supported with the older Python 2.7. Forum posts such as this one, 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 from a successful Arduino build. Here is an unsuccessful attempt to load the hex file with serial communication:
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. Can I update the firmware like the MATLAB Arduino Support Package that detects a new device and transfers the firmware automatically with user confirmation?

use baud rate of 9600 ... that should remove the possibility that 115200 is not supported

Thanks for the suggestion. I just tried baudrate of 9600 with ser2 = serial.Serial('COM9',9600) but it has the same result.

@jsotola, bootloader has baudrate set. 32u4 bootloader use 57600 baud.

The Leonardo uses the AVR109 protocol, not STK500.

http://ww1.microchip.com/downloads/en/AppNotes/doc1644.pdf

@Majenko, yes, I edited the comment as you wrote yours

the point is, there is some negotiation described in the protocol specification. you can't simply dump the hex to com port

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.
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"])

Thanks - this is helpful because it is much faster than using the Arduino IDE. I may go look at the AVRDUDE source (although it may not be pretty): https://stackoverflow.com/questions/37713905/flash-hex-file-to-arduino-via-terminal-without-avrdude


text:
Display GPS module data to my TFT display

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.
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.
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

Please do not include images of errors but include the full text. So, read what the error message says: "could not convert from 'void' to 'bool' ".... This gives a massive clue. You cannot use the output of gps.f_get_position(...), which is a void, inside an if statement, which expects something it can evaluate to a bool (i.e. a "true" or "false") to base its decision on.


text:
How can I make my custom board use the programmer selected in "Tools->Programmer" when the Upload button is pushed?
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).

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


text:
3-instruction remote machine coding Arduino Atmel chip over a serial line from a tethered (host) PC
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.
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
}

AVR chips use a so called “Harvard architecture”. A Web search for those terms should provide you some insight.

Thanks Edgar.  Are you suggesting separation of program and data memory is the reason why the xcall() function as written does not work?    I would have expected the use of function pointer to allow the C compiler to map to the correct assembly instruction to access the program memory (in Flash), i.e. agnostic to whether the chip has Harvard or von Neumann architecture.

The AVR is incapable of executing instructions from RAM. There is no physical pathway from the RAM to the CPU instruction decoder. It can only execute from flash. You would have to use code executing from the bootloader area (there are some bootloaders that provide that facility) to erase a page of flash then write the code into there. Or switch to a more capable MCU that can execute from RAM.

have you seen this? ... https://arduino-forth.com/

I'd heard about FlashForth, but this collection of articles by Marc Petremann (veteran Forth coder) is excellently written and should make it a snap to get started.  Thanks for sharing the link.

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.

I see! so the reason why xstore() and xfetch() worked was because I was injecting code into the mem[255] array, which is able to hold and return values as it is created in RAM.  But as it is unavailable to the Program Counter, this clears up why the xcall did not compile and the observation that the disassembled ELF file seemed to skip over the fGf() call.  Thanks much - accepting your answer!

For completeness, here's the link to Optiboot bootloader, and the MiniCore version for ATmega328.


text:
Serial.print() not fully printing
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);
}

How / Where do you see the output and the response?

@DataFiddler Arduino Serial Monitor

Could you provide a minimal, complete, reproducible example?
https://stackoverflow.com/help/minimal-reproducible-example

... please expand your code snippet to show this Serial Monitor output, too (at least). A minimal but complete test sketch were even better, of course.

Nothing in that code should print to the serial monitor. Show all your code.

@Majenko Ok Ok please wait a minute. till then sim800l is Software Serial library.

@Majenko Please See.

@FilipFranik Please see.

@DataFiddler Please see.

Thanks for the changed code: You send some commands to your sim800l. Then you try to read from Serial. If there should arrive anything, you return a few of those characters repeatedly forever.Your Serial.find will probably time out. Your Serial.readBytesUntil will probably timeout too, and will get you at most 17 characters.

BTW: warning: unknown escape sequence: '\+' in your readBytesUntil

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.

I do not want any  info from the commands. I just want to blindly issue the command. How can I empty the buffer?

Read it.  Or if you don't care what it returns why are you even bothering to display anything at all?

Because the last command, I want to read the AT+CCLK result. My module does not gets latest time. So the all commands are neccessary so that AT+CCLK returns correct date.

So you do want to read and interpret the responses then. At the very least you should be reading after every command and looking for either OK or ERR and discarding everything else.

I am very confused. If I open my own minimal reproducable example, there is no serial output. Then how come I was getting the output in my original code?

No idea. Write yourself a simple line-by-line reader / comparison routine that you can run after each command (except the one you're interested in) that returns a TRUE/FALSE result depending on if it finds OK or ERR. Do things properly from the start and things will be simpler later one.

Isn't there some command to empty Serial Buffer?

Yes. read. while (sim800l.available()) { sim800l.read(); }


text:
Attiny85 microcontroller programming without arduino
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?.

How about buying the Digispark USB Development board, which uses an Attiny85 and can be programmed via USB?

I use a “USBasp” ISP programmer. Those are cheap, compatible with avrdude, and more convenient than an Arduino running the ArduinoISP firmware. Beware there are some Chinese “USBISP” programmers (note the spelling) that are not compatible with avrdude.

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.
 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.

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.

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
Twelve PWM outputs from an ATtiny85.

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.

Is there a way to not use Arduino IDE for development, but just a text editor and compile from command line?

@rustyx: that's a great question - I see the original question can also be interpreted that way. I'll add another answer for that interpretation.

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 to compile source code into machine-code.
The avrdude program to install the compiled code onto the microcontroller.

All these can be obtained at zero cost.

Thanks! I've also found this and also this with links on how to debug and emulate AVR.


text:
little Code problem Servocity SPT 400 tilt kit
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.

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.

It is unclear to me, what the actual problem is. You didn't describe, what you expect the servo to do, and also not, what you are actually sending. Are you sending binary data or ASCII data? The external potentiometer has nothing to do with the code, since  the servo handles it. Have you connected the external potentiometer to the servos axis somehow? does the servo motor work correctly with the standard sweep example code?

Hi @chrisl. Oh well, I want that the servo turns up to 90 degree in both directions. I have tested another servo which is not connected the external potentiometer, On the Arduino board it makes the 180 degree turn, albeit becomes very warm. The servo, which is soldered to the external potentiometer doesn't make that much movement when connected to the Arduino. It worked a little in both directions, but that was not enough for the purpose. After I checked my soldering, I tried again. This servo now reacts on powering up but didn't move afterwards. I might have a servo defect?

you have not answered all of the questions ... how is the potentiometer connected to the servo mechanically?

Also looks like the servo is powered off the Arduino board.  That’s not a good idea.  It likely needs more current than is safe to provide there.  Motors and servos should not pull power off the arduino board unless you just want to fry boards.

@jsotola The instructions said to cut the connection inside the servo and connect them to the external potentiometer. link The thing looks like this link

@Delta_G Ok advice taken, I will change the setup :)


text:
Exit from for function after detecting obstacles
#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.

Did you try to break out of the loop?

No, i don't know how to use break here.. i have to break in for?

if( [some-condition] ) return;

Alternatively, calculate the brightness the blue led should be, based on time (millis()). E.g. rgb(0,0,(millis()/40)%256);

I don't understand how to use millis there..

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

Good answer as usual. Note that the for loop in C/C++ allows you to add additional checks, so you could also write the for loop as for (int i = start; i < end && condition; i += step) and get the same effect as the while loop, while also having the for loop manage the counter.

@DuncanC True ... and personally I don't like this concept, as it's like a while loop, written as a for loop. But it's personal. I have seen many professional projects using it this way (with the for). Personally I consider a for loop like an unconditional loop where beforehand the number of iterations is known, and a while loop as a conditional loop, where the number of iterations is not known beforehand. The break statement is kind of discussable in this sense. (But everything is better than a goto).

The condition of the while in my case should be if there is obstacles in front of sensor?

That depends on what your requirements are. If you want to break the loop based on some condition, use the condition you need. The while loop will stop when  condition is true, or you can use the not (!) operator (thus !condition) to stop the while` loop when the condition is false.

I noticed that the break happens ONLY after the end of the while loop and not at any time when there is obstacle in front of sensor, why this happens?

Assign the  condition you implemented to the variable condition and print it... It should change according to what you implemented.

No, i can't understand what kind of condition i need there. The only condition that stop the while loop should be something related to the distance from the sensor, (distance<=30) but i have used that on human() function...

Let us continue this discussion in chat.


text:
Trouble with basic communication between two NRF24L01 modules
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);
  }
}


text:
Ardiuno DUE board. Sketch uploading Error
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%20your%20Arduino%20Due%20on%20the%20Arduino%20Desktop%20IDE,the%20Arduino%20Boards%20Manager%20page.
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

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.


text:
delay() problem for 74HC595 and 7-segment
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 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). 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;
      }
    }
  }
}

So then don't use delay(). To do timed things, you need to learn a non-blocking coding style, like in the BlinkWithoutDelay example via the millis(). Look a the example and at tutorials about millis(). When you fully understand them, you will be able to replace the delay with non-blocking code

Thanks @chrisl. I already used of millis function. But it's useful for digital counting only like for making a digital clock. It's too bad for other applications like for DS18b20 temperature.

@soheil What are you talking about? I don't see, why millis()should be too bad to use here. delay() also just uses millis()in the background. And I also don't see how it should affect the temperature measurement. It is absolutely the way to go for handling the 1s delay there.

@chrisl This is a good question. Suppose that you have a DS18B20 temperature sensor. The sensor response time is about 0.5 sec (may be up to 0.75 sec). If you want to display it using 74HC595, during this time (exactly like a delay) the 7-segments are turned off! and after that they are turned on to display temperature. This appears like a flash (carefully watch the uploaded video). Some chips like MAX7219 doesn't interrupt the output when they don't have input (they run previous commands) while it seems that 74HC595 continuously needs the commands to keep the its output active.

@soheil So your problem is with the temperature sensor. Then you need to show a code, that really uses your temperature sensor. Currently you are asking about the 1s delay, for which Juraj provided a fitting answer. We can only understand how that might collude with the temp sensor, when we see the temp sensor code.

The 74HC595 doesn't need constant commands. If you stop shifting data out to it, it will keep the current state of the outputs. Though since you are reusing the same pins of it for all three digits, you need to constantly provide fitting data for each digit. That is not a property of the shift register, but of your circuit, which forms a matrix

If the 74HC595 sensor library you're using has delay() functions in it of more than a few milliseconds, you're going to have to modify your library function that reads the temp sensor to be non-blocking. (by following the model of blinkWithoutDelay.)

Either that or you are going to need to rewire your display to latch all 3 digits at once, and keep the whole display lit at once, or use a display driver that can multiplex all 3 digits automatically for you. You could use a MAX7221 for example. You'd feed the digits you need it to display using a serial interface, then read a new value from your temp sensor and feed the new value to the display driver. The display driver would continue to display the old value until the new value was sent.

@chrisl Thank you so much. But the temperature sensor is just one example which requires delay. Delay in my code simulates the raised problem of such usages. I can just say that how to avoid flashing in displaying numbers in such applications?

@chrisl Exactly. I think that one of the reasons is that in my code: first it should active the first digit and display its number and then inactive it and active the second digit and display its number and then inactive it and so on. This process should continuously be done to show all numbers without flashing. But, any delay (may be more than 20 ms) stops this process (of course for our eyes) and causes flashing in display. How do you think?

Thanks @Duncan-C. The delay is for sending and receiving data and can be up to 750 ms. MAX7219 and MAX7221 are great. Your idea is rewiring. How?

Remove the 74HC595 from your project and replace it with a Max7221 instead. The 7221 is able to drive up to 8 7-segment characters (plus decimals, for a total of 8 segments per character.) It is driven with a serial interface, so you send it commands to display values. A quick Google search reveals Arduino libraries for using it.

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

Thank you so much. But this isn't the correct answer! I already tried it. Please, carefully read the question.

Just a note, there is no temperature sensor or library included for one in the code presented.  For the question as presented this is the correct answer.  If there is some problem where your temperature sensor takes too long to read then that is a separate issue.  That's not the same as having a delay in your code.  Instead of trying to code around that time, fix the library for the sensor so it doesn't take so long.

delay() just simulates the required delay of such sensors. In real applications, this delay causes the flashing in display.

@soheil, I enhanced the answer

Thank you. I think changing chip is the best idea. I even used of two 74HC595 combined with ULN2803. But its result became worst. In fact, some segments of an inactive digit were a little bright!!!!!! 74HC595 can't handle the delay().

The use of millis() is suitable for digital clock, timer, ...

@soheil, with millis we do timed events. see this sketch https://github.com/jandrassy/lab/blob/master/KitchenTimer/KitchenTimer.ino

I updated your code based on millis().

@soheil, that code was wrong. you can't embed the timer inside 3 for loops. the main loop must run

I ran that and it worked fine. No problem.

@soheil, if that is all what your sketch should do, then it is ok

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.
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 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.)

Thank you. This strategy doesn't work properly! because if you do that, digits 1 and 2 are turned off until digit 0 counts from 0 to 9. Then digit 1 quickly displays number 1 and is turned off and again digit 0 counts from 0 to 9 and so on.

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. As another example, suppose that you need to call a php script using ESP8266 D1 Mini (it can similarly be programmed using Arduino IDE) and then display some returned numbers using 74HC595. Calling a php script may take over 15 s and during this time all digits are turned off.


text:
Using RX TX pin
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

can you be a bit more specific? do you mean pins 0 and 1?
What can't digital pin 2 do?

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.

and the component wired to this pins can interfere with sketch upload. and if one of this two stops working then no serial upload will be possible.

Oke , thank’s u so much


text:
Construct char arrays within function
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);
  }
}

In renderMenu() you are trying to create an array with the name output (which would hide the parameter of the function) with a variable size. That cannot work. Arrays created like this need sizes known at compile time. Otherwise you would need to use dynamic allocation (using new). Why aren't you just creating a simple char array inside of drawMenu()?

Also: because of the parameter of renderMenu() is hidden, the pointer lines is never set to anything valid. Thus printing the elements of it means reading from invalid memory location. There is just no array allocated behind that pointer

@chrisl, gcc can create an array on stack with a variable for size.

Thanks @chrisl, I value your help. I keep forgetting that arrays need to have a fixed size. So your saying that your first comment could be fixed by using char* lines[menuMaxLines] in drawMenu()? And your second question, I first trying to make that array of char arrays in the function but I was unable to return that and therefor went with the out var. Are you able to provide me with a solution to that?

@juraj, you assumed correctly. It’s a const int