text:
Arduino IDE 2.3.2 Not Launching New Install
I just installed the Arduino IDE on a new computer from the installer. It opens a window and the arduino icon pulses but never seems to do anything. I ran it from the powershell and got a bunch of errors.
Any idea how to fix the library_index.json not existing?
PowerShell 7.4.2
PS C:\Program Files\Arduino IDE> & '.\Arduino IDE.exe'

PS C:\Program Files\Arduino IDE> Arduino IDE 2.3.2
Checking for frontend application configuration customizations. Module path: C:\Program Files\Arduino IDE\resources\app\lib\backend\electron-main.js, destination 'package.json': C:\Program Files\Arduino IDE\resources\app\package.json
Setting 'theia.frontend.config.appVersion' application configuration value to: "2.3.2" (type of string)
Setting 'theia.frontend.config.cliVersion' application configuration value to: "0.35.3" (type of string)
Setting 'theia.frontend.config.buildDate' application configuration value to: "2024-02-20T10:04:35.814Z" (type of string)
Frontend application configuration after modifications: {"applicationName":"Arduino IDE","defaultTheme":{"light":"arduino-theme","dark":"arduino-theme-dark"},"defaultIconTheme":"none","electron":{"windowOptions":{}},"defaultLocale":"","validatePreferencesSchema":false,"preferences":{"window.title":"${rootName}${activeEditorShort}${appName}","files.autoSave":"afterDelay","editor.minimap.enabled":false,"editor.tabSize":2,"editor.scrollBeyondLastLine":false,"editor.quickSuggestions":{"other":false,"comments":false,"strings":false},"editor.maxTokenizationLineLength":500,"editor.bracketPairColorization.enabled":false,"breadcrumbs.enabled":false,"workbench.tree.renderIndentGuides":"none","explorer.compactFolders":false},"appVersion":"2.3.2","cliVersion":"0.35.3","buildDate":"2024-02-20T10:04:35.814Z"}
Starting backend process. PID: 20372
Using browser-only version of superagent in non-browser environment
Configuration directory URI: 'file:///c%3A/Users/jmwau/.arduinoIDE'
Configuring to accept webviews on '^.+\.webview\..+$' hostname.
2024-05-13T19:57:22.348Z root INFO Backend Object.initialize: 4.8 ms [Finished 0.487 s after backend start]
2024-05-13T19:57:22.349Z root INFO Backend Object.configure: 4.0 ms [Finished 0.487 s after backend start]
2024-05-13T19:57:22.349Z root INFO Backend s.onStart: 2.1 ms [Finished 0.487 s after backend start]
2024-05-13T19:57:22.350Z root INFO Backend s.configure: 0.3 ms [Finished 0.512 s after backend start]
2024-05-13T19:57:22.351Z root INFO Backend d.onStart: 0.2 ms [Finished 0.512 s after backend start]
2024-05-13T19:57:22.352Z root INFO Backend d.configure: 0.1 ms [Finished 0.512 s after backend start]
2024-05-13T19:57:22.352Z root INFO Backend d.initialize: 25.1 ms [Finished 0.513 s after backend start]
2024-05-13T19:57:22.353Z root INFO Backend c.onStart: 0.3 ms [Finished 0.513 s after backend start]
2024-05-13T19:57:22.353Z root INFO Backend a.configure: 1.2 ms [Finished 0.514 s after backend start]
2024-05-13T19:57:22.355Z config INFO >>> Initializing CLI configuration...
2024-05-13T19:57:22.355Z root INFO Backend c.initialize: 0.9 ms [Finished 0.515 s after backend start]
2024-05-13T19:57:22.355Z root INFO Backend R.onStart: 0.9 ms [Finished 0.515 s after backend start]
2024-05-13T19:57:22.356Z config INFO Loading CLI configuration from c:\Users\jmwau\.arduinoIDE\arduino-cli.yaml...
2024-05-13T19:57:22.356Z daemon INFO Starting daemon from C:\Program Files\Arduino IDE\resources\app\lib\backend\resources\arduino-cli.exe...
2024-05-13T19:57:22.356Z root INFO Backend a.initialize: 0.4 ms [Finished 0.516 s after backend start]
2024-05-13T19:57:22.356Z root INFO Backend w.onStart: 1.1 ms [Finished 0.517 s after backend start]
2024-05-13T19:57:22.356Z root INFO Backend r.configure: 1.9 ms [Finished 0.517 s after backend start]
2024-05-13T19:57:22.356Z discovery-log INFO start
2024-05-13T19:57:22.356Z discovery-log INFO start new deferred
2024-05-13T19:57:22.356Z root INFO Backend d.initialize: 0.5 ms [Finished 0.518 s after backend start]
2024-05-13T19:57:22.357Z root INFO Backend y.onStart: 2.0 ms [Finished 0.519 s after backend start]
2024-05-13T19:57:22.357Z root INFO Backend r.configure: 1.7 ms [Finished 0.520 s after backend start]
2024-05-13T19:57:22.357Z root INFO Backend a.onStart: 0.5 ms [Finished 0.521 s after backend start]
2024-05-13T19:57:22.357Z root INFO Backend h.configure: 0.4 ms [Finished 0.521 s after backend start]
2024-05-13T19:57:22.357Z root INFO Backend s.configure: 0.2 ms [Finished 0.521 s after backend start]
2024-05-13T19:57:22.357Z root INFO Backend l.configure: 0.1 ms [Finished 0.521 s after backend start]
2024-05-13T19:57:22.359Z root INFO Theia app listening on http://127.0.0.1:63045.
2024-05-13T19:57:22.359Z root INFO Finished starting backend application: 2.8 ms [Finished 0.524 s after backend start]
2024-05-13T19:57:22.367Z root WARN The local plugin referenced by local-dir:/c%3A/Users/jmwau/.arduinoIDE/plugins does not exist.
2024-05-13T19:57:22.367Z root WARN The local plugin referenced by local-dir:/c%3A/Users/jmwau/.arduinoIDE/extensions does not exist.
2024-05-13T19:57:22.367Z root WARN The local plugin referenced by local-dir:C:\Users\jmwau\.arduinoIDE\plugins does not exist.
2024-05-13T19:57:22.374Z config INFO Loaded CLI configuration: {"board_manager":{"additional_urls":[]},"build_cache":{"compilations_before_purge":10,"ttl":"720h0m0s"},"daemon":{"port":"50051"},"directories":{"data":"C:\\Users\\jmwau\\AppData\\Local\\Arduino15","downloads":"C:\\Users\\jmwau\\AppData\\Local\\Arduino15\\staging","user":"C:\\Users\\jmwau\\OneDrive\\Documents\\Arduino"},"library":{"enable_unsafe_install":false},"logging":{"file":"","format":"text","level":"info"},"metrics":{"addr":":9090","enabled":true},"output":{"no_color":false},"sketch":{"always_export_binaries":false},"updater":{"enable_notification":true}}
2024-05-13T19:57:22.374Z config INFO 'directories.data' and 'directories.user' are set in the CLI configuration model.
2024-05-13T19:57:22.374Z config INFO Loaded the CLI configuration.
2024-05-13T19:57:22.377Z config INFO Mapped the CLI configuration: {"dataDirUri":"file:///c%3A/Users/jmwau/AppData/Local/Arduino15","sketchDirUri":"file:///c%3A/Users/jmwau/OneDrive/Documents/Arduino","additionalUrls":[],"network":"none","locale":"en"}
2024-05-13T19:57:22.377Z config INFO Validating the CLI configuration...
2024-05-13T19:57:22.377Z config INFO The CLI config is valid.
2024-05-13T19:57:22.377Z config INFO <<< Initialized the CLI configuration.
2024-05-13T19:57:22.399Z root INFO Resolve plugins list: 43.4 ms [Finished 0.563 s after backend start]
2024-05-13T19:57:22.445Z daemon INFO time="2024-05-13T12:57:22-07:00" level=info msg="Using config file: c:\\Users\\jmwau\\.arduinoIDE\\arduino-cli.yaml"
time="2024-05-13T12:57:22-07:00" level=info msg="arduino-cli.exe version 0.35.3"
time="2024-05-13T12:57:22-07:00" level=info msg="Executing `arduino-cli daemon`"
Daemon is now listening on 127.0.0.1:63046
{"IP":"127.0.0.1","Port":"63046"}
2024-05-13T19:57:22.445Z daemon INFO Daemon is running.
2024-05-13T19:57:22.504Z daemon INFO time="2024-05-13T12:57:22-07:00" level=info msg="Updating libraries index"
2024-05-13T19:57:22.505Z daemon INFO time="2024-05-13T12:57:22-07:00" level=info msg="Starting download" url="https://downloads.arduino.cc/libraries/library_index.tar.bz2"
2024-05-13T19:57:23.068Z root INFO Deploy plugins list: 43.4 ms [Finished 1.233 s after backend start]
Opening channel for service path '/services/electron-window'.
Opening channel for service path '/services/ide-updater'.
2024-05-13T19:57:23.951Z root WARN Frontend a.configure took longer than the expected maximum 100 milliseconds: 137.5 ms [Finished 1.504 s after frontend start]
2024-05-13T19:57:23.951Z root WARN A command editor.action.toggleStickyScroll is already registered.
2024-05-13T19:57:24.661Z root ERROR Detected an error response during the gRPC core client initialization: code: 3, message: Error verifying signature: openpgp: signature expired
2024-05-13T19:57:24.669Z daemon INFO time="2024-05-13T12:57:24-07:00" level=info msg="Checking signature" index="C:\\Users\\jmwau\\AppData\\Local\\Arduino15\\package_index.json" signatureFile="C:\\Users\\jmwau\\AppData\\Local\\Arduino15\\package_index.json.sig" trusted=true
2024-05-13T19:57:24.670Z daemon INFO time="2024-05-13T12:57:24-07:00" level=info msg="Loading hardware from: C:\\Users\\jmwau\\AppData\\Local\\Arduino15\\packages"
2024-05-13T19:57:24.671Z daemon INFO time="2024-05-13T12:57:24-07:00" level=info msg="Loading package builtin from: C:\\Users\\jmwau\\AppData\\Local\\Arduino15\\packages\\builtin"
time="2024-05-13T12:57:24-07:00" level=info msg="Checking existence of 'tools' path: C:\\Users\\jmwau\\AppData\\Local\\Arduino15\\packages\\builtin\\tools"
time="2024-05-13T12:57:24-07:00" level=info msg="Loading tools from dir: C:\\Users\\jmwau\\AppData\\Local\\Arduino15\\packages\\builtin\\tools"
time="2024-05-13T12:57:24-07:00" level=info msg="Loaded tool" tool="builtin:ctags@5.8-arduino11"
time="2024-05-13T12:57:24-07:00" level=info msg="Loaded tool" tool="builtin:dfu-discovery@0.1.2"
time="2024-05-13T12:57:24-07:00" level=info msg="Loaded tool" tool="builtin:mdns-discovery@1.0.9"
2024-05-13T19:57:24.671Z daemon INFO time="2024-05-13T12:57:24-07:00" level=info msg="Loaded tool" tool="builtin:serial-discovery@1.4.0"
2024-05-13T19:57:24.671Z daemon INFO time="2024-05-13T12:57:24-07:00" level=info msg="Loaded tool" tool="builtin:serial-monitor@0.14.1"
2024-05-13T19:57:24.671Z daemon INFO time="2024-05-13T12:57:24-07:00" level=info msg="Loading libraries index file" index="C:\\Users\\jmwau\\AppData\\Local\\Arduino15\\library_index.json"
2024-05-13T19:57:24.672Z daemon INFO time="2024-05-13T12:57:24-07:00" level=info msg="Adding libraries dir" dir="C:\\Users\\jmwau\\AppData\\Local\\Arduino15\\libraries" location=ide
2024-05-13T19:57:24.672Z daemon INFO time="2024-05-13T12:57:24-07:00" level=info msg="Adding libraries dir" dir="C:\\Users\\jmwau\\OneDrive\\Documents\\Arduino\\libraries" location=user
2024-05-13T19:57:24.673Z root ERROR Detected an error response during the gRPC core client initialization: code: 9, message: Loading index file: reading library_index.json: open C:\Users\jmwau\AppData\Local\Arduino15\library_index.json: The system cannot find the file specified.
2024-05-13T19:57:24.678Z root ERROR The primary packages indexes are missing. Running indexes update before initializing the core gRPC client The index of the cores and libraries must be updated before initializing the core gRPC client.
The following problems were detected during the gRPC client initialization:
[library-index] - code: 9, message: Loading index file: reading library_index.json: open C:\Users\jmwau\AppData\Local\Arduino15\library_index.json: The system cannot find the file specified.

2024-05-13T19:57:24.679Z daemon INFO time="2024-05-13T12:57:24-07:00" level=info msg="Updating libraries index"
2024-05-13T19:57:24.680Z daemon INFO time="2024-05-13T12:57:24-07:00" level=info msg="Starting download" url="https://downloads.arduino.cc/libraries/library_index.tar.bz2"
2024-05-13T19:57:24.681Z root INFO core-client-provider [library-index] Downloading index: library_index.tar.bz2

2024-05-13T19:57:27.210Z daemon INFO time="2024-05-13T12:57:27-07:00" level=info msg="Updating libraries index"
2024-05-13T19:57:27.212Z daemon INFO time="2024-05-13T12:57:27-07:00" level=info msg="Starting download" url="https://downloads.arduino.cc/libraries/library_index.tar.bz2"
2024-05-13T19:57:29.772Z root ERROR Detected an error response during the gRPC core client initialization: code: 3, message: Error verifying signature: openpgp: signature expired
2024-05-13T19:57:29.780Z daemon INFO time="2024-05-13T12:57:29-07:00" level=info msg="Checking signature" index="C:\\Users\\jmwau\\AppData\\Local\\Arduino15\\package_index.json" signatureFile="C:\\Users\\jmwau\\AppData\\Local\\Arduino15\\package_index.json.sig" trusted=true
2024-05-13T19:57:29.784Z daemon INFO time="2024-05-13T12:57:29-07:00" level=info msg="Loading hardware from: C:\\Users\\jmwau\\AppData\\Local\\Arduino15\\packages"
2024-05-13T19:57:29.786Z daemon INFO time="2024-05-13T12:57:29-07:00" level=info msg="Loading package builtin from: C:\\Users\\jmwau\\AppData\\Local\\Arduino15\\packages\\builtin"
time="2024-05-13T12:57:29-07:00" level=info msg="Checking existence of 'tools' path: C:\\Users\\jmwau\\AppData\\Local\\Arduino15\\packages\\builtin\\tools"
time="2024-05-13T12:57:29-07:00" level=info msg="Loading tools from dir: C:\\Users\\jmwau\\AppData\\Local\\Arduino15\\packages\\builtin\\tools"
time="2024-05-13T12:57:29-07:00" level=info msg="Loaded tool" tool="builtin:ctags@5.8-arduino11"
time="2024-05-13T12:57:29-07:00" level=info msg="Loaded tool" tool="builtin:dfu-discovery@0.1.2"
time="2024-05-13T12:57:29-07:00" level=info msg="Loaded tool" tool="builtin:mdns-discovery@1.0.9"
time="2024-05-13T12:57:29-07:00" level=info msg="Loaded tool" tool="builtin:serial-discovery@1.4.0"
time="2024-05-13T12:57:29-07:00" level=info msg="Loaded tool" tool="builtin:serial-monitor@0.14.1"
time="2024-05-13T12:57:29-07:00" level=info msg="Loading libraries index file" index="C:\\Users\\jmwau\\AppData\\Local\\Arduino15\\library_index.json"
time="2024-05-13T12:57:29-07:00" level=info msg="Adding libraries dir" dir="C:\\Users\\jmwau\\AppData\\Local\\Arduino15\\libraries" location=ide
time="2024-05-13T12:57:29-07:00" level=info msg="Adding libraries dir" dir="C:\\Users\\jmwau\\OneDrive\\Documents\\Arduino\\libraries" location=user
2024-05-13T19:57:29.786Z root ERROR Detected an error response during the gRPC core client initialization: code: 9, message: Loading index file: reading library_index.json: open C:\Users\jmwau\AppData\Local\Arduino15\library_index.json: The system cannot find the file specified.
2024-05-13T19:57:29.786Z root ERROR Uncaught Exception:  Error: The index of the cores and libraries must be updated before initializing the core gRPC client.
The following problems were detected during the gRPC client initialization:
[library-index] - code: 9, message: Loading index file: reading library_index.json: open C:\Users\jmwau\AppData\Local\Arduino15\library_index.json: The system cannot find the file specified.

2024-05-13T19:57:29.786Z root ERROR Error: The index of the cores and libraries must be updated before initializing the core gRPC client.
The following problems were detected during the gRPC client initialization:
[library-index] - code: 9, message: Loading index file: reading library_index.json: open C:\Users\jmwau\AppData\Local\Arduino15\library_index.json: The system cannot find the file specified.

    at C:\Program Files\Arduino IDE\resources\app\lib\backend\main.js:2:622877
    at E.evaluateErrorStatus (C:\Program Files\Arduino IDE\resources\app\lib\backend\main.js:2:622893)
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
    at async a.<anonymous> (C:\Program Files\Arduino IDE\resources\app\lib\backend\main.js:2:622563)
Closing channel on service path '/services/electron-window'.
Closing channel on service path '/services/ide-updater'.
Stored workspaces roots:
No sketches were scheduled for deletion.

2024-05-13T19:57:29.772Z root ERROR Detected an error response during the gRPC core client initialization: code: 3, message: Error verifying signature: openpgp: signature expired

This "Error verifying signature: openpgp: signature expired" error occurs when your system time is incorrect. You can fix it by syncing the system time.
I'll provide instructions you can follow to do that:

Right click the Windows Start icon (⊞) on the taskbar.
A context menu will open.
Select "Settings" from the context menu.
Windows "Settings" will open.
Select "Time & language" from the navigation panel on the left side of the window.
Select "Date & time" from the list on the right side of the Settings window.
The Date & time settings section will expand.
Click the "Sync now" button that is under the "Additional settings" section of the page.
Wait for the time syncing process to finish.
Close any Arduino IDE windows that are open.
Start Arduino IDE again.

This time Arduino IDE should start up fully and work as expected.

I have this same issue except the fix noted above does not work for me. I just get a constant pulsing Arduino logo.

@TexasT this answer is specific to the case where startup hangs AND the "Error verifying signature: openpgp: signature expired" error message is present in the logs. There are other causes of Arduino IDE startup hanging. Since you don't have enough information to formulate a high quality Stack Exchange question, please request assistance over on https://forum.arduino.cc/. That will be a more suitable platform for supporting you.


text:
Why does static member std::map reset ESP8266 when outside the .ino file?
Here's an example of a class which crashes the ESP8266-03 causing it to reset:
Test.hpp file:
#include <map>

class Test {
public:
    int data() const;

    Test(int x);
    ~Test();
protected:
    int _data;

    static std::map<int, Test const *>thing;

    static void _Reserve(Test const * const t);
};

Test.cpp file:
std::map<int, Test const *> Test::thing;

int Test::data() const
{
    return this->_data;
}

void Test::_Reserve(Test const * const t) {
    Test::thing[t->data()] = t; // Works fine if this line is removed.
}

Test::Test(int x): _data(x)
{
    Test::_Reserve(this);
}

Test::~Test() {};

Project.ino:
#include "ESP8266WiFi.h"
#include "Test.hpp"

Test test(2);

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

void loop() {
    Serial.print("Timer: ");
    Serial.println(millis());
    delay(1000);
}

The following does NOT crash the ESP8266-03 and prints the time as it should:
#include "ESP8266WiFi.h"
#include <map>

class Test {
public:
    int data() const
    {
        return this->_data;
    }

    Test(int x): _data(x)
    {
        Test::_Reserve(this);
    }
    ~Test() {};
protected:
    int _data;

    static std::map<int, Test const *>thing;

    static bool _Reserve(Test const * const t) {
        Test::thing[t->data()] = t;
    }
};

std::map<int, Test const *> Test::thing;

Test test(2);

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

void loop() {
    Serial.print("Timer: ");
    Serial.println(millis());
    delay(1000);
}

When the first version is uploaded to the board, I get the following in the serial monitor:
 ets Jan  8 2013,rst cause:1, boot mode:(1,7)

 ets Jan  8 2013,rst cause:4, boot mode:(1,7)

wdt reset

When I reset it and boot it regularly, no upload mode, the following repeats every ~1 second:
 ets Jan  8 2013,rst cause:1, boot mode:(3,7)

load 0x4010f000, len 1384, room 16
tail 8
chksum 0x2d
csum 0x2d
v09f0c112
~ld

Does accessing a static POD variable cause the same issue?

@Matt I believe I haven't tried that, but will check later on today. It's a bit strange since removing that line with a comment works fine. I can even add the same line to another method in the class (such as a new setData method, in that example up there) and it works properly... If I make the variable public, I can access it properly as well from outside the class. It probably has something to do with the constructor.

Why does static member std::map reset ESP8266 when outside the .ino file?

What happens if the Test() constructor is run before the map constructor? This is the problem: you are assuming order of execution.
Use a Singleton pattern or init() member function to force the ordering that is required.
Cheers!

Like you said, it was an initialization issue. Turns out the Test instance in the first example is considered static, making it run before std::map is initialized since it's static code is in another translation unit (another file),  but I think this comment better explains the reason for the problem: http://stackoverflow.com/a/26996015/3342154

source: Stack Exchange

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

sort: votes


text:
Too low voltage on digital input on attiny45
I'm using one of my attiny's pins as digital input. I use it with a pulldown resistor. As input I use simple square wave generated by a separate waveform generator. igh state for square wave is 5V, low is 0V.
However, when I look at the voltage on the digital input, voltage of high state is below 2V, while low state is 0V. My arduino doesnt detect high state as "1".
Here is the code:
/*
 * Sketch for testing sleep mode with wake up on WDT.
 * Donal Morrissey - 2011.
 * ATTINY85
 */

#include <TinyWireM.h>                  // I2C Master lib for ATTinys which use USI - comment this out to use with standard arduinos
#include <LiquidCrystal_attiny.h>          // for LCD w/ GPIO MODIFIED for the ATtiny85

#include <avr/sleep.h>
#include <avr/power.h>
#include <avr/wdt.h>

//uwaga na numer pinu! nie używać tego z resetem
#define STATUS_PIN  1
#define IN_PIN     4
#define LOOP_TIME 5000
#define TIMEOUT 100

#define GPIO_ADDR     0x27
LiquidCrystal_I2C lcd(GPIO_ADDR, 16, 2); // set address & 16 chars / 2 lines

/* f_wdt is a flag used to monitor watchdog status */
volatile int f_wdt=1;

/***************************************************
 *  Name:        ISR(WDT_vect)
 *
 *  Returns:     Nothing.
 *
 *  Parameters:  None.
 *
 *  Description: Watchdog Interrupt Service. This
 *               is executed when watchdog timed out.
 *
 ***************************************************/
ISR( WDT_vect){
  if(f_wdt == 0){
    f_wdt=1;
  }
  else{
  }
}

/***************************************************
 *  Name:        enterSleep
 *
 *  Returns:     Nothing.
 *
 *  Parameters:  None.
 *
 *  Description: Enters the arduino into sleep mode.
 *
 ***************************************************/
void enterSleep(void)
{
  lcd.clear();
  lcd.print("Asleep...");

  /* Enable the WD interrupt (note no reset). */
  WDTCR |= (1<<WDIE);

  set_sleep_mode( SLEEP_MODE_PWR_DOWN );   /* EDIT: could also use SLEEP_MODE_PWR_DOWN for lowest power consumption. */
  sleep_enable();
  // Status pin goes low
  digitalWrite( STATUS_PIN, LOW );
  /* Now enter sleep mode. */
  sleep_mode();

  /* The program will continue from here after the WDT timeout*/
  sleep_disable(); /* First thing to do is disable sleep. */

  // Status pin goes low
  digitalWrite( STATUS_PIN, HIGH );

  /* Re-enable the peripherals. */
  power_all_enable();

  /* Disable the WD interrupt */
  WDTCR &= ~_BV(WDIE);
}

/***************************************************
 *  Name:        setup
 *
 *  Returns:     Nothing.
 *
 *  Parameters:  None.
 *
 *  Description: Setup for the serial comms and the
 *                Watch dog timeout.
 *
 ***************************************************/
void setup()
{
  /*  Setup the LCD */
  lcd.init();                           // initialize the lcd
  lcd.backlight();                      // Print a message to the LCD.
  lcd.clear();
  lcd.setCursor(0,0);

  /* Inform the user about initialization process */
  lcd.print("Initializing...");
  delay(1000);

  /* Config pins */
  pinMode( IN_PIN, OUTPUT );
  pinMode( STATUS_PIN, OUTPUT );

  /* Initialize pins */
  digitalWrite( STATUS_PIN, HIGH );

  /*** Setup the WDT ***/

  /* Clear the reset flag of watchdog interrupts, so that they are available again. */
  MCUSR &= ~(1<<WDRF);

  /* Enable configuration changes
   */
  WDTCR |= (1<<WDCE) | (1<<WDE);

/*
WDP3       WDP2    WDP1     WDP0         Number of WDT     Typical Time-out at
                                         Oscillator Cycles     VCC = 5.0V
  0         0      0        0             2K (2048) cycles       16 ms
  0         0      0        1             4K (4096) cycles       32 ms
  0         0      1        0             8K (8192) cycles       64 ms
  0         0      1        1            16K (16384) cycles    0.125 s
  0         1      0        0            32K (32768) cycles    0.25 s
  0         1      0        1            64K (65536) cycles    0.5 s
  0         1      1        0            128K (131072) cycles 1.0 s
  0         1      1        1            256K (262144) cycles 2.0 s
  1         0      0        0            512K (524288) cycles 4.0 s
  1         0      0        1            1024K (1048576) cycles 8.0 s
*/
  /* set new watchdog timeout prescaler value */
  WDTCR =  0<<WDP3 | 1<<WDP2 | 1<<WDP1 | 0<<WDP0 ;

  lcd.clear();
  lcd.print("Initialisation");
  lcd.setCursor(0,1);
  lcd.print("complete.");
  delay(500);
}

/***************************************************
 *  Name:        enterSleep
 *
 *  Returns:     Nothing.
 *
 *  Parameters:  None.
 *
 *  Description: Main application loop.
 *
 ***************************************************/
void loop()
{
  if(f_wdt == 1)
  {
    lcd.clear();
    lcd.print("Awake!");
    int start = millis();
    int end = 0;
    bool movement = false;
    int read = 0;
    lcd.clear();
    lcd.print( "Executing loop" );
    do{
      if( read = digitalRead(IN_PIN) ){
        lcd.setCursor(0,1);
        lcd.print( "Read value: " );
        lcd.print( read );

        //Wait for falling edge
        while( digitalRead(IN_PIN) != 0 );
        //Start counting time
        int endMov = 0;
        int startMov = millis();
        do{
          if( digitalRead( IN_PIN ) ){
            movement = true;
          }
          endMov=millis();
        }while( endMov - startMov < TIMEOUT && !movement );
            if( endMov - startMov >=LOOP_TIME ){
              lcd.clear();
              lcd.print("Time is out");
            }

            else{
              lcd.clear();
              lcd.print("Movement detected");
              lcd.setCursor(0,1);
              lcd.print( "Time: " );
              lcd.print( end-start );
            }
      }
      end=millis();
    }
    while( (end-start<LOOP_TIME) && !movement );

    if( end-start>=LOOP_TIME ){
      lcd.clear();
      lcd.print("Time is out");
    }

    else{
      lcd.clear();
      lcd.print("Movement detected");
      lcd.setCursor(0,1);
      lcd.print( "Time: " );
      lcd.print( end-start );
    }
    delay(1000);
    /* Don't forget to clear the flag. */
    f_wdt = 0;
    /* Re-enter sleep mode. */
    enterSleep();
  }
  else
  {
    /* Do nothing. */
  }
}

Does anyone has any idea why is it so?

Ideas, yes, but since you don't tell name or model number of  waveform generator, or the value of the pulldown resistor, or which ATtiny, or which pin, or if anything else is in the circuit, who can say?  Please edit your question to include that information.

What value pulldown resistor? What is the output impedance of your waveform generator?

First thing in my mind would be to check/change the pull-down resistor value.
The pull-down resistor must have a larger resistance than the impedance of the logic circuit, or else it might be able to pull the voltage down by too much and the input voltage at the pin would remain at a constant logical low value
Read more here.

I changed the pull down resistor to 360 ohms and 100k ohms, but it did not change a thing, unfortunately. Voltage levels are still too low.

Typical pull-down resistors 4.7K and 10K. But, it is also depending on your device connected to the pin. Do you know the impedance of your waveform generator?
And another thing is how you set-up the pin in your firmware? Can you show us your code?

Impedance of my waveform generator is close to 0 ohms. I edited the post, code is available now

Are you sure you use that Pin as INPUT;
This line;
pinMode( IN_PIN, OUTPUT );
should be
pinMode( IN_PIN, INPUT );

Oh my god, this is embarassing... Thanks:) Now it works

Good to hear that, I know this feeling, you are not alone ;)

But last note, I hope you are using some sort of protection for your input since the wave generator output can swing also in negative area which is not good for your uC. 1N4733A from input to GND will protect from this. And additionally a serial resistor (1K) to your generator would be good for your input.

So you suggest to put a zener diode between input pin and gnd?

Yes, it is zener diode, Anode to GND and Cathode to input #4.
Note that: please confirm my comment as your answer.

if the generator is close to zero ohms, how much current would such a diode arrangement draw from the generator?

@Dandavis: Since the zener diode will dissipate through the 1k resistor, it won't be more than appx. 5 mA.
We can  also replace that resistor with equivalence resettable fuse.

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


text:
compare char receive from Slave writer to Master reader with I2C
Im trying to send data from slave (writer) to master (reader) then compare it to declared 'char p[]' to turn on the lights but somehow i cant make it work.
////master reader

    #include <Wire.h>

int LED = 13;
char p[] = "YES...";

void setup() {
  pinMode(LED, OUTPUT);
  Wire.begin();        // join i2c bus (address optional for master)
  Serial.begin(9600);  // start serial for output

}

void loop() {
  Wire.requestFrom(8, 6);    // request 6 bytes from slave device #8

  while (Wire.available()) { // slave may send less than requested
    char c= Wire.read(); // receive a byte as character

  Serial.print(c);         // print the character

  if(c == p){

  digitalWrite(LED, HIGH);   // turn the LED on (HIGH is the voltage level)

    }else{

  digitalWrite(LED, LOW);   // turn the LED on (HIGH is the voltage level)

          }

  }

  delay(1500);

Slave
//////////////     Slave       ///////////////////////

    #include <Wire.h>

const int pingPin = 8; // Trigger Pin of Ultrasonic Sensor
const int echoPin = 9; // Echo Pin of Ultrasonic Sensor

void setup() {
  Serial.begin(9600); // Starting Serial Terminal
  Wire.begin(8);                // join i2c bus with address #8

}

void loop() {
   long duration, inches, cm;
   pinMode(pingPin, OUTPUT);
   digitalWrite(pingPin, LOW);
   delayMicroseconds(2);
   digitalWrite(pingPin, HIGH);
   delayMicroseconds(10);
   digitalWrite(pingPin, LOW);
   pinMode(echoPin, INPUT);
   duration = pulseIn(echoPin, HIGH);
   inches = microsecondsToInches(duration);
   cm = microsecondsToCentimeters(duration);
   Serial.print(inches);
   Serial.print("in, ");
   Serial.print(cm);
   Serial.print("cm");
   Serial.println();
   delay(1500);

if( inches <= 4){

  Wire.onRequest(requestEvent); // register event
   Serial.print("Obstacle detected");
   Serial.println();
  }
  else
  {

  Wire.onRequest(requestEvent1); // register event
   Serial.print("Nothing Detected");
   Serial.println();

    }

}

// function that executes whenever data is requested by master
// this function is registered as an event, see setup()
void requestEvent() {

  Wire.write("YES..."); // respond with message of 6 bytes
  // as expected by master
}
void requestEvent1() {

  Wire.write("NO...."); // respond with message of 6 bytes
  // as expected by master
}

long microsecondsToInches(long microseconds) {
   return microseconds / 74 / 2;
}

long microsecondsToCentimeters(long microseconds) {
   return microseconds / 29 / 2;
}

Improve you indentation.
If you want to compare two strings use strcmp function for that.
Your master part has some brackets left in your void loop() function, correct them.
In I2C you are receiving one byte at time. You should receive data till the last byte in received.
You should have some identification in your message, which is you are sending from slave to master indicating that this is last character. It helps you come out of Data reception loop in Master side.

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


text:
output not declaired.anyone please help me to fix this problem
output not declaired.anyone please help me to fix this problem
int const trigpin=10;
int const echopin=9;
int const buzzpin=2;
void setup()
{
  {
  Serial.begin(9600);
 }
  pinmode(trigpin,output);
  pinmode(echopin,input);
  pinmode(buzzpin,output);
}
void loop()
{
  long int duration,distance;
  digitalwrite(trigpin,high);
  delaymicroseconds(1000);
  digitalwrite(trigpin,low);
  duration=pulsein(echopin,high);
  distance=(duration/2)/29.1;
  Serial.print(distance);
  Serial.println("CH");
  if(distance<=50)
   {
    digitalwrite(buzzpin,high);
   }
   else if(distance>50)
   {
    digitalwrite(buzzpin,low);
   }
   delay(60);
}

To be used in the pinMode function (note capital M), it needs to be all capitals, ie OUTPUT.
From a quick scan, you might also need the following changes:
output ==> OUTPUT
input ==> INPUT
pinmode  ==> pinMode
digitalwrite ==> digitalWrite
delaymicroseconds ==> delayMicroseconds
Make sure your code matches the case (uppercase/lowercase) of the examples/tutorials etc.

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


text:
Why my serial message won't show on another when I try use 2 Arduino communication
I am trying to make a simple chatting program with my 2 arduino uno and 2 PC. But when I tried write a message using PC1 serial monitor the message won't show up on PC2 serial monitor. I can't see the problem or maybe I miss something on the program.
Here is my code:
PC1:
#include <SoftwareSerial.h>

SoftwareSerial Serial1(10,11);

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

void loop()
{
    if ( Serial.available()) // Check to see if at least one character is available
    {
        char ch1 = Serial.read();
        Serial1.print(ch1);
    }

    delay(200);
}

PC2:
#include <SoftwareSerial.h>

SoftwareSerial Serial1(10,11);

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

void loop()
{
    if (Serial1.available())
    {
        char ch = Serial1.read();
        Serial.print(ch);
    }
}

did you cross the wires RX to TX? use write not print

Yeah I wires RX to TX. So I should use write instead print?

The delay(200) is not necessary -- why is it there? It just creates annoying delays in the output

Did you tie the grounds together?

I see maybe I can just remove the code then

Try out this thing. It may be helpful for concept purpose. link

I haven't tested this in a while but it has been my experience that even though you can have multiple IDE windows open, you can only have one Serial Monitor at a time. The way I got around this is to use a Terminal Emulator program for the second Arduino.


text:
Data is not sending to Thingspeak using SIM900 with an interrupt in the code
I'm currently working in a weather station with online recording on Thingspeak. When I send a set of parameters (T, Pressure, Humidity, light), I don't have any problem with sending data. But when I add to the code the rain parameter, the code doesn't send the data. The rain parameter is calculated based on an interrupt, so could this affect my data sending? It is any trick that I can use to solve it?
The code:
#include <Wire.h>
#include <SoftwareSerial.h>
#include <String.h>

SoftwareSerial Sim900Serial(9,11);//Configarión de los pines serial por software: RX, TX

Weather myHumidity;//Create an instance of the humidity sensor

const byte RAIN = 2;

volatile int pulse_counter_ISR;
float mm;
volatile unsigned long raintime, rainlast, raininterval, rain;

float humidity = 0; // [%]

void setup() {
  Serial.begin(19200);
  Sim900Serial.begin(19200);//Arduino se comunica con el SIM900 a una velocidad de 19200bps
  Sim900Serial.println("AT+IPR=19200");    // Tell the SIM900 not to autobaud

  Wire.begin();

  pinMode(RAIN, INPUT_PULLUP); // input from wind meters rain gauge sensor
  digitalWrite(RAIN, HIGH);

  myHumidity.begin();

  // attach external interrupt pins to IRQ functions
  attachInterrupt(0, interrupt_handler, FALLING);

  // turn on interrupts
  interrupts();

}

void loop() {
 calcWeather();
 comandosAT();
 delay(600000);
}

void calcWeather()
{
//Calc humidity
humidity = myHumidity.getRH();

//Calculate amount of rainfall for the last 10 minutes
mm = pulse_counter_ISR*0.2794;
pulse_counter_ISR = 0;

}

void comandosAT(){
Sim900Serial.println("AT+CIPSTATUS");//Consultar el estado actual de la conexión
delay(2000);
Sim900Serial.println("AT+CIPMUX=0");//comando configura el dispositivo para    una conexión IP única o múltiple 0=única
delay(3000);
mostrarDatosSeriales();
Sim900Serial.println("AT+CSTT=\"internet.simple\"");
delay(1000);
mostrarDatosSeriales();
Sim900Serial.println("AT+CIICR");//REALIZAR UNA CONEXIÓN INALÁMBRICA CON GPRS O CSD
delay(3000);
mostrarDatosSeriales();
Sim900Serial.println("AT+CIFSR");// Obtenemos nuestra IP local
delay(2000);
mostrarDatosSeriales();
Sim900Serial.println("AT+CIPSPRT=0");//Establece un indicador '>' al enviar datos
delay(3000);
mostrarDatosSeriales();
Sim900Serial.println("AT+CIPSTART=\"TCP\",\"api.thingspeak.com\",\"80\"");//Indicamos el tipo de conexión, url o dirección IP y puerto al que realizamos la conexión
delay(6000);
mostrarDatosSeriales();
Sim900Serial.println("AT+CIPSEND");//ENVÍA DATOS A TRAVÉS DE una CONEXIÓN TCP O UDP
delay(4000);
mostrarDatosSeriales();
String datos="GET https://api.thingspeak.com/update?api_key=MYAPIKEY&field1=0" + String(humidity) + "&field2=0" + String(mm);
Sim900Serial.println(datos);//Envía datos al servidor remoto
delay(4000);
mostrarDatosSeriales();
Sim900Serial.println((char)26);
delay(5000);//Ahora esperaremos una respuesta pero esto va a depender de las condiones de la red y este valor quizá debamos modificarlo dependiendo de las condiciones de la red
Sim900Serial.println();
mostrarDatosSeriales();
Sim900Serial.println("AT+CIPSHUT");//Cierra la conexión(Desactiva el contexto GPRS PDP)
delay(5000);
mostrarDatosSeriales();
}

void mostrarDatosSeriales()//Muestra los datos que va entregando el sim900
{
while(Sim900Serial.available()!=0)
Serial.write(Sim900Serial.read());
}

void interrupt_handler()
{
  pulse_counter_ISR = pulse_counter_ISR + 1;
}

so could this affect my data sending? .... run a test to find out for sure

Did you forget to include a library from Sparkfun?

I run it and works, with and without interrupt(), but when I add more variables (4 or more) the AT-CIPSEND do not send the datas

Finally I split the comands in two functions (comandosAT_1 and comandosAT_2) with different variables. The first one do not works and the socond one works fine. Here are the code

Finally I split the comands in two functions (comandosAT_1 and comandosAT_2) with different variables. The first one do not works and the socond one works fine. Here are the code
void comandosAT_1(){
Sim900Serial.println("AT+CIPSTATUS");//Consultar el estado actual de la conexión
delay(2000);
Sim900Serial.println("AT+CIPMUX=0");//comando configura el dispositivo para una conexión IP única o múltiple 0=única
delay(3000);
mostrarDatosSeriales();
Sim900Serial.println("AT+CSTT=\"internet.simple\"");//comando configura el APN, nombre de usuario y contraseña."gprs.movistar.com.ar","wap","wap"->Movistar Arg.
delay(1000);
mostrarDatosSeriales();
Sim900Serial.println("AT+CIICR");//REALIZAR UNA CONEXIÓN INALÁMBRICA CON GPRS O CSD
delay(3000);
mostrarDatosSeriales();
Sim900Serial.println("AT+CIFSR");// Obtenemos nuestra IP local
delay(2000);
mostrarDatosSeriales();
Sim900Serial.println("AT+CIPSPRT=0");//Establece un indicador '>' al enviar datos
delay(3000);
mostrarDatosSeriales();
Sim900Serial.println("AT+CIPSTART=\"TCP\",\"api.thingspeak.com\",\"80\"");//Indicamos el tipo de conexión, url o dirección IP y puerto al que realizamos la conexión
delay(6000);
mostrarDatosSeriales();
Sim900Serial.println("AT+CIPSEND");//ENVÍA DATOS A TRAVÉS DE una CONEXIÓN TCP O UDP
delay(4000);
mostrarDatosSeriales();
String datos="GET https://api.thingspeak.com/update?api_key=XXXXXXXXXXXXX&field1=0" + String(tempC) + "&field2=0" + String(humidity) + "&field3=0" + String(pressure);
Sim900Serial.println(datos);//Envía datos al servidor remoto
delay(4000);
mostrarDatosSeriales();
Sim900Serial.println((char)26);
delay(5000);//Ahora esperaremos una respuesta pero esto va a depender de las condiones de la red y este valor quizá debamos modificarlo dependiendo de las condiciones de la red
Sim900Serial.println();
mostrarDatosSeriales();
Sim900Serial.println("AT+CIPSHUT");//Cierra la conexión(Desactiva el contexto GPRS PDP)
delay(5000);
mostrarDatosSeriales();
}

void comandosAT_2(){
Sim900Serial.println("AT+CIPSTATUS");//Consultar el estado actual de la conexión
delay(2000);
Sim900Serial.println("AT+CIPMUX=0");//comando configura el dispositivo para una conexión IP única o múltiple 0=única
delay(3000);
mostrarDatosSeriales();
Sim900Serial.println("AT+CSTT=\"internet.simple\"");//comando configura el APN, nombre de usuario y contraseña."gprs.movistar.com.ar","wap","wap"->Movistar Arg.
delay(1000);
mostrarDatosSeriales();
Sim900Serial.println("AT+CIICR");//REALIZAR UNA CONEXIÓN INALÁMBRICA CON GPRS O CSD
delay(3000);
mostrarDatosSeriales();
Sim900Serial.println("AT+CIFSR");// Obtenemos nuestra IP local
delay(2000);
mostrarDatosSeriales();
Sim900Serial.println("AT+CIPSPRT=0");//Establece un indicador '>' al enviar datos
delay(3000);
mostrarDatosSeriales();
Sim900Serial.println("AT+CIPSTART=\"TCP\",\"api.thingspeak.com\",\"80\"");//Indicamos el tipo de conexión, url o dirección IP y puerto al que realizamos la conexión
delay(6000);
mostrarDatosSeriales();
Sim900Serial.println("AT+CIPSEND");//ENVÍA DATOS A TRAVÉS DE una CONEXIÓN TCP O UDP
delay(4000);
mostrarDatosSeriales();
String datos="GET https://api.thingspeak.com/update?api_key=XXXXXXXXXXXXX&field4=0" +  String(light_lvl) + "&field5=0" + String(mm) + "&field6=0" + String(windspeed_KMH);
Sim900Serial.println(datos);//Envía datos al servidor remoto
delay(4000);
mostrarDatosSeriales();
Sim900Serial.println((char)26);
delay(5000);//Ahora esperaremos una respuesta pero esto va a depender de las condiones de la red y este valor quizá debamos modificarlo dependiendo de las condiciones de la red
Sim900Serial.println();
mostrarDatosSeriales();
Sim900Serial.println("AT+CIPSHUT");//Cierra la conexión(Desactiva el contexto GPRS PDP)
delay(5000);
mostrarDatosSeriales();
}

And the first answer of the serial monitor is the following:
OK
AT+CIPSTATUS
OK
STATE: IP INITIAL
AT+AT+CSTT="internet.simple"
OK
AT+CIICR
OK
AT+CIFSR
10.254.14.23
AT+CIPSPRT=0
OK
AT+CIPSTART="TCP","api.thingspeak.com","80"
OK
CONNECT OKAT+CIPSEND
SEND OK
AT+CIPSHUT
SHUT OK
And the socond one is (that works)
AT+CIPSTATUS
OK
STATE: IP INITIAL
AT+CIPMUX=0
OK
AT+CSTT="internet.simple"
OK
AT+CIICR
OK
AT+CIFSR
10.110.2.23
AT+CIPSPRT=0
OK
AT+CIPSTART="TCP","api.thingspeak.com","80"
OK
CONNECT OKAT+CIPSEND
GET https://api.thingspeak.com/update?api_key=XXXXXXXXXXXXXXXXX&
SEND OK
381
AT+CIPSHUT
SHUT OK
You can see that after the AT+CIPSEND command, the SIM answer "GET https://api.thingspeak.com/update?api_key=XXXXXXXXXXXXXXXXX&" , then "SEND OK" and finally the number of the entry (381).
Any idea or suggestion?


text:
Delay function not working with ESP32
For whatever reason the delay function is not working (it is not delaying at all) with my ESP32 development board. Has anyone come across a similar issue before? It's not working with other sketches, in either the loop or set up functions. A sample sketch:
#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BNO055.h>
#include <utility/imumaths.h>
#include <BleMouse.h>

// mouse object
BleMouse ble("test", "me");

/** I2C pins **/
#define I2C_SDA 33
#define I2C_SCL 32

// I2C object
TwoWire wire_custom = TwoWire(0);

// Sensor object
Adafruit_BNO055 bno = Adafruit_BNO055(55, 0x28, &wire_custom);

/**************************************************************************/
function definitions
...

/**************************************************************************/
void setup(void)
{
  wire_custom.begin(I2C_SDA, I2C_SCL, 400000);

  Serial.begin(115200);

  ble.begin();

  if (!bno.begin())
  {
    Serial.print("Ooops, no BNO055 detected ... Check your wiring or I2C ADDR!");
    while (1);
  }
  delay(1000);
  bno.setExtCrystalUse(true);

  // updating range
  bno.setMode(Adafruit_BNO055::OPERATION_MODE_CONFIG);
  delay(1000);
  write_register (0x28, 0x0A, 0b00111010);
  bno.setMode(Adafruit_BNO055::OPERATION_MODE_NDOF);
  delay(10000);
  byte result = read_register (0x28, 0x0A, 1);
  Serial.print(result);
  Serial.print("\n");
  Serial.print("\n");
}

/**************************************************************************/
void loop(void)
{
  sensor_calibration ();

  sensor_data (x_placeholder, y_placeholder);

  transform_sensor_data (x_placeholder, y_placeholder, x, y);

  if (ble.isConnected()) {
    ble.move(x, y);
  }
}

What does "not working" mean? Not delaying at all? Delaying forever? Too short a delay? Too long a delay? And what makes you believe that delay() is at fault?

how do you know that the delay function does not work? ... you do not have any debugging code that would verify that

Sorry I didn't clarify it is not delaying at all regardless of what amount I set it to.

How would you know? The loop() in the above code doesn't use a delay, and has no output either.

The output is the last function which moves the mouse, and that begins immediately after uploading the code. So there is no delay between uploading the code and when the loop function starts running.

Gotta be something to do with that register you set, or the setcrystal thing or one of those libraries.  To prove it, just upload a dead simple delay sketch and see if it works then.

Yeah will have to do it, I'm actually sorry I posted this question without considering it fully yesterday. It was quite a stressful day with this as the cherry on top.

Placing a delay within any built-in function pertaining to the wireless radio will only halt operations on the Wi-Fi core or core0. Your main loop code wont be affected by a delay placed in core0. It will only halt wireless operations.
I ran into a similar issue and it took a while for me to put it together. I use global variables when passing info between core0 and core1.

Wireless runs on core0 and
Your main code runs on core1 (unless otherwise specified in the setup).

How is this relevant to the question?


text:
How to use float data from a sensor with the Arduino mouse library
I'm using a gyroscope, which returns angular velocity in floats. I'm trying to use this data with the arduino mouse library. The move function requires a signed character. I'm not what the best way is to convert the float data from the sensor into signed char.
In what way can I do this, losing the least in terms of precision?
I found out you can use dtostrf to transfer floats into an array of characters, but not sure what to do following this or if it's even the best way.
I would appreciate any guidance.

this appears to be a general C++ programming question, not an Arduino related question ... please do your research in the C++ language realm

Besides data type concerns, there are scaling concerns. Exactly what does the signed char represent for the mouse move function? What mouse library are you using? What range of float values might you get from the gyroscope? If it's, for example, -300.0 to +300.0 then you'll at least need to scale that down before converting to a char-sized integer.

this should help https://duckduckgo.com/?q=c%2B%2B+float+to+signed&ia=web

Thanks for the responses. Scaling will be necessary as the values do tend to be in the 300 range maximum per sample size. The signed character of the standard arduino library represents the amount of movement on screen, relative to the previous cursor position. I did try researching this in both the C++ and arduino realms, but couldn't find the answer so I decided to try asking.

The mouse library expects the movement coordinates to be provided as
8-bit signed integers, which corresponds to the int8_t data type. This
type is actually an alias to signed char, but calling it this way is
confusing, as the word char somehow implies a type meant to store
characters, which is definitely not the case here.
Converting a float to any integer type can be done by plain
assignment, with two caveats:

If the float exceeds the range of the integer, the assignment will
wrap around modulo 2^(integer size in bits). This is undesirable and
can be prevented by first constrain()ing the float to the
appropriate range.
The assignment rounds towards zero, whereas rounding to the nearest
integer is better if you want to minimize the errors. This can be
achieved with the round() macro.

In summary:
// In global context:
const float scale = 0.4;  // scale factor for mouse moves

// Within loop():
float rotation = get_data_from_gyroscope();
int8_t mouse_move = round(constrain(rotation * scale, -128, +127));

Note that the optimal scale can only be determined experimentally: you
have to tweak it until your input device “feels” right.

Thank you very much again, Edgar! It feels to me this is a very important part of the implementation as you can lose the precision of the sensor in the conversion, so I'm grateful to have an expert jumping in.

You are misunderstanding the type char. It is named character, because in ASCII representation you can use it to save one character. But internally it just is a number. The Arduino doesn't care, if you save characters in it or numbers, because characters are also numbers for it.
A signed char, like the move() function of the library uses` has 1 byte and is signed, thus can hold numbers from -128 to 127.
While the documentation is not clear about what the x and y parameters really represent the answer to this question is clear about it. Basically the whole range from -128 to +127 represents a whole inch (or what the computer thinks is an inch). So this results in a resolution of 1" / (127 - -128) = 1" / 255 = 0.0039" (or about 0.1mm). I don't know, what values you are getting from the sensor, but you will have to scale it to somewhere in the -128 to 127 range (depends on how sensitive you want it to be). And you won't loose precision here. The sensor values most likely are more precise, than the range of the mouse move() function.
The calculation will then be as simple as
signed char mouse_x = sensor_x * factor + offset;

The result of the calculation will implicitly converted to a 1 byte signed integer (this is what signed char is). If you want to make it clearer what happens here, you can also write:
signed char mouse_x = (signed char)(sensor_x * factor + offset);

This is not needed, but you might wanna do it for clarity.

Seen in Edgar Bonets answer: You might wanna contrain the value of above calculation to the -128 to 127 range. If you get an unexpected high value from your sensor, the above calculation would overflow the mouse_x variable (not good for correct values). So capping the values to that range with the constrain() function is definitely good. Refer to Edgars answer and the documentation for this.

Hi Chrisl, thank you very much for the detailed response. I really appreciate you taking the time. Between your and Edgar's responses I feel like I have a much better understanding of the issue. You both should know newbies are really grateful when you help out. Or they should be!


text:
Best way to obtain angular velocity from a 9 DoF sensor
I have been using a BNO055 sensor (9° dof IMU) for a project which will use angular velocity to the mouse cursor on screen.
So far, I have gotten quaternion output from the sensor and been able to convert it to angular velocity in a couple of ways. The first, multiplying 1 quaternion sample by its conjugate in the next sample, and then converting the quaternion Delta in Euler angles. The second, converting from quaternions to Euler angles and then finding the change in those between samples.
Both methods result in angular velocity measurement, but each with their advantages and disadvantages. E.g. Quaternion Delta between samples does not suffer from gimbal lock, but it's difficult to isolate y-axis from z-axis movement.
I know that you can ask the sensor for angular velocity data directly, but apparently that's less precise due to the Gyro drift and it's relative orientation only, which is why I opted to work with quaternions.
Is there a better way to go about this?
My code included below for reference with the 2 approaches in case it's helpful/interesting. It uses the Adafruit repository, doing the standard stuff in setup function and then calling the function below in loop.
void quaternion_Delta () {
  // Quaternion data 1
  imu::Quaternion quat = bno.getQuat();
  // Euler 1
  imu::Vector<3> euler_one = quat.toEuler();
  //delay between samples
  delay(BNO055_SAMPLERATE_DELAY_MS);
  // Quaternion data 2
  imu::Quaternion quat_two = bno.getQuat();
  // Euler 2
  imu::Vector<3> euler_two = quat_two.toEuler();
  // quaternion comparison
  imu::Quaternion quatDelta = quat_two * quat.conjugate ();
  imu::Vector<3> euler = quatDelta.toEuler();
  Serial.print(" X: ");
  Serial.print(euler.x()*radius_to_degrees, 2);
  Serial.print(" Y: ");
  Serial.print(euler.y()*radius_to_degrees, 2);
  Serial.print(" Z: ");
  Serial.print(euler.z()*radius_to_degrees, 2);
  Serial.print("\t\t");
  // Euler comparison
  imu::Vector<3> euler_comparison = euler_two - euler_one;
  Serial.print(" x: ");
  Serial.print(euler_comparison.x()*radius_to_degrees, 2);
  Serial.print(" y: ");
  Serial.print(euler_comparison.y()*radius_to_degrees, 2);
  Serial.print(" z: ");
  Serial.print(euler_comparison.z()*radius_to_degrees, 2);
  Serial.print("\n");
  }

Sorry if this overlaps with any of my previous questions, I felt it was different enough that it would be more confusing to edit a already closed one. Thank you for your time.

Consider building on Sebastian Madgwick's PhD IMU research.  A GitHub Arduino project based on Madgwick's work can be found here.

Thanks for your response. The BNO sensor uses a proprietary fusion algorithm, but I've seen this implementation on a different sensor. I think my question boils down to if it's going to be more accurate to polled the sensor for quaternions from which to calculate angular velocity, or to poll the gyroscope only. Is the only difference that one is out of orientation, and the other is absolute?

I am not sure.  I have not worked with IMU chips that create quaternions.  Only with IMU chips which provide X,Y & Z values from accelerometers and gyroscopes.

There is also an Adafruit library for this and other fusion algos.


text:
How to send non char variables over serial
I'm trying to build a GUI that sends the data from processing to arduino via serial. With the help of a couple of guys on here, I have come up with a basic framework that sends a variable ID, variable value and termination character (\n). So far so good!
However, the [arduino reference][1] advises to only use char for storing characters. How would I send a byte or int over serial, while still being able to use a termination character to ensure everything is working as expected?
edit:
Using the arduino code from Edgar's answer below and the following processing code, I get the "could not parse value" error.
import processing.serial.*;

SerialConnection serialConnection;

boolean data_processed = false;
char[] var_array = new char[31];
char var_id;
char var_val;
char space = ' ';
char termchar = '\n';

void setup() {
  serialConnection = new SerialConnection(this, 9600);
}

void draw() {
  serialConnection.startSerialCommunication();

  if (serialConnection.isReady) {
    var_id = 'a';
    var_val = 127;
    serialConnection.serialPort.write(var_id);
    serialConnection.serialPort.write(space);
    serialConnection.serialPort.write(var_val);
    serialConnection.serialPort.write(termchar);

    delay(50);
    while (serialConnection.serialPort.available() > 0) {
      for (int i = 0; i < 30; i++) {
        char inchar = serialConnection.serialPort.readChar();
        var_array[i] = inchar;
        print(var_array[i]);
      }
    }
  }
}

https://www.arduino.cc/reference/en/language/variables/data-types/char/

If you want to send numeric values to your Arduino, the simplest option
is to send them formatted as ASCII text. Thus you end up simply sending
characters.
Let's assume for example a simple text-based protocol of the form
foo 42
bar 5678
baz -12

Each message is made of a variable name followed by its numeric value.
The name and the value a separated by a space. Each message is
terminated by a line feed ('\n').
In order to parse a message, you first have to split it at the space
character. The strsep() function comes handy for this. Then,
you have to parse the second part of the message (the value) as an
integer. I would use strtol() for this job. Putting all
together:
void process(char *message) {
    char *name = strsep(&message, " ");  // split at the space
    if (!message) {
        Serial.println("Error: no value given");
        return;
    }
    char *endp;  // end of the numeric value
    long value = strtol(message, &endp, 0);
    if (endp == message) {
        Serial.println("Error: could not parse value");
        return;
    }
    /* Successfully parsed. */
    Serial.print(name);
    Serial.print(" received value ");
    Serial.println(value);
}

Note there are some sanity checks in order to make sure the message does
match the expected format. Obviously, you have to replace the last three
lines by something more meaningful to your application.
Example sketch using this:
void setup() {
    Serial.begin(9600);
}

void loop() {
    static char buffer[40];
    static size_t buffer_pos = 0;
    while (Serial.available()) {
        char c = Serial.read();
        if (c == '\n') {  // end of message
            buffer[buffer_pos] = '\0';  // terminate the string
            process(buffer);
            buffer_pos = 0;  // reset for next message
        } else if (buffer_pos < sizeof buffer - 1) {
            buffer[buffer_pos++] = c;  // buffer the character
        }
    }
}

Thank you for the answer, Edgar! Sorry for the delay in responding, wanted to go through everything. I really appreciate the code example. Also, didn't even know these functions existed. If I understand what's happening correctly, you're passing by address the buffer array to the process function, which dereferences it, and is then fed into the str functions? What confuses me is, it looks like the process function takes a single char as argument, but it actually processes the whole buffer array. Is that normal C behavior when using pointers to arrays, or is specific to the str.. functions?

Also these functions have double pointers. That's crazy.

Finally, I love how elegant this code is, lots to learn here!

@ZhelyazkoGrudov: Re “If I understand what's happening correctly, you're passing by address the buffer array”: Exactly. Whenever you pass an array to a function in C or C++, it “decays” to a pointer to its first element. This “decay to pointer” behavior is generic: it affects all arrays whenever you do mostly anything with them. The str*() functions all expect a pointer to the first element of a NUL-terminated array of char. What is specific about them is that they interpret the first null char they find as the end of the string.

Great to know! Thank you for the explanation.

Sorry to bother you again Edgar, I run into the "could not parse value" error, even though from what I understand I'm sending the data in the correct format. I edited the question to include the processing code I'm using.

@ZhelyazkoGrudov: Your Processing code is sending an escape character (ASCII code 127) instead of "127". The Arduino expects an ASCII string: try sending '1', then '2', then '7'. I don't know Processing, but it is more than likely that it has a method similar to Arduino's print() that would format a number in ASCII for you. You may then write something like serialConnection.serialPort.print(127);. I don't know the exact name of the method. If you have to ask, look for some forum relevant to Processing (not here).

Thank you very much for taking the time to respond again Edgar. I really, really appreciate it.


text:
ESP32 OTA update over MQTT using "update.h"
I am trying to do OTA over MQTT using update.h library. I am publishing firmware file over MQTT in a specified chunk size. The file is receiving at ESP32 end. I am supplying the received data to update.write. In start ~150 packet are written successfully. But after that update.write started to give error Wrong Magic Byte.
Here is the code snippet which I am using inside ESP32
#include "mqtt_handler.h"
StaticJsonDocument <256> root;
uint8_t temp[100] = {0};
size_t length ;
void otaHandler(byte *msg, unsigned int len)
{
deserializeJson(root,msg);
String command = root["command"];
if (command.equals("ota.start"))
{
    Serial.println("OTA.START via MQTT");
    if (!Update.begin(UPDATE_SIZE_UNKNOWN))
    {
        Update.printError(Serial);
    }
}
else if (command.equals("ota.write"))
{
    Serial.println("OTA.WRITE via MQTT");
    memset(temp, 0, 100);
    length = root["length"];
    String data = root["data"];
    for (int i = 0; i < length; i++)
    {
        temp[i] = data[i];
    }

    Serial.println(data);
    if (Update.write(temp, length) != length)
    {
        Update.printError(Serial);
    }
}
else if (command.equals("ota.end"))
{
    Serial.println("OTA.END via MQTT");
    if (Update.end(true))
    {
        Serial.printf("Update Success \nRebooting...\n");
    }
    else
    {
        Update.printError(Serial);
    }
}
else
{
    Serial.println("Something went worng");
}
}
void callback(char* topic, byte* message, unsigned int length) {
otaHandler(message,length);
}

In this code callback is the method which is called when an MQTT message arrived.This is the relevant code, if required I can share the complete code.
Message send by python application looks like as below:
{"command" : "ota.start"}
{"command": "ota.write", "length": length, "data": data})
{"command" : "ota.end"}

Below is the snapshot of data send by Python application in above ota.write message:

Below is the snapshot how my firmware file looks like:

I am sharing this snapshot to show the data format in which I am publishing firmware file.
Below is the snapshot of serial monitor:

Please suggest me if I am missing something on this.
Thanks

The message basically means that you have not formatted your image data correctly. The first byte must always be 0xE9 (as in your firmware picture). I suspect you are sending some ASCII representation of the data and not converting that back to binary as you should.

Looking at it more closely it looks like you're just blasting a decimal ASCII representation of the data that would be absolutely impossible to parse.

Yes I am sending in decimal ASCII like 0XE9 is 233. In which format does it expect data ?? Binary  ??

It expects binary data. It is your responsibility to turn your text representation back into the binary format it started as. I would suggest using HEX as your transport layer not decimal - and use zero padding. You can't tell if 3224465 is 32 244 65 or 3 224 46 5, for example. Keep it as hex, and always 2 characters per byte, then in your C code take each pair of hex characters and convert them back to binary.

You are just throwing an unparseable stream of ASCII decimal representations of the binary data at your code, then writing that ASCII data verbatim to the flash. That can never work.
Instead you need to pick an ASCII representation of your data that is actually parseable (I would suggest sticking to HEX representation and always 2 digits, so represent 0x6 as "06"), then when you receive a packet you must convert the content back into binary before sending it to the Update library.
As it is you take a byte (for example 0xE9) and convert that to ASCII decimal, which is 223. Then you write the 2, 2 and 3 as individual bytes to the flash as ASCII, resulting in 0x32,0x32,0x33 - or printing as decimal in an unparseable stream, 505051.


text:
MAX30100 and ESP8266 NodeMCU Serial Errors
This is my final year project and for some reason, the max30100 sensor defaults to static values once the HTTP post request has been performed.
#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
#include <WiFiClient.h>
#include <Wire.h>
#include "MAX30100_PulseOximeter.h"
#include <SimpleTimer.h>

#define REPORTING_PERIOD_MS 1000

const char* ssid = "SDsouza";
const char* password = "dsouza@8104045917";
const char* serverName = "http://10.0.0.13/post-sensor-data.php";

String systolic_pressure;
String diastolic_pressure;
String pulse_rate;
String temperature_body;
String BPM;
String SpO2;

PulseOximeter pox;
uint32_t tsLastReport = 0;

SimpleTimer timer;

String sensor_data;
bool Sr;
String machineid = "MR1";
String room_number= "A1";
String bed_number= "1";

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  pinMode(16,OUTPUT);
  WiFi.begin(ssid , password);
  Serial.print("Connecting to SSID:");
  Serial.print(ssid);
  while (WiFi.status() != WL_CONNECTED)
  {
    Serial.print(".");
    delay(500);
  }
  Serial.println();
  Serial.print("Connected Successfully!!");
  Serial.println(WiFi.localIP());

  if(!pox.begin())
  {
    Serial.println("Failed");
    for(;;);
  }
  else
  {
    Serial.println("Pox Success");
  }
  pox.setOnBeatDetectedCallback(onBeatDetected);
  //pox.setIRLedCurrent(MAX30100_LED_CURR_7_6MA);
  timer.setInterval(1000L , getsendata);
}

void loop() {
  // put your main code here, to run repeatedly:
  pox.update();
  if(millis() - tsLastReport > REPORTING_PERIOD_MS)
  {
    BPM = pox.getHeartRate();
    SpO2 = pox.getSpO2();
    Serial.print("Bpm: ");
    Serial.println(BPM);
    Serial.print("SpO2: ");
    Serial.println(SpO2);
    tsLastReport = millis();
  }
  timer.run();
}

void onBeatDetected()
{
  Serial.println("Beat Detected");
}

void getsendata()
{
  while (Serial.available())
  {
    sensor_data = Serial.readString();
    Sr = true;

    int firstcommaindex = sensor_data.indexOf(",");
    int secondcommaindex = sensor_data.indexOf(",", firstcommaindex + 1);
    int thirdcommaindex = sensor_data.indexOf(",", secondcommaindex + 1);
    int fourthcommaindex = sensor_data.indexOf(",", thirdcommaindex + 1);

    systolic_pressure = sensor_data.substring(0, firstcommaindex);
    diastolic_pressure = sensor_data.substring(firstcommaindex + 1, secondcommaindex);
    pulse_rate = sensor_data.substring(secondcommaindex + 1, thirdcommaindex);
    temperature_body = sensor_data.substring(thirdcommaindex + 1);

    HTTPClient http;
    http.begin(serverName);
    http.addHeader("Content-Type" , "application/x-www-form-urlencoded");
    String httpRequestData = "machine_identifier=" + machineid + "&temp=" + temperature_body + "&hr=" + pulse_rate + "&sys_pressure=" + systolic_pressure + "&dias_pressure=" + diastolic_pressure + "&oxy_lvl=" + SpO2 + "&room_number=" + room_number + "&bed_number=" + bed_number + "";
    Serial.print("HTTP Request Data: ");
    Serial.println(httpRequestData);
    int httpResponseCode = http.POST(httpRequestData);

    if(httpResponseCode > 0)
    {
      Serial.print("HTTP Response Code: ");
      Serial.println(httpResponseCode);
    }
    else
    {
      Serial.print("Error Code: ");
      Serial.println(httpResponseCode);
    }
    http.end();

  }
}

The arduino mega is sending a string with the variable values set to 0 at startup. The MAX30100 sensor is doing its job of taking the readings however, as soon as the HTTP Post Request is done, the oximeter then defaults to it's static values and refuses to detect further readings.
Output:
This is output before HTTP Post

Output after HTTP Post

Once the http post request on arduino startup is done, or if i am taking readings from arduino after startup, the max30100 oximeter stops working and refuses to take further readings or update the values further.
The data is sent to mysql db where i will bbe fetching it on the website using php js and html css. This issue of the oximeter has been bothering me since so many days now and my final year project is nearing. Could anyone please guide me as to how to solve this problem?
Here is the library im using for the MAX30100: https://github.com/oxullo/Arduino-MAX30100

Why are you storing your numeric values in strings?

please, no screanshots of text ... add the actual text to your question

Well. Finally. Figured it out. After countless hours of googling and reading the issues on the github library, i just had to insert one line. resetFifo to reset the module after http post and re enable it to take readings normally.
Updated code:
#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
#include <WiFiClient.h>
#include <Wire.h>
#include "MAX30100.h"
#include "MAX30100_PulseOximeter.h"

#define REPORTING_PERIOD_MS 1000

MAX30100 maxim;
PulseOximeter pox;

const char* ssid = "SDsouza";
const char* password = "dsouza@8104045917";
const char* serverName = "http://10.0.0.13/post-sensor-data.php";

String systolic_pressure;
String diastolic_pressure;
String pulse_rate;
String temperature_body;
String BPM;
String SpO2;

uint32_t tsLastReport = 0;

String sensor_data;
bool Sr;
String machineid = "MR1";
String room_number= "A1";
String bed_number= "1";

HTTPClient http;

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  pinMode(16,OUTPUT);
  WiFi.begin(ssid , password);
  Serial.print("Connecting to SSID:");
  Serial.print(ssid);
  while (WiFi.status() != WL_CONNECTED)
  {
    Serial.print(".");
    delay(500);
  }
  Serial.println();
  Serial.print("Connected Successfully!!");
  Serial.println(WiFi.localIP());
  if(!pox.begin())
  {
    Serial.print("Failed");
    for(;;);
  }
  else
  {
    Serial.println("Success");
  }
  pox.setIRLedCurrent(MAX30100_LED_CURR_50MA);
  http.begin(serverName);
}

void loop() {
  // put your main code here, to run repeatedly:
    pox.update();
    if(millis() - tsLastReport > REPORTING_PERIOD_MS)
    {
      BPM = pox.getHeartRate();
      SpO2 = pox.getSpO2();
      Serial.print("Bpm: ");
      Serial.println(BPM);
      Serial.print("SpO2: ");
      Serial.println(SpO2);
      tsLastReport = millis();
    }
    while (Serial.available())
    {
      sensor_data = Serial.readString();
      Sr = true;

      int firstcommaindex = sensor_data.indexOf(",");
      int secondcommaindex = sensor_data.indexOf(",", firstcommaindex + 1);
      int thirdcommaindex = sensor_data.indexOf(",", secondcommaindex + 1);
      int fourthcommaindex = sensor_data.indexOf(",", thirdcommaindex + 1);

      systolic_pressure = sensor_data.substring(0, firstcommaindex);
      diastolic_pressure = sensor_data.substring(firstcommaindex + 1, secondcommaindex);
      pulse_rate = sensor_data.substring(secondcommaindex + 1, thirdcommaindex);
      temperature_body = sensor_data.substring(thirdcommaindex + 1);

      String httpRequestData = "machine_identifier=" + machineid + "&temp=" + temperature_body + "&hr=" + pulse_rate + "&sys_pressure=" + systolic_pressure + "&dias_pressure=" + diastolic_pressure + "&oxy_lvl=" + SpO2 + "&room_number=" + room_number + "&bed_number=" + bed_number + "";
      Serial.println(httpRequestData);
      http.addHeader("Content-Type" , "application/x-www-form-urlencoded");
      Serial.print("HTTP Request Data: ");
      Serial.println(httpRequestData);
      http.POST(httpRequestData);

      maxim.resetFifo();
    }
}

This code works flawlessly and i can now serial read from arduino, read from the oximeter and http post it to the database normally and again repeat these steps without any errors.


text:
RFM69HCW connected to Arduino Uno
I have a prototype LoRa Daughter Board that utilizes RFM69HCW transceiver module. I found an interesting blog online that covers everything courtesy of Sparkfun. Here's the link RFM69HCW Tutorial by Sparkfun 2.
I followed everything but the 2 RFM69HCW radios that I am working on didn't communicate to each other. When I checked my prototype board, DI0 of the RFM69HCW has no connection at all. Is it necessary to connect the DI0 to hardware interrupt pin of Arduino Uno? And also, can I connect it directly to the Arduino board if ever? Thanks in advance for whoever will shed light on this one.

You're saying the DIO0 pad on your breakout board doesn't connect internally to the LoRa module mounted on it?

unfortunately, yes @Majenko basically the DI0 pin in my prototype board is with no connection. Was it the reason why the RFM69HCW transceiver modules didn't communicating to each other?


text:
Code got stuck after initialization with RFM69
I'm working on RFM69 connected to an Arduino Uno. Currently, I was able to initialize the RFM69 using the a code I modified from the internet. However, my Receiver part always encounters error. It doesn't sometimes proceed and sometimes got stuck in the initialization loop. Yesterday, my Transmitter managed to work properly but today, sometimes I also observed same problem with my Receiver.
Here's my wiring.

The code I'm using for both Transmitter and Receiver
#include <SPI.h>
#include <RH_RF69.h>

/************ Radio Setup ***************/

// Change to 434.0 or other frequency, must match RX's freq!
#define RF69_FREQ 434.0

#define RFM69_CS 10
#define RFM69_INT 2
#define RFM69_RST 9
#define LED 13

// Singleton instance of the radio driver
RH_RF69 rf69(RFM69_CS, RFM69_INT);

int16_t packetnum = 0;  // packet counter, we increment per xmission

void setup()
{
  Serial.begin(9600);
  //while (!Serial) { delay(1); } // wait until serial console is open, remove if not tethered to computer

  pinMode(LED, OUTPUT);
  pinMode(RFM69_RST, OUTPUT);
  //digitalWrite(RFM69_RST, LOW);
  //from this point I added it
  digitalWrite (RFM69_RST, HIGH);
  delay (100);
  digitalWrite (RFM69_RST, LOW);
  delay (100);

  Serial.println("LoRa Daughter Board (RFM69) - Transmitter");
  Serial.println();

  // manual reset
  digitalWrite(RFM69_RST, HIGH);
  delay(10);
  digitalWrite(RFM69_RST, LOW);
  delay(10);

  if (!rf69.init()) {
    Serial.println("RFM69 Initialization Failed!");
    while (1);
  }
  Serial.println("RFM69 Initialization Success!");
  // Defaults after init are 434.0MHz, modulation GFSK_Rb250Fd250, +13dbM (for low power module)
  // No encryption
  if (!rf69.setFrequency(RF69_FREQ)) {
    Serial.println("setFrequency failed");
  }

  // If you are using a high power RF69 eg RFM69HW, you *must* set a Tx power with the
  // ishighpowermodule flag set like this:
  //rf69.setTxPower(20, true);  // range from 14-20 for power, 2nd arg must be true for 69HCW

  // The encryption key has to be the same as the one in the server
  uint8_t key[] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
                    0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08};
  rf69.setEncryptionKey(key);

  pinMode(LED, OUTPUT);

  Serial.print("RFM69 Frequency: ");  Serial.print((int)RF69_FREQ);  Serial.println(" MHz");
}

void loop() {
  delay(1000);  // Wait 1 second between transmits, could also 'sleep' here!

  char radiopacket[20] = "Hello World #";
  itoa(packetnum++, radiopacket+13, 10);
  Serial.print("Sending "); Serial.println(radiopacket);

  // Send a message!
  rf69.send((uint8_t *)radiopacket, strlen(radiopacket));
  rf69.waitPacketSent();

  // Now wait for a reply
  uint8_t buf[RH_RF69_MAX_MESSAGE_LEN];
  uint8_t len = sizeof(buf);

  if (rf69.waitAvailableTimeout(500))  {
    // Should be a reply message for us now
    if (rf69.recv(buf, &len)) {
      Serial.print("Got a reply: ");
      Serial.println((char*)buf);
      Blink(LED, 50, 3); //blink LED 3 times, 50ms between blinks
    } else {
      Serial.println("Receive failed");
    }
  } else {
    Serial.println("No reply, is another RFM69 listening?");
  }
}

void Blink(byte PIN, byte DELAY_MS, byte loops) {
  for (byte i=0; i<loops; i++)  {
    digitalWrite(PIN,HIGH);
    delay(DELAY_MS);
    digitalWrite(PIN,LOW);
    delay(DELAY_MS);
  }
}

Here are screenshots of the results
Taken yesterday: Mar 16

Taken today: Mar 17

please, no screenshots of text ... add the actual text ... some people here cannot view images

I'm surprised that you're getting anything reliable through the level converter at 1MHz. Where you've indicated it's not relevant I deleted that answer. No other suggestions for you.

It may be your environment, I have lots of problems here with RF transmission interference, a nearby radio amateur and proliferation of WiFi seem to exacerbate the problem. I've had some success building an RFM69 relay but have mostly gone over to WiFi using ESP8266 modules as they're much more reliable for communication.

Thank you @Bra1n. Actually Im currently in a laboratory. I was able to communication the RFM9x LoRa Radio by Adafruit in this very same environment, however, our prototype RFM69 didn't communicate at all huhuhu.


text:
How to detect ESP32 vs ESP8266 automatically when uploading the application?
I have the same application for both ESP32 and ESP8266 (the same functionality). The person, who is not an IT expert is expected to launch the dedicated installer program to upload the (first/new) version of the application. How can the installer (the program) detect what version of hardware is connected through USB? The goal is to upload the correct variant of he application. Is it possible at all?

esptool.py reports it

You can attempt to get the "chip ID" from the target board using esptool.py. The ESP8266 has a chip ID, but the ESP32 doesn't.
Running esptool.py --port <serial port> chip_id will either tell you, amongst other things:
Detecting chip type... ESP8266
Chip is ESP8266EX
....
Chip ID: 0x00a70414

Or:
Detecting chip type... ESP32
Chip is ESP32-PICO-D4 (revision 1)
...
Warning: ESP32 has no Chip ID. Reading MAC instead.

You can do similar with the read_mac command. In fact any operation on esptool.py that interacts with the target first probes the target to find out what the target is and report it - commands like chip_id and read_mac are just nice simple examples that return minimal information and don't interact with the target more than just querying the chip.

I suppose that you can't do it wrong anyway, can you? I mean attempting to upload an ESP8266-program to an ESP32 or vice versa will probably just result in an error?


text:
How to install the application + its configuration to many devices of the same kind? (ESP32)
Being the newbie in the Arduino area... Having more devices, how can I upload some configuration parameters after the code was uploaded? Is it possible?
Situation: I have the simple application for ESP32 with a simple sensor. It is to be used on many physical locations. Each location has its own Wi-Fi with its own SSID and password. An IT person on the location should be able to set the configuration parameters somehow. I would like to learn the possibilities -- to choose what is more suitable.
Separate compilation and upload: If I understand correctly, I can use the arduino-cli compile ... to compile the sketch to binary, and then arduino-cli upload ... to put the binary into the device. This way, I am able to prepare many devices with exactly the same binary content. (If I understand it correctly, then arduino-cli config ... is for setting the development environment, not for configuring the application on the board.)
Configuration: I have noticed the existence of Arduino Preferences Library (Preferences.h). I understand how to use it from inside the code of the application. Can the wanted preferences be uploaded to the board similarly as the sketch is? (I guess no, but asking to be sure.)
I have also noticed the existence of a lightweight file system (SPIFFS), and the ability to create (say) /config.json on the device from inside the application code. There is the plug-in to Arduino IDE to appear as a new tool (.../tool/esp32fs.jar). Then the data/ subdirectory is created in the sketch directory, and its content can be uploaded by another IDE command. That seems to be nice way to upload the configuration in my case; however, ...
Is there any command-line alternative to upload the configuration data that way? Can a single file be uploaded, or is it necessary to erase whole file system area, and upload whole content of the data/ like directory?

for the upload part: you can use "Export compiled binary" in IDE and then use esptool.py to flash the binary without Arduino tools.

Thanks, Juraj. That helped.

There's even an Android app that can be used for the upload on site.

If you don't want to include the individual config data in the sketch for each location there are mainly two possibilities to handle that:

As consumer IOT devices often do you can write your code to create a hotspot with a website, where the IT staff can then connect to and config the device by inputting the config data into the website.
You can use SPIFFS/LittleFS (The second is the successor of the first) to create a config file, which you then can read at the start of your sketch. This file system is saved in flash and can be written with an extra tool.

I would go for the second option. I'm currently still using SPIFFS, so I don't know if the following will be different for LittleFS. Your paths might vary (depending on core/version/OS).

First create your data directory, where you then place your config.json file. The standard is a directory named "data" inside the sketch folder.

Then you need to invoke mkspiffs to create a binary image for your data folder. I'm doing it like this:
 ~/.arduino15/packages/esp32/tools/mkspiffs/0.2.3/mkspiffs -c ./data -d 5 -b 4096 -s 0x170000 -p 256 ${file_path}/spiffs_image.bin

{file_path} is the path of the sketch folder for me. That way the image is placed directly besides the sketch. The options mean the following (I will also paste the help page of the command below):
 -d 5  -->  Debug Level at max (goes from 0 to 5)
 -b 4096  --> block size in bytes
 -s 0x170000  -->  image size in bytes
 -p 256       -->  page size in bytes
 -c ./data    -->  data directory

You can get these information when you look at the verbose output in the Arduino IDE while uploading the filesystem over the tool. They depend on your board and the settings that you use (mostly the partition scheme).

Then you can upload the image file via the esptool.py:
  ~/.arduino15/packages/esp8266/tools/python3/3.7.2-post1/python3 ~/.arduino15/packages/esp32/hardware/esp32/1.0.5/tools/esptool.py --port /dev/ttyUSB0 --baud 921600 --before default_reset --after hard_reset write_flash 0x290000 ${file_path}/spiffs_image.bin

0x290000 is the position in flash, where the data should be written. This also depends on your partition scheme and it should also appear in the Arduino IDE output, where you can copy it from. Note, that I'm invoking the python version here, that comes with the ESP32 core.

This works great for my ESP32 board (using the Wemos LOLIN32 with the "Standard" Partition scheme). Now you will have to think of a fitting workflow. You can have individual data directories and images for each location. Or you can change the file everytime you invoke the commands above (you can even do this in a script).

Here the help output of mkspiffs:
~/.arduino15/packages/esp32/tools/mkspiffs/0.2.3/mkspiffs --help

USAGE:

   /home/christian/.arduino15/packages/esp32/tools/mkspiffs/0.2.3/mkspiffs
                                        {-c <pack_dir>|-u <dest_dir>|-l|-i}
                                        [-d <0-5>] [-a] [-b <number>] [-p
                                        <number>] [-s <number>] [--]
                                        [--version] [-h] <image_file>

Where:

   -c <pack_dir>,  --create <pack_dir>
     (OR required)  create spiffs image from a directory
         -- OR --
   -u <dest_dir>,  --unpack <dest_dir>
     (OR required)  unpack spiffs image to a directory
         -- OR --
   -l,  --list
     (OR required)  list files in spiffs image
         -- OR --
   -i,  --visualize
     (OR required)  visualize spiffs image

   -d <0-5>,  --debug <0-5>
     Debug level. 0 means no debug output.

   -a,  --all-files
     when creating an image, include files which are normally ignored;
     currently only applies to '.DS_Store' files and '.git' directories

   -b <number>,  --block <number>
     fs block size, in bytes

   -p <number>,  --page <number>
     fs page size, in bytes

   -s <number>,  --size <number>
     fs image size, in bytes

   --,  --ignore_rest
     Ignores the rest of the labeled arguments following this flag.

   --version
     Displays version information and exits.

   -h,  --help
     Displays usage information and exits.

   <image_file>
     (required)  spiffs image file

And for the esptool.py:
~/.arduino15/packages/esp8266/tools/python3/3.7.2-post1/python3 ~/.arduino15/packages/esp32/hardware/esp32/1.0.5/tools/esptool.py --help
usage: esptool [-h] [--chip {auto,esp8266,esp32,esp32s2beta}] [--port PORT]
               [--baud BAUD]
               [--before {default_reset,no_reset,no_reset_no_sync}]
               [--after {hard_reset,soft_reset,no_reset}] [--no-stub]
               [--trace] [--override-vddsdio [{1.8V,1.9V,OFF}]]
               [--connect-attempts CONNECT_ATTEMPTS]
               {load_ram,dump_mem,read_mem,write_mem,write_flash,run,image_info,make_image,elf2image,read_mac,chip_id,flash_id,read_flash_status,write_flash_status,read_flash,verify_flash,erase_flash,erase_region,version,get_security_info}
               ...

esptool.py v2.9-dev - ESP8266 ROM Bootloader Utility

positional arguments:
  {load_ram,dump_mem,read_mem,write_mem,write_flash,run,image_info,make_image,elf2image,read_mac,chip_id,flash_id,read_flash_status,write_flash_status,read_flash,verify_flash,erase_flash,erase_region,version,get_security_info}
                        Run esptool {command} -h for additional help
    load_ram            Download an image to RAM and execute
    dump_mem            Dump arbitrary memory to disk
    read_mem            Read arbitrary memory location
    write_mem           Read-modify-write to arbitrary memory location
    write_flash         Write a binary blob to flash
    run                 Run application code in flash
    image_info          Dump headers from an application image
    make_image          Create an application image from binary files
    elf2image           Create an application image from ELF file
    read_mac            Read MAC address from OTP ROM
    chip_id             Read Chip ID from OTP ROM
    flash_id            Read SPI flash manufacturer and device ID
    read_flash_status   Read SPI flash status register
    write_flash_status  Write SPI flash status register
    read_flash          Read SPI flash content
    verify_flash        Verify a binary blob against flash
    erase_flash         Perform Chip Erase on SPI flash
    erase_region        Erase a region of the flash
    version             Print esptool version
    get_security_info   Get some security-related data

optional arguments:
  -h, --help            show this help message and exit
  --chip {auto,esp8266,esp32,esp32s2beta}, -c {auto,esp8266,esp32,esp32s2beta}
                        Target chip type
  --port PORT, -p PORT  Serial port device
  --baud BAUD, -b BAUD  Serial port baud rate used when flashing/reading
  --before {default_reset,no_reset,no_reset_no_sync}
                        What to do before connecting to the chip
  --after {hard_reset,soft_reset,no_reset}, -a {hard_reset,soft_reset,no_reset}
                        What to do after esptool.py is finished
  --no-stub             Disable launching the flasher stub, only talk to ROM
                        bootloader. Some features will not be available.
  --trace, -t           Enable trace-level output of esptool.py interactions.
  --override-vddsdio [{1.8V,1.9V,OFF}]
                        Override ESP32 VDDSDIO internal voltage regulator (use
                        with care)
  --connect-attempts CONNECT_ATTEMPTS
                        Number of attempts to connect, negative or 0 for
                        infinite. Default: 7.

Thanks @chrisl. That seems to be exactly what I need. :)

I usually use BLE to set the WiFi credentials.
After the WiFi connection is taken care of, I usually provision the rest of the configuration data by having a web application in the LAN that I put into "pairing" mode with the MAC address of the ESP. The ESP then downloads the config from the web application. Although I don't have super secret config data, for good measure the application ends the pairing mode after one download and will not serve further config requests.


text:
esp8266 - server.handleClient() fails to call assigned function
I'm trying to get one esp to send integers to a second as a part of a simple remote control, but after multiple days I can't get it to work. The transmitter seems like it's connecting and sending properly as best I can tell, and the receiver is sending some kind of response, but the function I attached with server.on() never gets called.
The code is basically copy and pasted from a tutorial, the only thing I changed was removing code to display the read data to an LCD and display to serial instead.
This is the receiver's code.
#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>

const char *ssid = "controllerReceiver";
const char *password = "password";

ESP8266WebServer server(80);

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

  WiFi.softAP(ssid, password);
  IPAddress myIP = WiFi.softAPIP();

  server.on("/data/", HTTP_GET, handleSentVar);
  server.begin();
  Serial.println("server online");
}

void loop() {
  server.handleClient();

}

void handleSentVar() {
  Serial.println("Handling");
  if (server.hasArg("x_value")) { // this is the variable sent from the client
    int readingInt = server.arg("x_value").toInt();
    Serial.println(readingInt);
    server.send(200, "text/html", "Data received");
  }

}

And here is the transmitter
#include <ESP8266WiFi.h>

const char *ssid = "controllerReceiver";
const char *password = "password";

int outputValue = 999;

void setup() {

  Serial.begin(115200);
  delay(10);

  // Explicitly set the ESP8266 to be a WiFi-client
  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);

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

}

void loop() {

  char intToPrint[5];
  itoa(outputValue, intToPrint, 10); //integer to string conversion for OLED library

  // Use WiFiClient class to create TCP connections
  WiFiClient client;
  const char * host = "192.168.4.1";
  const int httpPort = 80;

  if (!client.connect(host, httpPort)) {
    Serial.println("connection failed");

    return;
  }

  // We now create a URI for the request. Something like /data/?sensor_reading=123
  String url = "/data/";
  url += "x_value=";
  url += intToPrint;

  // This will send the request to the server
  client.print(String("GET ") + url + " HTTP/1.1\r\n" +
               "Host: " + host + "\r\n" +
               "Connection: close\r\n\r\n");
  unsigned long timeout = millis();
  while (client.available() == 0) {
    if (millis() - timeout > 5000) {
      Serial.println(">>> Client Timeout !");

      client.stop();
      return;
    }
  }

}

Running a whole webserver + client is waaay overkill for a remote control. Use UDP packets instead.

Replace "/data/" with "/data" and url += "x_value=" with url += "?x_value=".
The HTTP GET parameters are separated from the path by "?". The on function is executed for a path ("/data").

If you sub server.on("/data/", don't you need the trailing slash in the request also? some web hosts tack that on for you, but the ESP doesn't.

@dandavis, no..

I just tested it by on()ing /test and /test/ with different functions, and they are indeed discrete. This is why there's repetitive stuff like server.on("/read/", getReading);  server.on("/read", getReading); in my old sketches. I now use a macro that subs both the plain and slashed path to make it easier and would have been pleased+surprised to find out it was useless. Maybe async server is different...


text:
What GSM module I should use for HttpClient, ArduinoHttpClient, WebSockets etc.?
I need to use some API in my project. So I'm gonna use such libraries as listed in the title? What GSM/SIM module do I need for this purpose? I've checked 800L and similar - it only can use plain http, and only via AT command. At least based on this, that's not what I really need. Thanks in advance.

The TinyGSM library implements the Arduino Client class required by networking super libraries you mention in the question.
TinyGSM supports the SIM800 modems.

Ok, thanks, but what about http only, no https?

@picKit, see the "SSL/TLS (HTTPS)" paragraph in README


text:
How can I SPI "Latch" (LE/CS/SS) for a specific number of SCLK cycles?
Context
I am working on a project which includes 13 cascaded STMicroelectronics LED1642GWs. These LED drivers are essentially 16bit shift registers, whereby the buffered serial data can be loaded to a number of different registers dependant on the required function.
The function is selected through the use of "digital keys", which is selected by number of CLK cycles for which the LE (CS/SS) pin is HIGH. For example, LE being HIGH for 1-2 CLK cycles will switch the 16 outputs as per the buffered bits, whereas LE being HIGH for 3-4 CLK cycles will load the 16 bits to a brightness register.

Question
How can I toggle my LE/CS/SS pin for a specific number of SCLK cycles? I had intended to use the SPI Libary, however I'm not sure this can be supported.
Many Thanks!

SPI works on bytes not individual clock cycles. You will have to bit-bang your own protocol.

Well it can still be write out as full bytes, "3-4 Clock Cycles" being written as 0x7 or 0xF for example (00000111 or 00001111). It's just writing out to LE which is the bit I can't figure.

Yeah, but you can only trigger your LE on multiples of 8 clock cycles. You will have to bit-bang your own protocol. It's not hard.

I've achieve this by "bit-banging" via a modified shiftOut() of ArduinoCore-avr/cores/arduino/wiring_shift.c, essentially allowing for two data lines on the same clocking:
void keyedShiftOut(
  uint8_t dataPin,
  uint8_t clockPin,
  uint8_t latchPin,
  uint8_t bitOrder,
  uint16_t val,
  uint16_t key)
{
    uint8_t i;

    for (i = 0; i < 16; i++)  {
        if (bitOrder == LSBFIRST) {
            digitalWrite(dataPin, val & 1);
            val >>= 1;
            digitalWrite(latchPin, key & 1);
            key >>= 1;
        } else {
            digitalWrite(dataPin, (val & 0x8000) != 0);
            val <<= 1;
            digitalWrite(latchPin, (key & 0x8000) != 0);
            key <<= 1;
        }

        digitalWrite(clockPin, HIGH);
        digitalWrite(clockPin, LOW);
    }
}

I used this to implement the sequence described within the data sheet (Figure 24. Brightness register setting) to set all of my 16 Brightness Registers to a half setting (0x7FFF) with a timed LE providing the digital key. This scoped out as:

Running on my Arduino Nano 33 IoT this clocked at 150kHz which is sufficient for my application.