text:
How do I get the size of my program at runtime?
(This question is specific for the Arduino Due, but maybe there's a general answer to the question)
I'm using DueFlashStorage to store application data in the flash memory of my Arduino Due. That works quite nicely. The Due has two flash blocks with 256k each. By default, the library writes data to the second flash block. The first flash block is used for the program. My program currently uses around 160k of flash (as the compiler tells me). That leaves about 96k of flash unused, which I could really use to store more application data. I managed to adjust DueFlashStorage to allow writing to the full memory range, but how do I detect where it is safe to write to? (Obviously, I must not overwrite any part of the program)
I have tried something like:
  // this returns the logical address of the first byte in flash (0x80000)
  byte* startAddr = dueFlashStorage.readAddress(0);
  Serial.println((unsigned int)startAddr, HEX);
  int bytes = 0;
  while (bytes < 512 * 1024) // That's the size of the flash
  {
    int* data = (int*)(startAddr + bytes);
    if (*data == 0xFFFFFFFF) // empty flash is initialized with FF's
     {
       Serial.print("Free block at 0x");
       Serial.println((unsigned int)data, HEX);
     }
     else
     {
       Serial.print("Used block at 0x");
       Serial.println((unsigned int)data, HEX);
     }
    bytes+=512;
  }

This seems to work, as the first block detected as "free" is just above the size of the program. However, this approach has some major drawbacks:

It's slow. Running over the whole address space to find the end of the program uses time (and maybe I shouldn't just test the first word of each block)
It's not reproducible. After I have written data to the detected first free block, it's no longer free, so I need another approach (like some magic number) to detect the first data block after the CPU is reset.

Is there a better way for this (like, in the ideal world, a constant I could use)? I don't want to hardcode the data start, because as the program grows (and it's still in development) I would forget to adjust that constant and booooommmm....

exact location far up in flash? you want to have the data on the same location even if the sketch size changes or not?

I'm using some (simple) memory management for allocating flash space for the data. I'm filling it up from bottom to top, much like if it was a file. So the addresses I'm using are relative to the start, but the start can move.

Just to warn you, I minimally tested this, but it seems to work.
In the Due's linker script there are these relevant lines, containing the named rom section.
MEMORY
{
    rom (rx)    : ORIGIN = 0x00080000, LENGTH = 0x00080000 /* Flash, 512K */

Below you'll see:
SECTIONS
{
    .text :
    {
        . = ALIGN(4);
        _sfixed = .;

_sfixed is a symbol they've created to mark the current location, which happens to be the start of the rom section in this case, 0x00080000.  At the bettom of the brace matching the one following .text, you'll see:
} > rom

showing that section goes into ROM, which is why . at the beginning of the .text section refers to the rom section start address.
If you look near the last thing placed in rom, you'll see:
    . = ALIGN(4);
    _etext = .;

So, they've set another symbol there, the one of interest, _etext, the address of which should be the byte of ROM not used, or so I thought the first time through this; turns out it isn't.  I gather you have no use for start of ROM symbol, since it's a static value and at the beginning, so I'll ignore that, but if you cared to make use of it it could be done the same way as follows for _etext.
These symbols don't have any type, but you can make them whatever you want.  If you want to perform arithmetic on a pointer that results, it makes sense to use a char type, so:
extern "C" unsigned char _etext;

I thought this was the end of the story, could just take the address of this symbol, but there is more to it.  Following the regular code is this section:
    .relocate : AT (_etext)
    {
        . = ALIGN(4);
        _srelocate = .;
        *(.ramfunc .ramfunc.*);
        *(.data .data.*);
        . = ALIGN(4);
        _erelocate = .;
    } > ram

They're placing code for the banzai (reset) function (and perhaps other things), which goes into ram ultimately, at this location in ROM.  So, presumably in the start code this is copied from the end of the normal program code into some place in ram.
So, there are two more symbols of interest here, _srelocate and _erelocate.  Declarations for them:
extern "C" unsigned char _srelocate;
extern "C" unsigned char _erelocate;

These symbols resolve to addresses in RAM, so they can't be used directly, but can have their addresses subtracted to get the size of the image in ROM that gets relocated to RAM, leading to:
const unsigned char *rom_end = &_etext + (&_erelocate - &_srelocate);
Serial.print("The end of used ROM is : 0x");
Serial.println((uintptr_t)rom_end, HEX);

When I compile and run a simple test like this and check the serial monitor connection, I see output like:
The end of used ROM is : 0x82FF8

If look at the .bin file produced by the compiler:
$ wc --bytes  build/arduino.sam.arduino_due_x_dbg/efixed.ino.bin
12280 build/arduino.sam.arduino_due_x_dbg/efixed.ino.bin

And 0x82FF8 - 0x80000 == 12280.
When I hex dump flash around this address I can see what looks like it padding out the flash sector with 0x00 bytes before the next unprogrammed flash sector shows as 0xFF.  So you would need to round this up yourself, and if you want be somewhat safer, maybe add some margin.
I don't know how common that configuration in the linker script is.  It's likely that most linker scripts place a symbol there, if they've had some forethought.  But I wouldn't necessarily expect it have the same name.  It's possible they modify it to add more stuff after that symbol.  But for now, for the Due, that would seem to work fine.  It is a bit messy though.

Wow, thanks for the concise analysis. Exactly what I was looking for. Seems to work nicely.

This is specific to the Arduino Due anyway (and it doesn't look like it's toolchain is going to be updated any time soon), so that's fine. If I port this code to another CPU (i.e. ESP32), I need to replace the whole flash part anyway.

Good deal. I had hoped to make the methodology fairly clear to allow future readers to react to changes in the linker script, or to apply the same thinking for a different Arduino, rather than offering a "just do this" type of answer.  Then again, it may also get ignored until heat death, but I thought it was an interesting question to look at. =)

Yea, I was just referring to the fact that https://github.com/arduino/ArduinoCore-sam is quite dead. Nobody seems to care about PRs or issues.


text:
Problems uploading arduino zero bootloader to atsamd21g18a
I am trying to upload the arduino zero bootloader (https://github.com/arduino/ArduinoCore-samd/tree/master/bootloaders/zero) to an atsamd21g18 breakout board that I made. The breakout has a 32KHz oscillator hooked to pins 1 and 2 (with 22pF caps). I have successfully done this twice before with two other atsamd21g18's, Atmel Studio, and an Atmel ICE as the programmer. These are the steps I followed the first two times:

Create a new GCC C executable project in Atmel Studio and chose ATSAMD21G18A as the device
Go to Tools->Device Programming, chose Atmel-ICE as tool, and SWD as interface
Go to Fuses, set USER_WORD_0.NVMCTRL_BOOTPROT to 0 Bytes, and hit Program
Go to Memories, select the file ArduinoCore-samd-master\bootloaders\zero\samd21_sam_ba.bin under the Flash option, and hit Program
Go back to Fuses, set USER_WORD_0.NVMCTRL_BOOTPRT to 8192 Bytes and hit Program

Then, I went to the Arduino IDE and was able to upload any sketches with Arduino Zero (programming port) chosen as the board and Atmel SAM-ICE as the programmer.
I have followed these same steps with the third samd21 chip. Eventually, all of the commands will go through. About 30% of the time when I click Program (in steps 2-5) I will get one of two errors:
Could not activate interface
Unable to enter programming mode. Verify device selection, interface settings, target power, security bit, and connections to the target device.
or
Erasing device failed.
However, if I just retry clicking Program it will not give any errors.
After following those steps with no errors in Atmel Studio, I go to the Arduino IDE and try uploading a basic blink sketch (with the same board and programmer selection as before), and the upload goes through (it says Done Uploading). However, the code does not execute. This is the code I am trying to upload:
const int ledPin =  6;

void setup() {
  // put your setup code here, to run once:
  pinMode(ledPin, OUTPUT);
  digitalWrite(ledPin, LOW);
}

void loop() {
  // put your main code here, to run repeatedly:
  digitalWrite(ledPin, HIGH);
  delay(1000);
  digitalWrite(ledPin, LOW);
  delay(1000);
}

This is the output I get after uploading the code:
Sketch uses 11444 bytes (4%) of program storage space. Maximum is 262144 bytes.
Global variables use 2188 bytes (6%) of dynamic memory, leaving 30580 bytes for local variables. Maximum is 32768 bytes.
Open On-Chip Debugger 0.10.0+dev-gf0767a31 (2018-06-11-13:36)
Licensed under GNU GPL v2
For bug reports, read
    http://openocd.org/doc/doxygen/bugs.html
debug_level: 0
none separate
adapter speed: 400 kHz
cortex_m reset_config sysresetreq
target halted due to debug-request, current mode: Thread
xPSR: 0x01000000 pc: 0x0000060c msp: 0x20007ffc
** Programming Started **
auto erase enabled
wrote 11520 bytes from file C:\Users\Michaela\AppData\Local\Temp\arduino_build_379254/blinky_samd21.ino.bin in 1.021138s (11.017 KiB/s)
** Programming Finished **
** Verify Started **
target halted due to debug-request, current mode: Thread
xPSR: 0x21000000 pc: 0x00000694 msp: 0x20007fdc
Error: error executing cortex_m crc algorithm
verified 11444 bytes in 0.999887s (11.177 KiB/s)
** Verified OK **
** Resetting Target **
shutdown command invoked

I have tried switching out the oscillator and led, uploading the bootloader and arduino sketch with and without the oscillator, simply hitting the Burn Bootloader command from the Arduino IDE, and even tried using openocd directly in the command line.
I do not believe this is an error with the specific samd21 chip I am using, because before I started messing with the bootloader, I uploaded a C sketch from Atmel Studio to blink the led, and it worked fine.
If anyone has any insight as to what could be going wrong, I would greatly appreciate it!

is the LED on the right pin?

I believe so. It is on pin 29 of the samd, which correlates to pin 6 in arduino.

source: Stack Exchange

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

sort: votes


text:
using RTOS SDK - crashes when adding another task
(I hope this is the right place to ask questions about the ESP8266_RTOS_SDK)
I have a program that I've taken from the samples directory (protocols/tcp_client) in the RTOS SDK and added code from the uart sample just so I can use the keyboard to tell the client when to start. The tcp_client task simply does a socket send to & recv from the server (a simple sockets server running on a linux desktop). It runs great until I tried to add another sample task:
 static void test_task(void *pvParameters)
    {
        vTaskDelay(MYDELAY2);
        ESP_LOGI(TAG, "asdf 123");
    }

And then, in the app_main(), I create the task:
xTaskCreate(test_task, "test", 2048, NULL, 10, NULL);

I try to run it and it either locks up and then crashes or just crashes as soon as it connects to the server. It usually crashes right after it prints out the message in the test_task.
 #include <string.h>
    #include <sys/param.h>
    #include "freertos/FreeRTOS.h"
    #include "freertos/task.h"
    #include "esp_system.h"
    #include "esp_log.h"
    #include "esp_netif.h"
    #include "esp_event.h"
    #include "protocol_examples_common.h"
    #include "nvs.h"
    #include "nvs_flash.h"
    #include "lwip/err.h"
    #include "lwip/sockets.h"
    #include "lwip/sys.h"
    #include <lwip/netdb.h>
    #include "freertos/queue.h"
    #include "driver/uart.h"

    #define HOST_IP_ADDR CONFIG_EXAMPLE_IPV4_ADDR
    #define MYDELAY1 (75 / portTICK_PERIOD_MS)
    #define MYDELAY2 (125 / portTICK_PERIOD_MS)
    #define MYDELAY3 (250 / portTICK_PERIOD_MS)
    #define MYDELAY4 (500 / portTICK_PERIOD_MS)
    #define MYDELAY5 (1000 / portTICK_PERIOD_MS)
    #define MYDELAY6 (2000 / portTICK_PERIOD_MS)
    #define MYDELAY7 (5000 / portTICK_PERIOD_MS)
    #define PORT CONFIG_EXAMPLE_PORT

    static const char *TAG = "example";
    #define EX_UART_NUM UART_NUM_0
    #define BUF_SIZE (1024)
    #define RD_BUF_SIZE (BUF_SIZE)
    static QueueHandle_t uart0_queue;
    unsigned char state;
    int sock;

    static void test_task(void *pvParameters)
    {
        vTaskDelay(MYDELAY2);
        ESP_LOGI(TAG, "asdf 123");
    }

    static void tcp_client_task(void *pvParameters)
    {
        char rx_buffer[128];
        char send_buff[100];
        char addr_str[128];
        int addr_family;
        int ip_protocol;
        int i = 0;
        char xbyte = 0x21;
        int len, err;

        struct sockaddr_in destAddr;
    //  destAddr.sin_addr.s_addr = inet_addr(HOST_IP_ADDR);
    // can set ip address either explicitly or using 'make menuconfig' and go to 'example      configuration'
        destAddr.sin_addr.s_addr = inet_addr("192.168.88.103");
        inet_ntoa_r(((struct sockaddr_in *)&destAddr)->sin_addr.s_addr, addr_str, sizeof(addr_str) -     1);
        ESP_LOGI(TAG, "address : %s", addr_str);
        destAddr.sin_family = AF_INET;
        destAddr.sin_port = htons(PORT);
        addr_family = AF_INET;
        ip_protocol = IPPROTO_IP;
        inet_ntoa_r(destAddr.sin_addr, addr_str, sizeof(addr_str) - 1);

        sock =  socket(addr_family, SOCK_STREAM, ip_protocol);
        if (sock < 0)
        {
            ESP_LOGE(TAG, "Unable to create socket: errno %d", errno);
            state = 51;
        }
        ESP_LOGI(TAG, "Socket created %d",sock);

        memset(send_buff,0,sizeof(send_buff));
        for(i = 0;i < 99;i++)
        {
            send_buff[i] = xbyte;
            if(++xbyte > 0x7e)
                xbyte = 0x21;
        }
        send_buff[99] = 0;

        ESP_LOGI(TAG,"press '1' to connect, then press '2' to start client, '3' to shutdown");

        while (1)
        {
            switch(state)
            {
                case 0:
                vTaskDelay(MYDELAY3);
                break;
            case 49:
                err = connect(sock, (struct sockaddr *)&destAddr, sizeof(destAddr));
                if (err != 0)
                {
                    ESP_LOGE(TAG, "Socket unable to connect: errno %d", errno);
                    close(sock);
                    vTaskDelay(MYDELAY1);
                    state = 0;
                }
                ESP_LOGI(TAG, "Successfully connected %d",err);
                state = 0;
                break;
            case 50:
                //ESP_LOGI(TAG, "starting...");

                err = send(sock, send_buff, 80, 0);
                if (err < 0)
                {
                    ESP_LOGE(TAG, "Error occured during sending: errno %d", errno);
                    state = 0;
                    break;
                }
                //ESP_LOGI(TAG,"send returned: %d",err);

                vTaskDelay(MYDELAY1);

                len = recv(sock, rx_buffer, 80, 0);
                // Error occured during receiving
                if (len < 0)
                {
                    ESP_LOGE(TAG, "recv failed: errno %d", errno);
                    state = 0;
                    break;
                }
                else
                {
                    rx_buffer[len] = 0; // Null-terminate whatever we received and treat like a string
                    //ESP_LOGI(TAG, "Received %d bytes from %s:", len, addr_str);
                    ESP_LOGI(TAG, "%s", rx_buffer);
                }

                vTaskDelay(MYDELAY1);

                if (sock == -1)
                {
                    ESP_LOGE(TAG, "Shutting down socket, press '1' to restart...");
                    shutdown(sock, 0);
                    close(sock);
                    state = 0;
                }
                break;
            case 51:
                ESP_ERROR_CHECK(example_disconnect());
                break;
            case 52:
                shutdown(sock,0);
                close(sock);
                ESP_LOGI(TAG,"shutdown - deleting task");
                vTaskDelete(NULL);
                break;
            default:
                ESP_LOGI(TAG,"press '1' to connect, then press '2' to start client %d",state);
                vTaskDelay(MYDELAY3);
                state = 0;
                break;
        }
    }
}
//#if 0
static void uart_event_task(void *pvParameters)
{
    uart_event_t event;
    int i;
    uint8_t *dtmp = (uint8_t *) malloc(RD_BUF_SIZE);

    for (;;) {
        // Waiting for UART event.
        if (xQueueReceive(uart0_queue, (void *)&event, (portTickType)portMAX_DELAY)) {
            bzero(dtmp, RD_BUF_SIZE);
            //ESP_LOGI(TAG, "uart[%d] event:", EX_UART_NUM);

            switch (event.type) {
                // Event of UART receving data
                // We'd better handler data event fast, there would be much more data events than
                // other types of events. If we take too much time on data event, the queue might be full.
                case UART_DATA:
                    ESP_LOGI(TAG, "[UART DATA]: %d", event.size);
                    uart_read_bytes(EX_UART_NUM, dtmp, event.size, portMAX_DELAY);
                    state = dtmp[0];
                    ESP_LOGI(TAG,"state: %d",state);
//                    uart_write_bytes(EX_UART_NUM, (const char *) dtmp, event.size);
                    break;

                // Event of HW FIFO overflow detected
                case UART_FIFO_OVF:
                    ESP_LOGI(TAG, "hw fifo overflow");
                    // If fifo overflow happened, you should consider adding flow control for your application.
                    // The ISR has already reset the rx FIFO,
                    // As an example, we directly flush the rx buffer here in order to read more data.
                    uart_flush_input(EX_UART_NUM);
                    xQueueReset(uart0_queue);
                    break;

                // Event of UART ring buffer full
                case UART_BUFFER_FULL:
                    ESP_LOGI(TAG, "ring buffer full");
                    // If buffer full happened, you should consider encreasing your buffer size
                    // As an example, we directly flush the rx buffer here in order to read more data.
                    uart_flush_input(EX_UART_NUM);
                    xQueueReset(uart0_queue);
                    break;

                case UART_PARITY_ERR:
                    ESP_LOGI(TAG, "uart parity error");
                    break;

                // Event of UART frame error
                case UART_FRAME_ERR:
                    ESP_LOGI(TAG, "uart frame error");
                    break;

                // Others
                default:
                    ESP_LOGI(TAG, "uart event type: %d", event.type);
                    break;
            }
        }
    }
    free(dtmp);
    dtmp = NULL;
    vTaskDelete(NULL);
}
//#endif

void app_main()
{
    ESP_ERROR_CHECK(nvs_flash_init());
    ESP_ERROR_CHECK(esp_netif_init());
    ESP_ERROR_CHECK(esp_event_loop_create_default());

    ESP_ERROR_CHECK(example_connect());
        uart_config_t uart_config = {
        .baud_rate = 115200,
        .data_bits = UART_DATA_8_BITS,
        .parity = UART_PARITY_DISABLE,
        .stop_bits = UART_STOP_BITS_1,
        .flow_ctrl = UART_HW_FLOWCTRL_DISABLE
    };
    uart_param_config(EX_UART_NUM, &uart_config);

    // Install UART driver, and get the queue.

    uart_driver_install(EX_UART_NUM, BUF_SIZE * 2, BUF_SIZE * 2, 100, &uart0_queue, 0);

    xTaskCreate(test_task, "test", 2048, NULL, 10, NULL);

    xTaskCreate(uart_event_task, "uart_event_task", 2048, NULL, 12, NULL);

    xTaskCreate(tcp_client_task, "tcp_client", 2048, NULL, 5, NULL);
}

When I added the task for the uart it works, but when I add the task to print the test message and do the time delay, it crashes.

I didn't have the task as an infinite loop. It should be:
static void test_task(void *pvParameters)
{
    while(1)
    {
        vTaskDelay(MYDELAY6);
        ESP_LOGI(TAG, "test 123");
     }
}

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


text:
Simple LCD countdown timer
I tried to modify the basic "hello-world" sketch for the LCD that is a part of the examples section in the IDE. I intended to make a countdown timer using the LCD.
The original code simply prints "Hello World" in the first line, and then makes use of the millis() function to print the time elapsed in the next line.
So I tried a simple modification to make it count down from 20. Instead of printing millis()/1000 , I printed 20-millis()/1000, and also added a while() to only print till millis()<=20,000. (so that it does not go beyond 00)
#include <LiquidCrystal.h>

LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

void setup() {

  lcd.begin(16, 2);

  lcd.print("time left");
}

void loop() {

  while(millis()<=20000){

    lcd.setCursor(0, 1);

    lcd.print(20- millis() / 1000);
  }

}

It seemed to work till 10. but instead of 9, it printed 90, and likewise 80,70.. for 8,7...etc till 00.
How can I get rid of these extra zeros?

lcd.print(' ');

where do I put this?

instead of 9, it printed 90

No, it didn't: it printed “9”. However, it did not erase the previous
value before printing “9”. Before printing the 9, the LCD had:
┌────────────────┐
│time left       │
│10              │
└────────────────┘
 ^cursor position

When you printed “9”, that character replaced the “1”, and you end up
seeing “90”.
The fix, as pointed out by Juraj, is to add a space after printing the
numbers.
An alternative is to prepend a space (or a zero), but only when the
number to be displayed is less that 10:
int count = 20 - millis() / 1000;
if (count < 10)
    lcd.print(' ');  // alternatively: '0'
lcd.print(count);


text:
Multiple MQTT topics
I have 3 nodemcu's(ESP32) each connected with a sensor, from which I get data and send it to aws IoT-core. How can I send all 3 sensor's data by a single MQTT subscription? The below code is for a single MQTT using one nodemcu.
#include "SPIFFS.h"
#include <WiFiClientSecure.h>
#include <Wire.h>
#include <PubSubClient.h>

float V_0 = 5.0; // supply voltage to the pressure sensor
float rho = 1.204; // density of air

// parameters for averaging and offset
int offset = 0;
int offset_size = 10;
int veloc_mean_size = 20;
int zero_span = 2;

const char* ssid = ""; //Provide your SSID
const char* password = "";          // Provide Password
const char* mqtt_server = "a3mtl8k0aiowyx-ats.iot.us-east-2.amazonaws.com"; // Replace with your MQTT END point
const int mqtt_port = 8883;

String Read_rootca;
String Read_cert;
String Read_privatekey;
//=============================================================================================================================
#define BUFFER_LEN  256
long lastMsg = 0;
char msg[BUFFER_LEN];
int value = 0;
byte mac[6];
char mac_Id[18];
int count = 1;
int id=1;
//=============================================================================================================================

WiFiClientSecure espClient;
PubSubClient client(espClient);

void setup_wifi() {
  delay(10);
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);

  WiFi.begin(ssid, password);

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

  randomSeed(micros());

  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
}

void callback(char* topic, byte* payload, unsigned int length) {
  Serial.print("Message arrived [");
  Serial.print(topic);
  Serial.print("] ");
  for (int i = 0; i < length; i++) {
    Serial.print((char)payload[i]);
  }
  Serial.println();
}
void reconnect() {
  // Loop until we're reconnected
  while (!client.connected()) {
    Serial.print("Attempting MQTT connection...");
    // Create a random client ID
    String clientId = "ESP32-";
    clientId += String(random(0xffff), HEX);
    // Attempt to connect
    if (client.connect(clientId.c_str())) {
      Serial.println("connected");
      // Once connected, publish an announcement...
      //client.publish("ei_out", "connection success");
      // ... and resubscribe
      client.subscribe("ei_in");
    } else {
      Serial.print("failed, rc=");
      Serial.print(client.state());
      Serial.println(" try again in 5 seconds");
      // Wait 5 seconds before retrying
      delay(5000);
    }
  }
}

void setup() {
  Serial.begin(115200);
    for (int ii=0;ii<offset_size;ii++){
    offset += analogRead(34)-(1023/2);
  }
  offset /= offset_size;
  Serial.setDebugOutput(true);
  // initialize digital pin LED_BUILTIN as an output.
  pinMode(2, OUTPUT);
  setup_wifi();
  delay(1000);
  //=============================================================
  if (!SPIFFS.begin(true)) {
    Serial.println("An Error has occurred while mounting SPIFFS");
    return;
  }
  //=======================================
  //Root CA File Reading.
  File file2 = SPIFFS.open("/AmazonRootCA1.pem", "r");
  if (!file2) {
    Serial.println("Failed to open file for reading");
    return;
  }
  Serial.println("Root CA File Content:");
  while (file2.available()) {
    Read_rootca = file2.readString();
    Serial.println(Read_rootca);
  }
  //=============================================
  // Cert file reading
  File file4 = SPIFFS.open("/9bcef01134-certificate.pem.crt", "r");
  if (!file4) {
    Serial.println("Failed to open file for reading");
    return;
  }
  Serial.println("Cert File Content:");
  while (file4.available()) {
    Read_cert = file4.readString();
    Serial.println(Read_cert);
  }
  //=================================================
  //Privatekey file reading
  File file6 = SPIFFS.open("/9bcef01134-private.pem.key", "r");
  if (!file6) {
    Serial.println("Failed to open file for reading");
    return;
  }
  Serial.println("privateKey File Content:");
  while (file6.available()) {
    Read_privatekey = file6.readString();
    Serial.println(Read_privatekey);
  }
  //=====================================================
  char* pRead_rootca;
  pRead_rootca = (char *)malloc(sizeof(char) * (Read_rootca.length() + 1));
  strcpy(pRead_rootca, Read_rootca.c_str());

  char* pRead_cert;
  pRead_cert = (char *)malloc(sizeof(char) * (Read_cert.length() + 1));
  strcpy(pRead_cert, Read_cert.c_str());

  char* pRead_privatekey;
  pRead_privatekey = (char *)malloc(sizeof(char) * (Read_privatekey.length() + 1));
  strcpy(pRead_privatekey, Read_privatekey.c_str());

  Serial.println("================================================================================================");
  Serial.println("Certificates that passing to espClient Method");
  Serial.println();
  Serial.println("Root CA:");
  Serial.write(pRead_rootca);
  Serial.println("================================================================================================");
  Serial.println();
  Serial.println("Cert:");
  Serial.write(pRead_cert);
  Serial.println("================================================================================================");
  Serial.println();
  Serial.println("privateKey:");
  Serial.write(pRead_privatekey);
  Serial.println("================================================================================================");

  espClient.setCACert(pRead_rootca);
  espClient.setCertificate(pRead_cert);
  espClient.setPrivateKey(pRead_privatekey);

  client.setServer(mqtt_server, mqtt_port);
  client.setCallback(callback);

  //====================================================================================================================
  WiFi.macAddress(mac);
  snprintf(mac_Id, sizeof(mac_Id), "%02x:%02x:%02x:%02x:%02x:%02x",
       mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
  Serial.print(mac_Id);
  //=====================================================================================================================
}

void loop() {
    float adc_avg = 0;
    float veloc = 0.0;

// average a few ADC readings for stability
  for (int ii=0;ii<veloc_mean_size;ii++){
    adc_avg+= analogRead(34)-offset;
  }
  adc_avg/=veloc_mean_size;

  // make sure if the ADC reads below 512, then we equate it to a negative velocity
  if (adc_avg>512-zero_span and adc_avg<512+zero_span){
  } else{
    if (adc_avg<512){
      veloc = -sqrt((-10000.0*((adc_avg/1023.0)-0.5))/rho);
    } else{
      veloc = sqrt((10000.0*((adc_avg/1023.0)-0.5))/rho);
    }
  }
//  Serial.println(veloc); // print velocity
//  delay(10); // delay for stability
  //===============================================

  if (!client.connected()) {
    reconnect();
  }
  client.loop();

  long now = millis();
  if (now - lastMsg > 5000) {
    lastMsg = now;
    //=============================================================================================
    //String macIdStr = mac_Id;
    String sensor_id=String(id);
    String Velocity = String(veloc);
    snprintf (msg, BUFFER_LEN, "{\"sensor_id\" : \"%s\", \"Velocity\" : \"%s\"}", sensor_id.c_str(), Velocity.c_str());
    //"{\"mac_Id\" : \"%s\", \"Velocity\" : %s, \"sensor_id\" : \"%s\"}"
    Serial.print("Publish message: ");
    Serial.print(count);
    Serial.println(msg);
    client.publish("ei_out", msg);
    count = count + 1;
    //================================================================================================
  }
  digitalWrite(2, HIGH);   // turn the LED on (HIGH is the voltage level)
  delay(1000);                       // wait for a second
  digitalWrite(2, LOW);    // turn the LED off by making the voltage LOW
  delay(1000);                       // wait for a second
}

ei_out is the topic I have subscribed in iot-core,
I wish to have one more ei_out_1 from another nodemcu

ei_out is the topic I have subscribed in iot-core, I wish to have one more ei_out_1 from another nodemcu -- So... have another called ei_out_1...? I don't understand what you're asking. If you want to send to a different topic then send to a different topic.

How can I send all 3 sensor's data by a single MQTT subscription? .... same way that you would place three words on one piece of paper? .... BTW, data is sent by publishing,  subscription is for receiving data

You're not subscribing to ei_out but only to a topic called ei_in (defined in reconnect()). What you want is to publish. At the moment, you're using only ei_out to publish (client.publish("ei_out") in loop()). You can freely create additional topics (with different names than "ei_out") to publish data from other sensors.

Publishing has to have an explicit topic. Subscribing has two wild cards # which means anything below this level in the hierarchy and + which means anything at the next level of the hierarchy. The division between hierarchical levels is the / character. So if sensor one publishes on sensor/1/out/temp1 and sensor two publishes on sensor/2/out/temp1 you can subscribe to sensor/+/out/temp1 to read from both sensors. You can subscribe on sensor/1/out/+ to read anything sent by sensor one. You can subscribe to sensor/# to read any output from any sensor.

change ei_out and ei_out_1 to ei/out and ei/out/1 to get the benefits of the hierarchical topic structure. The only hard part of this stuff is designing a sensible and coherent hierarchy for your topics.


text:
Float switch is not detected

Good day everyone, forgive me for the shabby drawing I am just panicking, why my float switches are suddenly undetected by my Arduino mega. I've tested all the float switches one by one to confirm if everything is working just before installing it..
i have 18 sets of float switches, 5 pumps being controlled by the relay, my main PSU is 12V 20A.
The yellow rectangle stands for the float switch, the purple line is connected to digital pins from between and 10k ohm resistor and the switch. the green line is a common ground connection from the 5.2V buck (psu for devices that need 5 to 5.5v) to the Arduino mega's gnd.
here's my code, and its not the project code, just a simple test sketch because my float switches are suddenly acting weird:
#include <OneWire.h>
#include "OneButton.h"
#include <DallasTemperature.h>
#include "GravityTDS.h"
#include <EEPROM.h>
#include "Wire.h" // Include the I2C Wire Library
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27,20,4);

#define bp1 (uint8_t) 10 /*Button 1*/
#define bp2 (uint8_t) 11 /*Button 2*/
#define bp3 (uint8_t) 12 /*Button 3*/

OneButton btn1 = OneButton(bp1,false,false); uint8_t bx1 = 0;
OneButton btn2 = OneButton(bp2,false,false); uint8_t bx2 = 0;
OneButton btn3 = OneButton(bp3,false,false); uint8_t bx3 = 0;

//Float Switches...........
/*Collector Float Switch*/
#define CT_Fs2 (uint8_t) 9

/*Sieve & Cloth*/
#define SC_Fs1 (uint8_t) 8

/*Primary Test Tank*/
#define PT_Fs1 (uint8_t) 7
#define PT_Fs2 (uint8_t) 6

/*Grease Trap*/
#define GT_Fs1 (uint8_t) 5

/*First Filtration*/
#define FFP_Fs1 (uint8_t) 4
#define FFP_Fs2 (uint8_t) 3

/*Sediment Filter*/
#define SD_Fs1 (uint8_t) 2

/*Second Filtration Passed*/
#define SP_Fs1 (uint8_t) 24
#define SP_Fs2 (uint8_t) 25

/*Final Test Tank*/
#define FT_Fs1 (uint8_t) A7
#define FT_Fs2 (uint8_t) A8

/*Tank A*/
#define TA_Fs1 (uint8_t) 45
#define TA_Fs2 (uint8_t) 47

/*Tank B*/
#define TB_Fs1 (uint8_t) 42
#define TB_Fs2 (uint8_t) 43

/*Tank C*/
#define TC_Fs1 (uint8_t) 40
#define TC_Fs2 (uint8_t) 41

void setup()
{
  Serial.begin(9600); /* Show Serial Monitor */
  lcd.begin(); /* LCD Screen Set Up */

//---------------------------------------------------------------------dont forget to set up the pins
//ALL DIGITAL PINS ARE INPUT AS DEFAULT, DECLARE ONLY IF MODE IS OUTPUT:
  pinMode(FT_Fs1,INPUT);
  pinMode(FT_Fs2,INPUT);

//----------------------------------------------------------------------One Button Single Click event attachment
  btn1.attachClick(handleClick1);
  btn2.attachClick(handleClick2);
  btn3.attachClick(handleClick3);

}

//simple show txt on LCD Screen
void lcd_print(String txt ,uint8_t a, uint8_t b)
{ lcd.setCursor(a,b); lcd.print(txt);}

void loop()
{
  FSTester();
}

void FSTester() // to check FLOAT SWITCH
{
  if (digitalRead(CT_Fs2) == 1)
  {
    lcd.clear();
    lcd_print("CT_Fs2 Detected",0,1);
    delay(5000);
  }
  else if (digitalRead(SC_Fs1) == 1)
  {
    lcd.clear();
    lcd_print("SC_Fs1 Detected",0,1);
    delay(5000);
  }
  else if (digitalRead(PT_Fs1) == 1)
  {
    lcd.clear();
    lcd_print("PT_Fs1 Detected",0,1);
    delay(5000);
  }
  else if (digitalRead(PT_Fs2) == 1)
  {
    lcd.clear();
    lcd_print("PT_Fs2 Detected",0,1);
    delay(5000);
  }
  else if (digitalRead(GT_Fs1) == 1)
  {
    lcd.clear();
    lcd_print("GT_Fs1 Detected",0,1);
    delay(5000);
  }
  else if (digitalRead(FFP_Fs1) == 1)
  {
    lcd.clear();
    lcd_print("FFP_Fs1 Detected",0,1);
    delay(5000);
  }
  else if (digitalRead(FFP_Fs2) == 1)
  {
    lcd.clear();
    lcd_print("FFP_Fs2 Detected",0,1);
    delay(5000);
  }
  else if (digitalRead(SD_Fs1) == 1)
  {
    lcd.clear();
    lcd_print("SD_Fs1 Detected",0,1);
    delay(5000);
  }
  else if (digitalRead(SP_Fs1) == 1)
  {
    lcd.clear();
    lcd_print("SP_Fs1 Detected",0,1);
    delay(5000);
  }
  else if (digitalRead(SP_Fs2) == 1)
  {
    lcd.clear();
    lcd_print("SP_Fs2 Detected",0,1);
    delay(5000);
  }
  else if (digitalRead(FT_Fs1) == 1)
  {
    lcd.clear();
    lcd_print("FT_Fs1 Detected",0,1);
    delay(5000);
  }
  else if (digitalRead(FT_Fs2) == 1)
  {
    lcd.clear();
    lcd_print("FT_Fs2 Detected",0,1);
    delay(5000);
  }
  else if (digitalRead(TA_Fs1) == 1)
  {
    lcd.clear();
    lcd_print("TA_Fs1 Detected",0,1);
    delay(5000);
  }
  else if (digitalRead(TA_Fs2) == 1)
  {
    lcd.clear();
    lcd_print("TA_Fs2 Detected",0,1);
    delay(5000);
  }
  else if (digitalRead(TB_Fs1) == 1)
  {
    lcd.clear();
    lcd_print("TB_Fs1 Detected",0,1);
    delay(5000);
  }
  else if (digitalRead(TB_Fs2) == 1)
  {
    lcd.clear();
    lcd_print("TB_Fs2 Detected",0,1);
    delay(5000);
  }
  else if (digitalRead(TC_Fs1) == 1)
  {
    lcd.clear();
    lcd_print("TC_Fs1 Detected",0,1);
    delay(5000);
  }
  else if (digitalRead(TC_Fs2) == 1)
  {
    lcd.clear();
    lcd_print("TC_Fs2 Detected",0,1);
    delay(5000);
  }
  else
  {
    lcd.clear();
    lcd_print("NOTHING",0,1);
  }
}

I've checked for continuity and everything is fine. why is it weird?
somebody please correct my mistakes

"suddenly acting weird" doesn't give us much to go on. I'd suggest trying a small fragment of your code that only uses one float switch and get that working. Then add in the rest of them (with any modifications you might have had to make for the first one). Is it possible that the switches work in the opposite sense from which your testing them? You're testing for HIGH - are they in fact switching to LOW? Otherwise, we'll need to know what you expected your code to do, and what it is doing instead. And it will still be helpful to reduce it to just one relay - i.e. the simplest case that fails.

What is the yellow component in your drawing and what are the green/purple connection?

What is the reason, that you are using an additional buck power supply for - what I assume from your drawing - are just simple switches? Why not just directly using the Arduinos 5V pin for that?

Your diagram is almost impossible to follow. Can you sketch out the actual wiring without using coloured boxes, etc? In particular the part about the switch. We assume you are supplying power to the various devices, you don't need to show that. Possibly the inputs to your switch are "floating" (that is, indeterminate) in either the open or closed position.

See my page about switches and if that helps I can make an answer along those lines (if there isn't one already which there probably is).

It is difficult to determine from the diagram if the green wire is at the same voltage as the black wire supplying power to the Arduino board. Even if they are connected, it is difficult to say if the current is nominal. As there is a power supply of unknown design involved for both the Arduino and the float switch.
This could cause unexpected results and may even permanently damage sensitive parts.  Consider using a design with only one power supply thereby mitigating the risk of unexpected results.

The assumption is that your code, sensors and pump all worked together at one point ("on the test bench").  So the code probably works.  And only after you installed it and ran it for a while did you notice that it fails.  Is that correct?

You're new @princessbubbles15. If the above answers your question select it as the correct answer. If you want to wait and try it fist to see if it works that's ok too. Or write a comment/question here if something is not clear and I'll edit the answer. Feel free to edit your question too if you find you forgot to ask something in particular.


text:
Servo noise during program flash on Arduino
I'm running serveral servos using a driver A4988 and external power supply. Everything works fine.
I've just noticed one issue that I can't explain.
As soon as I upload a new program version on my arduino uno, while the external power supply is one, the servo makes some strange noises. After the upload has finished, the noise disappears.
Without any further details, can you explain this behavior? Does the arduino set some Pins to HIGH during flashing?
Thanks!

It would depend on which Arduino and what bootloader it's running.  Generally MCUs have their pins in INPUT mode when they reset.  Sometimes the bootloader will leave some pins configured for a particular mode by the some the sketch runs.  E.g. the Leonardo seems to leave pin 13 set to OUTPUT mode.
You usually want devices connected to your Arduino to have stable signals when the Arduino MCU is in reset, or in the bootloader, so it makes sense to pull the signal pins, that will later be output from the Arduino sketch, to known levels.  So maybe pulling your servo driver enable signal to inactive (HIGH) is appropriate.
Looking at the A4988, it has an EN (enable) pin, which seems to be active low.  So putting a high(ish) value resistor, say 5k or 10k, on it to VDD/HIGH (to inactive) is probably the thing to do.  When the Arduino is not driving the enable line to its low (active) state, that is when it's in the bootloader or being held in reset, the A4988 should stop its activity.

Can you explain what you mean with "Pulling servo signal to ground" ?

First time through, I'd been thinking of a typical hobby servo.  I've changed the wording there to be correct (I think) for the A4988 driver.  The basic idea is the same, when the MCU is not strongly influencing the signal (any signal really, the driver enable signal in this case) a resistor can be used to weakly influence the pin to the default level.


text:
How to calculate required amperage of multiple motors?
I a very simple question about calculating the amperage I need to run 5 stepper motors from my Arduino Uno.
If I have 5 28BYJ-48 stepper motors(which are 5V and are said to require about 240mA each) all plugged into 5 separate ULN2003 driving boards, and I wire 4 signal wires from the boards to the Arduino, and connect the two power wires for the board to 5V and GND on the Arduino. What voltage and amperage I need to supply to my Arduino for everything to run properly?
I'm worried because I read that the Arduino cannot handle over one amp but 0.24*5>1, although I don't know if the amperage is additive with each additional motor.
Thanks for any answers!

your question is not about the arduino ... it is off topic here

I don't know if the amperage is additive with each additional motor

Yes, amperage is additive.

the Arduino cannot handle over one amp but 0.24*5>1

That is correct. But the stepper motors should never be powered through the Arduino. You should connect a fitting power supply directly to the stepper drivers. That way the needed current flows past the Arduino, not through it.

What voltage and amperage I need to supply to my Arduino for everything to run properly?

The Arduino runs at 5V, though you can provide 7-12V to Vin/barrel jack. When your motors are rated for 5V, you should provide them with 5V. So it would be fitting to buy one 5V power source to power the Arduino (through the 5V pin or USB) and the stepper drivers.
For the current: A good measure is the stall current of a motor, so the current, that flows, when the motor is driven, but cannot move (due to being physically stuck). Add a bit headroom to this. The mentioned motors are often badly documented, so that you might not be able to find a stall current value. Add more headroom in that case. So I would suggest adding up all the amps and then multiply this value with 1.5 or even 2. Let's take 250mA per motor (for ease of calculation) with 5 motors gives 1.25A. Take at least a 2A power supply. When you want to make sure go directly to 3A. The price difference in that range isn't that much anyway.

Super helpful thanks lot

You said it would be fitting to have a single 5V/2-3A power source for both the Arduino and the motors but can't the Arduino not take over 1A

@KidWithComputer Current is different than voltage. While you need to provide a specific voltage, the current of a power supply is only a maximum, that it can supply. The Arduino will only draw the current, that it needs to work, from the power supply. You could easily use a power supply capable of hundreds of amps, it would still work. The 1A current limit is actually meant for the situations, where you power components through the Arduino, so the current is flowing through it and its components and PCB traces can only handle max current. But this current would be drawn by other components.


text:
Converting ESP32 SPI code to Arduino for MAX6921 IV-18 driver board
I purchased a IV-18 VFD tube driver module, which came with some example code for an ESP32 board. The driver module has a 20 output MAX6921 serial chip to drive the vacuum tube. I want to use this driver module with an Arduino Uno and then eventually a Raspberry Pi.
I think I have a very rough understanding of the electronics and demo code, but cannot seem to get my SPI calls to work. Rather than trying to translate the demo code in its entirety, my first goal is to just get one segment to light up.
Quick background
The IV18 tube has 9 grids. The first grid has only a dot and a dash, but the remaining 8 grid have 7 segments and a decimal point.

To light a segment, you provide power to the segment pins / decimal point and to the grid for that segment. To display several numbers, you have to quickly cycle through lighting each of the grid positions and the relevant segments for that position. If you cycle through this fast enough, the human eye sees the whole grid with numbers (persistence of vision).
What I have tried
So far, I have made the connections from the Arduino Uno to the driver board
Driver GND   - Uno GND
Driver 5V    - Uno +5V
Driver Din   - Uno digital pin 11 / MOSI
Driver CLK   - Uno digital pin 13 / SCK
Driver LOAD  - Uno digital pin 2
Driver BLANK - Uno digital pin 3
Driver Dout  - Not connected

The example code has hex codes which I believe are then translated to a 24 bit buffer (although only 17 bits are required) to send via SPI to set the MAX6921 outputs HIGH or LOW.
I think the bits required are as follows:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

G7
G6
G5
G4
G3
G2
G1
G0
SEG_G
SEG_F
SEG_E
SEG_D
SEG_C
SEG_B
SEG_A
SIGN

DP

So to light the number 8 in the righthand most grid, I assumed I'd need the 8th bit high (grid) and bits 9,10,11,12,13,14 and 15 for the 7 semens for the "8".
In my setup function, I call SPI.begin and then SPI.transfer with what I assumed was the matching binary data (from right to left, I think because of the bit order LSB/MSB?):
SPI.transfer(0b000000000111111110000000);
This lights the first grid (the one after the degree and minus sign) but not what I want - I see some segments in the leftmost grid (the full grid, not the grid with the dot and minus) but these light in a different pattern each time  (varies each time I reset or re-upload which I think is to be expected as I'm pushing data to the MAX6921 each time).
This is my code so far
#include "SPI.h"

#define DISP_CLK 13   // White - SPI SCK
#define DISP_DATA 11  // Yellow - SPI MOSI
#define DISP_LOAD 2   // Blue
#define DISP_BLANK 3  // Green

void setup() {
  Serial.begin(9600);
  Serial.println("IV18 Test");

  SPI.begin();

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

  pinMode(DISP_LOAD, OUTPUT);
  digitalWrite(DISP_LOAD, HIGH);

  SPI.transfer(0b000000000111111110000000);
}

void loop() {

}

I'm pretty sure the two fundamental things I have wrong here are the bits of data to send and then the correct use of the SPI.
Can someone please help me to understand the ESP32 code properly, and ideally help me get the correct data to send via SPI so that I can light up the segments & grid positions that I expect to.

SPI.transfer() does only serve the clock and write/read MOSI/MISO. It does not bring the CS low to select the SPI slave.

So it turns out that I got a few things wrong.
UPDATE: Working code is now on my GitHub if anyone is interested.
Firstly, I misunderstood the example code and made a mess of the bits to send to the MAX6921. To work out the correct mapping, I went and probed each pin of the IV-18 and noted the connection to the pins / outputs of the MAX6921 which gave me this table:

BIT
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

IV-18
G9
G8
G7
G6
G5
G4
G3
G2
G1
A
B
C
D
E
F
G
DP

MAX6921
0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

Note that the MAX6921 value is the OUTPUT number and not the PIN number
This then gave me the correct order for each bit to send, as noted in the top row of the table.
The next mistake was trying to send all 24 bits in one go. Instead, I broke each byte into a separate SPI.transfer() call which finally let me display the segments in the grid position that I expected.
For example, to display "HELLO", my loop function has this:
void loop() {
  //             XXXXXXXDP                 GFEDCBA1                  23456789
  SPI.transfer(0b00000000); SPI.transfer(0b11101100); SPI.transfer(0b10000000); delay(1);
  SPI.transfer(0b00000000); SPI.transfer(0b11110010); SPI.transfer(0b01000000); delay(1);
  SPI.transfer(0b00000000); SPI.transfer(0b01110000); SPI.transfer(0b00100000); delay(1);
  SPI.transfer(0b00000000); SPI.transfer(0b01110000); SPI.transfer(0b00010000); delay(1);
  SPI.transfer(0b00000001); SPI.transfer(0b01111110); SPI.transfer(0b00001000); delay(1);
}

I have setup TIMER1 to use instead of the loop/delay code, so hopefully I can finish converting the rest of the example code to Arduino.


text:
pH code of Arduino SEN0169 refuses to output
Good day everyone!
I'm making my research project a hydroponics sensor that collects air and water temperature, humidity, conductivity, and pH, then sends it through a sim900a GSM module. However, when testing it out, the pH part of the code does not work. When I removed the part of the code that collects pH, the device worked as intended. I got the code from the manufacturer's website, but I'm not sure what to change to make it work. Thank you very much!
#include <DHT.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#include <EEPROM.h>
#include <GravityTDS.h>

#define ONE_WIRE_BUS 5
#define DHTPIN 7
#define DHTTYPE DHT11
#define TdsSensorPin A1

OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
DHT dht(DHTPIN, DHTTYPE);
SoftwareSerial mySerial(9, 10);
GravityTDS gravityTds;

#define SensorPin A0            //pH meter Analog output to Arduino Analog Input 0
#define Offset 0.00            //deviation compensate
#define LED 13
#define samplingInterval 20
#define printInterval 800
#define ArrayLenth  40    //times of collection
int pHArray[ArrayLenth];   //Store the average value of the sensor feedback
int pHArrayIndex=0;

char msg;
char call;

void setup()
{
  mySerial.begin(9600);   // Setting the baud rate of GSM Module
  Serial.begin(9600);    // Setting the baud rate of Serial Monitor (Arduino)
  Serial.println("GSM SIM900A BEGIN");
  Serial.println("Enter character for control option:");
  Serial.println("h : to disconnect a call");
  Serial.println("i : to receive a call");
  Serial.println("s : to send information");
  Serial.println("c : to make a call");
  Serial.println("e : to redial");
  Serial.println();
  delay(100);

  dht.begin();

  sensors.begin();

  gravityTds.setPin(A1);
  gravityTds.setAref(5.0);
  gravityTds.setAdcRange(1024);
  gravityTds.begin();

  pinMode(LED,OUTPUT);
}

void loop()
{

  if (Serial.available()>0)
   switch(Serial.read())
  {
    case 's':
      SendMessage();
      break;
    case 'c':
      MakeCall();
      break;
    case 'h':
      HangupCall();
      break;
    case 'e':
      RedialCall();
      break;
    case 'i':
      ReceiveCall();
      break;
  }
 if (mySerial.available()>0)
 Serial.write(mySerial.read());
}

void SendMessage()
{

  int h = dht.readHumidity();
  float t = dht.readTemperature();
  float tdsValue = 0;
  float temperature = t;
  gravityTds.setTemperature(temperature);
  gravityTds.update();
  tdsValue = gravityTds.getTdsValue();

  sensors.requestTemperatures();

  mySerial.println("AT+CMGF=1");    //Sets the GSM Module in Text Mode
  delay(1000);  // Delay of 1000 milli seconds or 1 second
  mySerial.println("AT+CMGS=\"+639494145111\"\r"); // Replace x with mobile number
  mySerial.print(h);// The SMS text you want to send
  mySerial.print("% humidity, ");
  mySerial.print(t);
  mySerial.print(" degrees Celsius air temperature, ");
  mySerial.print(sensors.getTempCByIndex(0));
  mySerial.print(" degrees Celsius water temperature, ");
  mySerial.print(tdsValue,0);
  mySerial.println(" ppm, ");

  static unsigned long samplingTime = millis();
  static unsigned long printTime = millis();
  static float pHValue,voltage;
  if(millis()-samplingTime > samplingInterval)
  {
      pHArray[pHArrayIndex++]=analogRead(SensorPin);
      if(pHArrayIndex==ArrayLenth)pHArrayIndex=0;
      voltage = avergearray(pHArray, ArrayLenth)*5.0/1024;
      pHValue = 3.5*voltage+Offset;
      samplingTime=millis();
  }
  if(millis() - printTime > printInterval)   //Every 800 milliseconds, print a numerical, convert the state of the LED indicator
  {
    mySerial.print(pHValue,2);
    mySerial.print(" pH value");
        digitalWrite(LED,digitalRead(LED)^1);
        printTime=millis();
  }
}
double avergearray(int* arr, int number){
  int i;
  int max,min;
  double avg;
  long amount=0;
  if(number<=0){
    Serial.println("Error number for the array to avraging!/n");
    return 0;
  }
  if(number<5){   //less than 5, calculated directly statistics
    for(i=0;i<number;i++){
      amount+=arr[i];
    }
    avg = amount/number;
    return avg;
  }else{
    if(arr[0]<arr[1]){
      min = arr[0];max=arr[1];
    }
    else{
      min=arr[1];max=arr[0];
    }
    for(i=2;i<number;i++){
      if(arr[i]<min){
        amount+=min;        //arr<min
        min=arr[i];
      }else {
        if(arr[i]>max){
          amount+=max;    //arr>max
          max=arr[i];
        }else{
          amount+=arr[i]; //min<=arr<=max
        }
      }//if
    }//for
    avg = (double)amount/(number-2);
  }//if
  return avg;
  delay(100);
  mySerial.println((char)26);// ASCII code of CTRL+Z
  delay(1000);
}

void ReceiveMessage()
{
  mySerial.println("AT+CNMI=2,2,0,0,0"); // AT Command to recieve a live SMS
  delay(1000);
  if (mySerial.available()>0)
  {
    msg=mySerial.read();
    Serial.print(msg);
  }
}

void MakeCall()
{
  mySerial.println("ATD+639494145111;"); // ATDxxxxxxxxxx; -- watch out here for semicolon at the end!!
  Serial.println("Calling  "); // print response over serial port
  delay(1000);
}

void HangupCall()
{
  mySerial.println("ATH");
  Serial.println("Hangup Call");
  delay(1000);
}

void ReceiveCall()
{
  mySerial.println("ATA");
  delay(1000);
  {
    call=mySerial.read();
    Serial.print(call);
  }
}

void RedialCall()
{
  mySerial.println("ATDL");
  Serial.println("Redialing");
  delay(1000);
}

start by running only the pH code ... remove everything else ... if the pH code does not run on its own, then it won't run as a part of a larger program either

The pH program works on its own, so it's only when I incorporate it like this that the pH value doesn't output

how do you know that the pH part of the program does not work? ... you have no debugging code that prints information to Serial

I used just the pH code in another sketch and it outputs the pH there.

that means nothing really ... it could just as easily be the GSM code ... you don't know if that part of code even runs


text:
How to call multiple delayed functions using a single millis()
I am working in a project where I need to call more than 1 functions actually 4 functions using a single millis()
Here is the code below.
 unsigned long then = 0;

 void loop(){

     unsigned long now = millis();

     if(now-then >=0){

         Serial.println("Function 1 called");

     }else if(now-then>=2000){

         Serial.println("Function 2 called");

     }else if(now-then>=4000){

         Serial.println("Function 3 called");

     }else if(now-then>=6000){

        Serial.println("Function 4 called");

         Serial.println("The end");

         then = now;
     }
 }

All the functions above gets run successfully but not in a proper sequence.
The running sequence of the functions seem to be very improper and random.
The 'function 1' gets executed in a proper sequence and timing but rest of the others are making a messy output.
How can I fix it please?
Thanks.

How do you want the functions to be called in order? Like "1,2,3,4 ... 1,2,3,4" or like "1...1,2...1,2,3...1,2,3,4...1...1,2..."?

Like '1234' order

why with else? why only one then?

The current structure with multiple if statements and on timestamp variable does only work, if you also check for millis()-then being smaller than the next interval. Otherwise the first if statement will always be executed.
I think it gets easier, when you use only one if statement, but put the intervals in an array. In that if statement you can either use a switch statement to execute the code for the corresponding interval, or use a function pointer. Somewhat like this (untested):
unsigned long then = 0;
unsigned long intervals[4] = {0, 2000, 4000, 6000};
int current_interval_index = 0;

...

void loop(){
    unsigned long now = millis();
    if(now-then >= intervals[current_interval_index]){
        switch(current_interval_index){
            case 0:
                Serial.println("Function 1");
                break;
            case 1:
                Serial.println("Function 2");
                break;
            case 2:
                Serial.println("Function 3");
                break;
            case 3:
                Serial.println("Function 4");
                break;
        }
    then = now;
    current_interval_index = (current_interval_index + 1) % 4; // increment index and wrap it back to zero, if it goes to 4
    }
}

That way you can easily extent for more functions and the intervals are conveniently managed in an array. Note, that the intervals add up here. So function 4 executes after 2s+3s+6s = 11s.

Nah, my bad, missed the scope of the index update.

your else in that set of if's is causing only a single if to be possible to be true at any one time, and once the now-then line up, only the first one in the line-up will ever execute. remove the else from your if block. treat each if as its own thing. i.e.
if(now-then >=0) { /* do thing 1*/ }
if(now-then >=1000) { /* do thing 2*/ }
if(now-then >=2000) { /* do thing 3*/ }
if(now-then >=3000) { /* do thing 4*/ }

that way, even if the conditions line up, all the blocks will be checked, and all the if's that resolve true, will execute.

your code will result in sequence 1, 1, 2, 1, 2, 3, 1, 2, 3, 4

You need a stamp for every thing x because you'll have to reset each of them to the current millis when the thing gets executed.


text:
Arduino MKR GSM 1400 project - Establish call - Wait and hang call
I am implementing a GSM project using the Arduino MKR 1400 GSM board and I would like to achieve the following:
Establish a call to a specific number, wait for a certain amount of seconds and then hag the call. I have written the following test code in order to see how to manage it.
#include <MKRGSM.h>

// PIN Number
#define PINNUMBER ""

GSM gsmAccess;
GSMVoiceCall vcs;

void setup()
{

  Serial.begin(9600);

  boolean notConnected = true;

  // Start GSM shield
  // If your SIM has PIN, pass it as a parameter of begin() in quotes
  while(notConnected)
  {
    if(gsmAccess.begin(PINNUMBER)==GSM_READY)
      notConnected = false;
    else
    {
      Serial.println("Not connected");
      delay(1000);
    }
  }

  Serial.println("GSM initialized.");

  if (vcs.voiceCall(char_array_number)) {
    Serial.println("Call established");
    delay(10000);
  } else {
    Serial.println("Something is going wrong");
  }

}

void loop()
{

}

Well, the call is established, the phone rings but the instructions inside the if statement won't get execute. Instead I get the following Serial Monitor output.

I don't really understand why that happens because since the call is stablished the first if statement would be executed. I would really appreciate any help, since this is like the final step of my project and been struggling for some time.


text:
Accelerometer Orientation (LIS3DH)
Newbie here!
I’m trying to make a pocket level using an LIS3DH but I don’t know how to “reset” all the axis to start reading from a certain orientation since my LIS3dh won’t be mounted flat and will change often.
Ideally whenever the level starts it would start reading everything at 0 no matter the orientation.
I’m sure it’s just math, but it’s way over my head to begin to understand it.
Starting with the absolute basics I’m using the adafruit lib. I can easily get all the readings, and I understand they are acceleration forces. But how do I start them all from 0?
Initially I was thinking to take the very first reading and store it, then add or subtract the new readings from the originals based on if the new numbers are higher or lower than original (subjectively) but that only works in some instances which means that it wasn’t a good solution.
I don’t have specific code to share as I’m using the adafruit LIS3DH example.
Here’s a reading from the sensor of it not flat
X: -11408 Y: -3152 Z: 10560 X: -6.87 Y: -1.87 Z: 6.27 m/s^2
And here’s readings closer to a flat surface
X: -80 Y: 704 Z: 16176 X: -0.02 Y: 0.46 Z: 9.86 m/s^2

Take an initial reading. Convert that to a 3D vector. Normalize it. That's "zero". Take any other reading. Convert it to a 3D vector. Normalize it. The angle between those two vectors is the angle of the level. This is maths, not Arduino.

"subtract the new readings from the originals [...] only works in some instances" - that's exactly what you have to do. When doesn't it work?

The last 3 number from the Adafruit example look to be the gyroscope.  Unless you are doing something like motion tracking (i.e. 3D gaming) or a "very reactive" tilt compass you don't need to bother w/those.

Consider taking on this project in sever steps.  Some you might do now and other later if necessary
First, accelerometers do not usually need alignment.  But if accuracy and reproducibility is important, a project may benefit from finding any offset a single accelerometer may need and finding any magnitude adjustments between the three accelerometers.  Using gravity rotate each accelerometer through their maximum negative and positive values.  Use these values to find an offset such that the absolute values are equal for each individual accelerometer.  Then select one accelerometer as the bases and find the appropriate coefficients to normalize the other two accelerometers such that the absolute values of all maximums and minimum are equal.  As hinted, this is one of the step you can skip until later if necessary.  If you need a more thorough explanation you can find it in section 2 of this STMicro document.
To find angles it would be best to consider the classic airplane example where pitch (nose up or down) and roll (rotation around the axis passing through the nose and tail).  Here is a good submersible Arduino project to consider. In this project the accelerometer Z axis is pointed down and the X to the side.  To find ROLL the author calculates the inverse tangent of the negative of the ratio of acceleration in the X direction over the acceleration in the Z direction.

The pitch calculation is a bit more involved.  This can be found by taking the inverse tangent of the acceleration in the Y direction over the square root of the sum of the square of the X plus Y acceleration.

That out of the way, now consider how to zero the angles out.  First decide on if you will adjust the roll or the pitch.  Let's consider the roll case.  Record the current roll angle and subtract it from the current calculated roll angle before displaying it as zero.  Now rotate your accelerometer such that you do it around the Y axis (remember, we are only considering the roll case and do not want to change the Y accelerometer's reading!).  If you have done the math correctly, the displayed angle will be the difference between when you started and finished your rotation.
All that out of the way, now consider what would happen if you rotated your accelerometer through a roll position where the acceleration in the Z direction falls to zero.  Your trigonometric inverse tangent function for roll would go to infinity!  In the physical world, where gimbals are used for air and space navigation, this is referred to as Gimbal lock!
What to do about Gimbal lock?!  Well, it's a story that starts in 1843 (yeah, that does sound odd doesn't it WRT air and space navigation).  In short, if you stop using classical trigonometry to convert acceleration to angle an start using Quaternions you avoid Gimbal lock entirely.  Quaternions use complex numbers to describe rotation in 3D space.  People who write 3D gaming programs absolutely love how Quaternions simplify their efforts.  This is another of those steps you don't have to do.  But doing so will make your project all the more robust.
(BTW, this is the STMicro LIS3DH data sheet.)

You're new @CarmexLover13.  If the above answers your question select it as the correct answer.  If you want to wait and try it fist to see if it works that's ok too.  Or write a comment/question here if something is not clear and I'll edit the answer.  Feel free to edit your question too if you find you forgot to ask something in particular.

I'm not intentionally ignoring. I'm attempting to understand enough trig to be able to test this.. it's currently way over my head ha.

I fixed the link to the 1st STMicro document.  Maybe that will help.  Review the unit circle.  Get a feel for how angle and Sin and Cos relate.  Tan is just Sin/Cos.  After you wrap you head around that you can take a stab at converting the accelerameter's readings to angles.

If you want, you can skip over trigonometry and jump to quaternion. Also, you are using an STMicro IMU chip.  If you are also using an STMicro processor you can simply skip over all of this by using STMicro development tools and ready made compass libraries.  It would be even better if you are using recent vintage STMicro development boards. But fair warning, unlike Arduino tools, these are complex tools meant for enterprise development.

I should have noted the pitch and roll are figured out. Resetting the starting leveling or accounting for gimbal lock I believe are the only hold up now and they share the same solution.
Also for the time being I'm using an arduino uno, not stmicro based I don't believe
I'll be back when I understand quaternions a bit more


text:
Arduino 33 Nano BLE Sense not compatible with pulseIn()?
Preface
Currently, I'm making an application on a Arduino 33 Nano BLE Sense. I'm trying to measure the current humidity and send it via BLE to another device. The target is to send a precise value with a high frequency, 8-10 values every second.
For measuring the humidity I connected an external sensor, the P14 Rapid Capacitive Humidity Sensor (it's faster and more accurate than the onboard humidity sensor) with a NE555 Timer IC in Monostable Mode.
To read the output pulse (frequency: ca. 500Hz) I'm using pulseIn().
I managed to calculate the humidity correctly and also the BLE data transfer worked.

Problem
My (minified) sketch:
#include <ArduinoBLE.h>

void setup() {
    // some setup, takes around 10s
}

void loop() {
    BLE.poll(); // polling for new events, takes ca. 10 µs

    value = pulseIn(6, HIGH); // read the high pulse, takes around 500-4000 µs

    // calculating the average value, takes < 1 µs

    if (/* this if is executed every 1 second for testing purposes, targeted is every 100ms*/) {
        // humidity is calculated, takes ca. 20 µs

        characteristic.writeValue(/* calculated value */); // takes ca. 50 µs
    }
}

When I merged the features, the problems began. I couldn't connect to the Arduino anymore.
When I try to connect to it (with nrf Connect App), this happens. When I manage to connect to it before it stops working, I will be disconnected with a GATT_CONN_TIMEOUT exception.

When the Arduino is powered on, the setup is called and it's connectable while the setup is running. When pulseIn() is called for the first time the BLE connection stops working. But the programm keeps on running.
I already tried calling pulseIn() only every 10s or only once, the BLE connection stops working.
And yes, commenting out the pulseIn() makes BLE work again.

Possible Solution
Next thing I would try is to delete the pulseIn() and use interrupts for measuring the time.
My question is if there is a better way to fix this issue?

Likely you can not mix these two libraries.  If you are so inclined I would dive into the source code for each library in an attempt to find the conflict.  You are probably looking for both libraries using the same resource such as a timer.  Setting up your own timer as stated in the question may be easier.  It may be a bit extreme, but if you understand the underlying (to an Arduino sketch) C++ language, you might also consider destroying & constructing the BLE library ever time you want to use it.

how do you know that it stops at pulseIn()? ... the code that you posted has no debug functions

@jsotola as said in the question the code i posted is very minified. I print the value I get from the ´pulseIn()` and when it's printed the connection stops.

so it does not stop at pulseIn() ... it stops a couple of program lines after

@jsotola sorry, I wasn't very clear about what stops. The programm keeps running normally and I see the prints the continue. But the BLE connection stops, as seen in screenshot the device stops "existing".


text:
MacOS BigSur Arduino IDE No Ports Shown
I'm trying to get the Arduino IDE (1.8.13) installed on MacOS BigSur 11.0.1 and am unable to compile and run an Arduino sketch. There are no ports available in 'Tool' menu; the port item is grayed out.  The error message states that the IDE "Could not initialize class sun.security.ssl.SSLContextImpl$DefaultSSLContext".  I have installed the following Java code:
java 16.0.1 2021-04-20
Java(TM) SE Runtime Environment (build 16.0.1+9-24)
Java HotSpot(TM) 64-Bit Server VM (build 16.0.1+9-24, mixed mode, sharing)

Any insight would be most appreciated.  Thanks in advance.

I don't have a Mac, so I'm not likely to be of much use on this, but it would be good to confirm that the device shows up in /dev or whatever is in the Mac control panel that lists USB devices.  If it doesn't, then the SSL error is unrelated (which would kind of make sense) or, at a minimum, not entirely determining the problem.

@timemage serial ports are listed in /dev.

Solved: I opened Android Studio and there was a security update for Java 8 (I think) so I accepted it and installed it.  Now I can magically see serial ports in the Arduino IDE.  I wish I understood what happened, but for now the problem appears to be solved.  Thank you for allowing me to post here.

Odd.  The way the IDE comes packaged, at least for Linux and Windows, it has its own JRE bundled in.

With all the gatekeeper features on a Mac, perhaps it blocked the Java code when I downloaded the Arduino IDE?  Macs used to come with Java pre-installed, but I've read that they no longer do that.  It is a new 64 bit machine and I have to give special permission just to run my own apps developed and compiled on my old 32 bit system.

If you get to the point of having a definitive answer, it may make sense to post it as an answer.


text:
How to show the distance in decimal use sensor TF-Luna Lidar or more specific value
I want to ask about TF-Lunar Lidar, I've written code to know the distance in cm by reading the array data, right now I need some help about how to read the data so it can be showing the more specific value (float or in decimal)
Or do you guys know what is the speed of the waves transmitted and captured by the lidar sensor, so that I can calculate it in a more specific form, such as using the method of calculating the distance on the Hc-srf04 sensor
I also have used this format to read the distance in mm, but It never works (image about array data)

it is unclear what you are trying to do ... you said that you are able to measure the distance in cm ... what is more specific value?

i'm sorry, what i mean is below cm, (mm or below) because the sensor only show it in cm like 1.00, 2.00 it wont show 1.01 or 1.02
sorry for my bad english

Re “the speed of the waves”: The “li” in “lidar” stands for “light”. Light waves travel at the speed of light.

so if i inputting the duration of the light travel from trigger to echo, i can find the distance?. will it work?

so if i inputting the duration of the light travel from trigger to echo, i can find the distance?. will it work?

That's the basic working principle, but you cannot do that with an Arduino. Light is too fast, resulting in incredibly small travel times. You need specialized hardware for that. And thats, what a Lidar sensor (or other Time Of Flight sensor) are.

The TF-Lunar Lidar sensor supports different output formats. The distance in cm is just the default. There is also the format, that you showed in your question (9 byte mm), which gives you the distance in mm. The manual of the TF-Lunar also explains how to change the used output format (look at page 22: "5.Output format setting ID_OUTPUT_FORMAT=0x05"). How exactly this is done depends on your actual code and the used communication interface (Serial or I2C).

Thank you for the answer sir, that's very helpful and informative.
But since I can't use the I2c because I can't find the address when I connect it to Arduino (search the address with the i2c scanner), so I need to research how to find it because I'm still learning to program Arduino without a library (.h file and .cpp file)


text:
Bluetooth module not working
I was following a tutorial on YouTube to build a Bluetooth car with Arduino.
#include <AFMotor.h>

//initial motors pin
AF_DCMotor motor1(1, MOTOR12_1KHZ);
AF_DCMotor motor4(4, MOTOR34_1KHZ);

char command;

void setup()
{
  Serial.begin(9600);  //Set the baud rate to your Bluetooth module.
}

void loop(){
  if(Serial.available() > 0){
    command = Serial.read();
    stop(); //initialize with motors stoped
    //Change pin mode only if new command is different from previous.
    //Serial.println(command);
    switch(command){
    case 'F':
      forward();
      break;
    case 'B':
       back();
      break;
    case 'L':
      left();
      break;
    case 'R':
      right();
      break;
    case 'S':
      stop();
      break;
    }
  }
}

void forward()
{
  motor1.setSpeed(255); //Define maximum velocity
  motor1.run(FORWARD); //rotate the motor clockwise
  motor4.setSpeed(255);//Define maximum velocity
  motor4.run(FORWARD); //rotate the motor clockwise
}

void back()
{
  motor1.setSpeed(255); //Define maximum velocity
  motor1.run(BACKWARD); //rotate the motor anti-clockwise
  motor4.setSpeed(255); //Define maximum velocity
  motor4.run(BACKWARD); //rotate the motor anti-clockwise
}

void left()
{
  motor1.setSpeed(255); //Define maximum velocity
  motor1.run(BACKWARD); //rotate the motor anti-clockwise
  motor4.setSpeed(255); //Define maximum velocity
  motor4.run(FORWARD);  //rotate the motor clockwise
}

void right()
{
  motor1.setSpeed(255); //Define maximum velocity
  motor1.run(FORWARD); //rotate the motor clockwiseclockwise
  motor4.setSpeed(255); //Define maximum velocity
  motor4.run(BACKWARD); //rotate the motor anti-clockwise
}

void stop()
{
  motor1.setSpeed(0); //Define minimum velocity
  motor1.run(RELEASE); //stop the motor when release the buttonbutton
  motor4.setSpeed(0); //Define minimum velocity
  motor4.run(RELEASE); //stop the motor when release the button
}

Here's the schematic:

I didn't use the resistor, I used 4 aa batteries, and I used 2 motors instead of 4, but the bluetooth module is flashing.

Please include the image directly into your question.

Could you establish the bluetooth connection to the HC-05 on your smartphone? Did you configure the module to use 9600 baud for the serial connection?

ok i will one second

@chrisl i don't understand, but yes i established the bluetooth connection to the hc05 on my smartphone but i don't understand the second part

The HC-05 is a bluetooth-Serial bridge. The pins going to TX and RX of the Arduino are for the Serial (UART) communication interface. For using that interface, both devices need to be configured to the same baudrate/speed. In your sketch you are using 9600 baud. But often the HC-05 modules are configured for something like 38400 baud by default. So have you made sure, that you are using the same baudrate in your code as the HC-05 uses?

yes i set the serial.begin to 38400

but it is still not working

I didn't use the resistor...  so ... you wired the bluetooth module direct to the Arduino with no logic level translation?

no i used the arduinon driver board

and the hc05 module has a 3.3v regulator

@powerdido2007 Most HC-05 modules only have a 3.3V regulator for the power lines. They don't translate the data lines. Thus the 5V from the Arduino at the HC-05s RX line can damage it

so what should i do

generally with the HC-05 it isn't plug&play. Please google for some tutorials about it and try them first. It can be rather complex, so that answering here for all possible problems is too much.


text:
Display upTime using `millis()` - Arduino Uno
I want to use the following function to display MCU's uptime, but after several hours I get error.
void uptime(char *ret_clk)
{
  byte days = 0;
  byte hours = 0;
  byte minutes = 0;
  byte seconds = 0;

  int sec2minutes = 60;
  int sec2hours = (sec2minutes * 60);
  int sec2days = (sec2hours * 24);

  unsigned long time_delta = millis() / 1000UL;

  days = (int)(time_delta / sec2days);
  hours = (int)((time_delta - days * sec2days) / sec2hours);
  minutes = (int)((time_delta - days * sec2days - hours * sec2hours) / sec2minutes);
  seconds = (int)(time_delta - days * sec2days - hours * sec2hours - minutes * sec2minutes);

  sprintf(ret_clk, "%01dd %02d:%02d:%02d", days, hours, minutes, seconds);
}

after 2:55 hours I got a correct answer : 0d 02:55:27
also after 4 hours, a correct answer : 0d 04:06:44
but roughly after 12 hours i get an error: 1d 02:01:27
and after roughly 20 hours I get : 2d 23:74:26
What is wrong in uptime ?

On an 8-bit Arduino an int can only hold values in the range -32768 to +32767. One day's worth of seconds is 86400, which is far outside that range.
You should replace your sec2... variables with literals, maybe #defined - and don't forget to force the length for longer values:
#define SEC2MINUTES 60
#define SEC2HOURS 3600
#define SEC2DAYS 86400UL

what is the bennefit define it using #define ? whould define as usgined long save the problem ?

@Guy.D If you put it in a variable and use that variable to calculate other variables to do your calculations with it has to calculate them every single iteration. By using #define (or you could use const unsigned long if you wish) it calculates it at compile time (which I shortcut by just calculating it myself).

what might be that cause getting this result :upTime[0d 10:123:33] ? code was corrected as you suggested

The millis function increments rapidly, hence it easily exceeds the maximum value of int -  -32768 to +32767.
So, use unsigned long data types for millis and other stuff that's large.
4 billion and some change is the max value that unsigned long data types can store, hence no overflowing till about 49 days.


text:
Why is this extremely simple code not working?
I have a problem with a for loop, and Serial.print("Its Working") does not appear. Seems simple, I've done it before, now for whatever reason, its not working anymore
void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
}

void loop() {
  // put your main code here, to run repeatedly:

  for (int x = 0; x > 10; x++) {

    Serial.println("Its Working");
    delay(1000);
  }
}

The problem is:
for (int x = 0; x > 10; x++) {

That can be rewritten, in pseudo code, as:

X is zero
While X is greater than 10:

Increment X

You see the problem? X is zero. It's not greater than 10, so it never increments.
I assume you actually wanted:
for (int x = 0; x < 10; x++) {

Also be aware that your for loop will be run over and over again, so you will never see it finish.  You should add
Serial.println("Loop done");

at the end so you know it's finished.

Essentially, the for loop never starts as the first time it checks the condition, its already false, right?

@Coder9390 That is correct.

@Coder9390: You can see that for yourself by single-stepping your code with a debugger.  You'll see execution skip over the loop without ever entering the loop body.  That's your hint that you accidentally wrote a loop condition that's false on the first check.  Remember that a for loop is basically the same as part1;  / while(part2){ ...; part3; }, so like a while loop, the condition is checked before entering the loop for the first time.

@Coder9390:   Using a debugger is essential for low-level stuff where alternatives like sprinkling debug-print statements in your code aren't easy, or to help catch brain-farts where something you're assuming you got right was actually the problem.


text:
Arduino , python , pyfirmata , standard firmata
Is there a way to change arduino analog reference to EXTERNAL IN PYTHON using pyfirmata or any other library ?
Necessary Links : https://www.arduino.cc/reference/en/language/functions/analog-io/analogreference/
My sensor has a 3.3 volt operating voltage , my arduino has a 5 volt operating voltage.
As such in arduino using C++ and arduino module the scaling can be done using analogReference(External) and providing reference voltage to analog read?
IS there any equivalent to this in python, pyfirmata ?

No, not as far as I know. The firmata protocol does not include a command to set the analog reference. However, you can of course modify the firmata firmware to your liking. In the simplest case, just add the appropriate command to the setup() function of the main .ino.

I have been using pyfirmata for the previous projects. Since pyfirmata doesnt include the necessary function , you suggest adding analogreference(External) to the firmata module that i would have to upload and run on arduino , would that make the analog reference voltage external when accessing with pyfirmata and python?

@Shahanhasan Yes. Firmata doesn't use analogReference() anywhere in the code, so when you add analogReference(EXTERNAL) to the startup code, it should change the behavior when accessing it from pyfirmata.


text:
Arduino Yún causing power suge warning
Recently I got an Arduino Yún board that sends out a power surge error message everytime I connect it to my laptop through the USB cable. I tried two Arduino Leonardo and one Arduino Uno and there wasn't any problem with them or the USB port. Am I missing something or is the board faulty already?

Use a USB tester to test the current consumption, it should be < 500ma
I recommend using a USB that has power of its own, eg. monitor USB

Yún boards are more powerful boards than your average Arduino. Probably too powerful for your little laptop's USB ports. Use a powered hub or an external power supply to run the board.


text:
Arduino Nano 33 BLE - use of flash to store data; how to expand a piece of sample code
I've been looking into how to store data in between restarts.  With an Arduino UNO, there are plenty of EEPROM libraries, but I'm not finding something 'off the rack' for the Arduino Nano 33 BLE.
I did manage to find a well documented example by Pete Warden, who recently put on github (https://github.com/petewarden/arduino_nano_ble_write_flash), and it can be compiled and downloaded, but I'm unclear as to how one would expand on it, to write a simple function that can store and read multiple values (integer, float, string, arrays).
The code is below, I'm a bit rusty on things, but I am thinking that the key is in the part:
  // Treat the first four bytes of the copy of our flash array as a 32-bit
  // integer.
  int32_t* counter_address = reinterpret_cast<int32_t*>(ram_buffer);

How would one add additional variables (and of different lengths) to this code, so you could write and read more than one variable?   Somehow, it would seem a command like:
int32_t* another_variable = [modified version of:] reinterpret_cast<int32_t*>(ram_buffer);

... would do the trick, but I'm not quite sure about how this is done.
   * Copyright 2021 The TensorFlow Authors. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
    http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
==============================================================================*/

// This sketch demonstrates how to initialize, read, and update flash memory
// on an Arduino Nano BLE Sense 33. It contains a counter that starts at zero
// when the sketch is first uploaded, and is incremented by one every time that
// the board is reset without a re-flash. You can test this by uploading the
// sketch, opening the serial monitor, and seeing "Counter=0" output initially.
// If you then press the reset button, you should see "Counter=1", and so on as
// the board is restarted.

// This Mbed API lets us access flash memory, so we include the header. See
// https://os.mbed.com/docs/mbed-os/v6.9/apis/flashiapblockdevice.html
#include "FlashIAPBlockDevice.h"

// One of the challenges I had with the existing examples I found of using flash
// was that they didn't demonstrate how to set an initial value for the memory
// when the sketch was first uploaded. This was essential for most use cases,
// for example we want the counter to start at zero so the initial contents need
// to be set when the program is flashed. I would typically try to use linker
// scripts to set aside an area of memory and mark it so it's initialized during
// flashing, but that's not very easy with the Arduino IDE. Instead I use a bit of
// a hack, by:
//  - Declaring an array of bytes as const, so I know it will end up in
//    flash.
//  - Forcing it to align with the block size of the flash, so it can be
//    accessed by the API that works with whole pages of flash.
//  - Adding an empty initializer list ({}) tells the compiler to zero out the
//    contents in the binary that's flashed to the device.
// The last point is a bit subtle, because you might think that doing it in a
// constructor or setup() would work, but that would be called every time the
// program is reset. What I needed was a way to create a binary with that area
// already initialized before upload, which this approach offers.
// Some other examples use hard-coded addresses for the flash, usually towards
// the top of the address space so that they won't clash with the loaded program,
// but this approach does have the advantage that your writable area is dealt with
// in the same way as other variables, so you shouldn't have to worry about
// overwriting anything.

// From experimentation I know that the "page size" or "block size" of the flash
// on the board is 4KB, and should match the reported get_erase_size() from the
// block device object. In theory we should be able to use the
// MBED_CONF_FLASHIAP_BLOCK_DEVICE_SIZE macro, but this seems to be set to zero.

    #include "FlashIAPBlockDevice.h"

    constexpr int kFlashBlockSize = 4096;

        // Your flash area needs to be a multiple of the block size. In this case I want
        // 64KB (even though I'm only using the first four bytes). You should make this
        // the smallest multiple of the block size that will hold your data.
        #define ROUND_UP(val, block_size) ((((val) + ((block_size) - 1)) / (block_size)) * (block_size))
        constexpr int kFlashBufferSize = ROUND_UP(64 * 1024, kFlashBlockSize);

        // As mentioned above, alignas ensures we get a valid block-aligned address,
        // const should make sure it's in flash, and the empty brackets mean the array
        // is filled with zeroes when the program is first uploaded.
        alignas(kFlashBlockSize) const uint8_t flash_buffer[kFlashBufferSize] = {};

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

              // Beware! If you copy and paste this code into your own example, and try
              // running it without the serial monitor attached, this line will hang forever.
              // You'll need to remove this in production (and yes I have been caught by this
              // myself far too often).
              while (!Serial);

              // The address of the array will be determined by the compiler, and we need to
              // grab it as a 32-bit integer to use with the Mbed API.
              const uint32_t flash_buffer_address = reinterpret_cast<uint32_t>(flash_buffer);
              Serial.println(String("flash_buffer_address=0x") + String(flash_buffer_address, 16));

              // Create the flash object we'll be using to access the flash memory.
              static FlashIAPBlockDevice bd(flash_buffer_address, kFlashBufferSize);
              bd.init();

              // We'll need to copy the area of flash to RAM to modify it, so allocate an
              // array of the right size.
              uint8_t* ram_buffer = (uint8_t*)(malloc(kFlashBufferSize));

              // Copy the existing flash contents into our ram buffer.
              bd.read(ram_buffer, 0, kFlashBufferSize);

              // We need to erase the flash area before we can write into it again.
              bd.erase(0, kFlashBufferSize);

              // Treat the first four bytes of the copy of our flash array as a 32-bit
              // integer.
              int32_t* counter_address = reinterpret_cast<int32_t*>(ram_buffer);

              // Print out the value before any changes.
              Serial.println(String("Counter=") + String(*counter_address, 16));

              // Update our RAM copy of the counter integer.
              *counter_address += 1;

              // Write the whole copy of our RAM buffer back into flash.
              bd.program(ram_buffer, 0, kFlashBufferSize);

              // Shut down our flash access object.
              bd.deinit();
            }

put them in the buffer, read them from buffer

OK... but how does one exactly put them in the buffer?   The syntax is what is not understood.  It is understood that if you have a buffer, you can put at certain locations in the buffer - but how is that done?

The flash will be erased everytime you upload a new sketch. Is that what you want?

No; the request is that you be able to add N variables.  In doing this with EEPROM, it involved offsets from a memory location.  What I'm curious about is how you can do this with a bunch of variables of different types.

I can't really help with the source code you found, but here is a simpler solution for your original problem: I wrote a library called NanoBLEFlashPrefs. It allows you to store parameters and preferences persistently between program restarts and even reprogramming.
The Arduino boards mentioned above use a nRF52840 microcontroller from Nordic Semiconductor. This chip features a very simple file system for flash storage. This is used in the library to store and retrieve an arbitrary struct of data of your program.
Please take a look at the GitHub repository of NanoBLEFlashPrefs.

In the new Arduino board setup, I get the message "WARNING: library NanoBLEFlashPrefs claims to run on mbed_nano architecture(s) and may be incompatible with your current board which runs on mbed architecture(s).
"

@asylumax You can safely ignore this if you really use an Arduino Nano 33 BLE. I have seen this as well, but now it is gone. Which version of the IDE and which version of the board support "Arduino Mbed OS Nano Boards" do you use? With version 2.6.1 of that board support and version 1.8.15 of the IDE I don't see this warning any more.

You can also try my FS_Nano33BLE Library with simple-to-use LittleFS / FATFS.
The filesystem access uses normal POSIX APIs or mbed FileSystem APIs

Great library; there doesn't seem to be a 'directory' function to figure out what files exist.  Right now, I'm writing a few wrappers so you can use strings, which some folks might use.

I was able to build the 'directory' command, based on the link you provided, (https://os.mbed.com/docs/mbed-os/v6.10/apis/file-system-apis.html).  Thanks.

I guess a simple solution would be to stick with the original
pattern and use only one variable... but have this variable be a
container for all the stuff you need:
struct StoredData {
    int32_t some_integer_variable;
    float some_float;
    // etc...
};

Then you can use the same pattern as the original code:
StoredData* my_data = reinterpret_cast<StoredData*>(ram_buffer);

and access the individual variables as my_data->some_integer_variable,
my_data->some_float, etc.


text:
how to run 2 different servo (continuous rotation and regular servo) in parallel, not run one after other?
I need to control 2 servos in parallel, whereas one is of continuous rotation and another is of regular positioning control (angle) on arduino IDE. I tried but it works one after another, not parallel. How can I do that, please suggest. Thanks.

Please post the code that is not working as expected in a minimum example. Then I can try to help.

you can only control one at a time. You can switch between both servo after, so that, it seems to be happening in parallel

I am proposing one answer
https://wokwi.com/arduino/projects/297646292038844936
Here, we are not using the delay function. We are using the millis()
Based on your actual application, you can control individual servo accordingly.
Here is the Arduino simulation:
https://wokwi.com/arduino/projects/297646292038844936

/* Sweep
  by BARRAGAN <http://barraganstudio.com>
  This example code is in the public domain.

  modified 8 Nov 2013
  by Scott Fitzgerald
  http://www.arduino.cc/en/Tutorial/Sweep
*/

#include <Servo.h>

Servo myservo;  // create servo object to control a servo
Servo myservo2;  // create servo object to control a servo

// twelve servo objects can be created on most boards
unsigned long previousMillis = 0;        // will store last time LED was updated
const long interval = 15;           // interval at which to blink (milliseconds)

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

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

}

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

  if (currentMillis - previousMillis >= interval) {
    // save the last time you blinked the LED
    previousMillis = currentMillis;

    myservo.write(pos);              // tell servo to go to position in variable 'pos'
    pos = pos + 1;
    if (pos > 180) {
      pos = 0;
    }                      // waits 15ms for the servo to reach the position

    myservo2.write(pos2);              // tell servo to go to position in variable 'pos'
    pos2 = pos2 + 1;
    if (pos2 > 90) {
      pos2 = 0;
    }

  }

}

The angel of two Servomotors should be same ?
If yes,
Try this for 180 deg. Servos :
You can connect signal pin of ech servo to a specific PWM pin of Arduino like pin number '9' in this example
It's just for test but you can change this how you want to
I hope it will work you,
Good luck
#include <Servo.h>

Servo myservo;

int PWMpin = 9;  // change this for your circuit configuration

int a = 0;

void setup() {
  myservo.attach(9);
  myservo.write(0);  // set servo to mid-point
}
void loop() {
  for (int i = 0; i < 180; i++) {
   myservo.write(i);
    delay(10);
  If (i == 180) {
    analogWrite(PWMpin, a);
    }
  }
}

Please don't post code as a image.

Thanks @Hamid 'Smith' Salehi for your reply. well, the servos I am using are not the same, i mean one is of continuous rotation and one is regular, so what i wish to have it like the continuous rotation servos should be rotate with the regular servo which should run between 0~180 deg in parallel. ans these are connected to pin 9 and 10 respectively.

The only difference of servomotors is their rotation limitations? Both of them works by standard PWM ?

As i know, there is no way for a single arduino or any other microcontrollers to command on pins in exactly same time and it's because of microcontrollers nature.
When you have to command 2 outputs
Microcontroller will be act like this :
Command 1 .... To pin number 9
Command 2 .... To pin number 10
and for example if your microcontroller, like arduino or others do each command in one complete clock cycle and your clock frequency will be 16 MHz, so each cycle's time period is 62.5 nano-seconds.
So your microcontroller will do your command in first clock cycle and do the second command in next clock cycle,
In the other words, command 2 will do 62.5 nano-second after command one (if each those commands takes just one clock cycle) but in normal 16 MHz arduino boards it takes much much more time to do commands like this and it was just an example to understand it's principle, and because of this reason i suggest you to connect both servomotors into same output PWM pin if you are using two standard servomotors;
But the main issue is different angle limitations of your servomotors and it's impossible to control them when you want one of them to rotate 360 deg. and the other must rotate 180 deg. .
If you connect those signal pin to a same output, you have two options with two issuse.
First, if you command to the output pin to turn 360 deg. , All things will be good but when your output pin command for angles more than 180 deg. , The little servo will stop.
Second, if you limit your rotation to 180 deg., You will not be able to rotate 360 deg. Your bigger servomotor.
I hope my description will be useful and face you by your complete pattern of what's going on in this project's issue


text:
send images from Arduino Uno to raspberry pi
I am a new to work with ov7670 camera module and Arduino . please let me know whether it could be possible to send images captured from ov7670 module with Arduino Uno to Raspberry pi??

Wouldn't it be easier to connect the OV7670 directly to the Raspberry Pi?

It really would be way easier to directly use the Pi's camera interface and ditching the Uno. The Uno is not good for handling images, though it is generally capable of doing it (in limits). If you want to go on vacation you wouldn't try to tow your car with a boby car to the destination. You would directly use the car itself, because it is way more capable.

Thanks for your response :) .But would it be possible to connect ov7670 to raspberry pi directly?? In some websites I saw that 0V7670 is a arducam and doesn't compatible with raspberry pi ?? Isn't it ? Pls let me know ASAP .