text:
How do I write and read .pem certs from SPIFFS?
I'm trying to construct a program for an ESP32 Dev Board that writes my AWS cert files [(https://medium.com/@flynam/securing-your-iot-device-using-ssl-4643110ab901)][1] to SPIFFS so that I can later read them from another program that's loaded via an OTA (over the air) updater.
However, it looks like something is being lost during the read & write process.  The certs will work if hardcoded, but error out when loaded from SPIFFS.
Hardcoding to a variable like the one in Secrets.h works:
static const char AWS_CERT_CA[] PROGMEM
But when writing that to a file and printing via Serial.println I'm missing things like R"EOF( and )EOF" which I'm assuming are hidden characters.
Does this have to do with writing as a .txt file or perhaps storing in the wrong kind of variable?
The code below is missing some functions, but the relevant portions are below.
I should also mention I am very much a C++ beginner so there's probably some things off with my code above and beyond my initial question.
main.ino
// ...
#include "Secrets.h" // contains cert files info
#include <WiFiClientSecure.h>
#include <MQTTClient.h>
#include <ArduinoJson.h>
#include "Esp.h"
#include "SPIFFS.h"
// ...

// Where I'm wanting to store my cert files
static char AWS_CERT_CA_FILEPATH[] = "/AWS_CERT_CA.txt";
static char AWS_CERT_CRT_FILEPATH[] = "/AWS_CERT_CRT.txt";
static char AWS_CERT_PRIVATE_FILEPATH[] = "/AWS_CERT_PRIVATE.txt";

// Save a file to the designated location
void saveFile(const char* filePath, const char* contents){
  if(!SPIFFS.exists(filePath)) {
      File writeLog = SPIFFS.open(filePath, FILE_WRITE);
      if(!writeLog) {
          Serial.print("Couldn't open ");
          Serial.println(filePath);
      } else {
        writeLog.print(contents);
        delay(50);
        Serial.print(contents);
        Serial.print(" written to file system");
        Serial.println(filePath);
        delay(50);
        writeLog.close();
      }
      delay(50);

  } else {
    Serial.print(filePath);
    Serial.print(" already exists.  Call remove() first.");
  }
}

// Remove files if they are there already, then save anew
void saveCerts(){

  SPIFFS.remove(AWS_CERT_CA_FILEPATH);
  SPIFFS.remove(AWS_CERT_CRT_FILEPATH);
  SPIFFS.remove(AWS_CERT_PRIVATE_FILEPATH);

  saveFile(AWS_CERT_CA_FILEPATH, AWS_CERT_CA);
  saveFile(AWS_CERT_CRT_FILEPATH, AWS_CERT_CRT);
  saveFile(AWS_CERT_PRIVATE_FILEPATH, AWS_CERT_PRIVATE);
}

// Load the file into char* ...
// Loads, but perhaps not into the correct format?
bool loadFile(const char* filePath, char* buffer){
    File f = SPIFFS.open(filePath, "r");
    if (f && f.size()) {

      Serial.print("Reading ");
      Serial.print(f.size());
      Serial.print(" bytes from file ");
      Serial.println(filePath);

      int pos = 0;
      while (f.available()) {
        buffer[pos] = f.read();
        pos++;
      }

      buffer[pos] = 0;

      f.close();
      return true;

    } else {
      Serial.print("No contents available for ");
      Serial.println(filePath);
      return false;
    }
}

// Allows for creation of correctly size char arrays
int getFileSize(const char* filePath){
    File f = SPIFFS.open(filePath, "r");
    if (f && f.size()) {
      return (int)f.size();

    } else {
      return 0;
    }
}

void connectAWS()
{
  // Need to save these to file
  char AWS_CERT_CA_LOADED[getFileSize(AWS_CERT_CA_FILEPATH)];
  char AWS_CERT_CRT_LOADED[getFileSize(AWS_CERT_CRT_FILEPATH)];
  char AWS_CERT_PRIVATE_LOADED[getFileSize(AWS_CERT_PRIVATE_FILEPATH)];

  loadFile(AWS_CERT_CA_FILEPATH, AWS_CERT_CA_LOADED);
  loadFile(AWS_CERT_CRT_FILEPATH, AWS_CERT_CRT_LOADED);
  loadFile(AWS_CERT_PRIVATE_FILEPATH, AWS_CERT_PRIVATE_LOADED);

  WiFi.mode(WIFI_STA);
  WiFi.begin(WIFI_SSID, WIFI_PASSWORD);

  // From here on out is code from tutorials and works when
  // certs are hardcoded

  Serial.println("Connecting to Wi-Fi");

  // TODO Put in some code when auth fails
  while (WiFi.status() != WL_CONNECTED){
    delay(500);
    Serial.print(".");
  }

  // Configure WiFiClientSecure to use the AWS IoT device credentials
  net.setCACert(AWS_CERT_CA_LOADED);
  net.setCertificate(AWS_CERT_CRT_LOADED);
  net.setPrivateKey(AWS_CERT_PRIVATE_LOADED);

  // Connect to the MQTT broker on the AWS endpoint we defined earlier
  client.begin(AWS_IOT_ENDPOINT, 8883, net);

  // Create a message handler
  client.onMessage(messageHandler);

  Serial.print("Connecting to AWS IOT");

  while (!client.connect(THINGNAME)) {
    Serial.print(".");
    delay(100);
  }

  if(!client.connected()){
    Serial.println("AWS IoT Timeout!");
    return;
  }

  // Subscribe to a topic
  client.subscribe(AWS_IOT_SUBSCRIBE_TOPIC);

  Serial.println("AWS IoT Connected!");
}

void setup() {
  Serial.begin(9600);
  SPIFFS.begin();
  saveCerts();
  connectAWS();
  publishMessage();
}

In secrets.h
#include <pgmspace.h>

#define SECRET

// Amazon Root CA 1
static const char AWS_CERT_CA[] PROGMEM = R"EOF(
-----BEGIN CERTIFICATE-----
awholebunchofrandomlettersandnumbers
-----END CERTIFICATE-----
)EOF";

// Device Certificate
static const char AWS_CERT_CRT[] PROGMEM = R"KEY(
-----BEGIN CERTIFICATE-----
awholebunchofrandomlettersandnumbers
-----END CERTIFICATE-----

)KEY";

// Device Private Key
static const char AWS_CERT_PRIVATE[] PROGMEM = R"KEY(
-----BEGIN RSA PRIVATE KEY-----
awholebunchofrandomlettersandnumbers
-----END RSA PRIVATE KEY-----
)KEY";

 Print and Error Message
[E][vfs_api.cpp:135] remove(): /AWS_CERT_CRT.txt does not exists or is directory
[E][vfs_api.cpp:135] remove(): /AWS_CERT_PRIVATE.txt does not exists or is directory

-----BEGIN CERTIFICATE-----
someprivatestuffIerased
-----END CERTIFICATE-----
 written to file system/AWS_CERT_CA.txt

-----BEGIN CERTIFICATE-----
someprivatestuffIerased
-----END CERTIFICATE-----
 written to file system/AWS_CERT_CRT.txt

-----BEGIN RSA PRIVATE KEY-----
someprivatestuffIerased
-----END RSA PRIVATE KEY-----
 written to file system/AWS_CERT_PRIVATE.txt
Reading 1189 bytes from file /AWS_CERT_CA.txt
Reading 1221 bytes from file /AWS_CERT_CRT.txt
Reading 1676 bytes from file /AWS_CERT_PRIVATE.txt
[D][WiFiGeneric.cpp:337] _eventCallback(): Event: 0 - WIFI_READY
[D][WiFiGeneric.cpp:337] _eventCallback(): Event: 2 - STA_START
Connecting to Wi-Fi
[D][WiFiGeneric.cpp:337] _eventCallback(): Event: 4 - STA_CONNECTED
[D][WiFiGeneric.cpp:337] _eventCallback(): Event: 7 - STA_GOT_IP
[D][WiFiGeneric.cpp:381] _eventCallback(): STA IP: 192.168.1.192, MASK: 255.255.255.0, GW: 192.168.1.1
.Connecting to AWS IOT[V][ssl_client.cpp:56] start_ssl_client(): Free internal heap before TLS 258252
[V][ssl_client.cpp:58] start_ssl_client(): Starting socket
[V][ssl_client.cpp:93] start_ssl_client(): Seeding the random number generator
[V][ssl_client.cpp:102] start_ssl_client(): Setting up the SSL/TLS structure...
[V][ssl_client.cpp:115] start_ssl_client(): Loading CA cert
[V][ssl_client.cpp:163] start_ssl_client(): Loading CRT cert
[V][ssl_client.cpp:170] start_ssl_client(): Loading private key
[V][ssl_client.cpp:180] start_ssl_client(): Setting hostname for TLS session...
[V][ssl_client.cpp:195] start_ssl_client(): Performing the SSL/TLS handshake...
Guru Meditation Error: Core  1 panic'ed (Unhandled debug exception)
Debug exception reason: Stack canary watchpoint triggered (loopTask)
Core 1 register dump:
PC      : 0x4008c363  PS      : 0x00060036  A0      : 0x8008c458  A1      : 0x3ffb0060
A2      : 0x3ffd9cbc  A3      : 0xbaad5678  A4      : 0x3ffd9cb0  A5      : 0x3ffb0190
A6      : 0x00000001  A7      : 0x00000000  A8      : 0x3ffd9cc8  A9      : 0x3ffd9cb4
A10     : 0x00000001  A11     : 0x3ffd9cb0  A12     : 0x00005640  A13     : 0x00005568
A14     : 0x3ffd9da8  A15     : 0x3ffd9ccc  SAR     : 0x0000001f  EXCCAUSE: 0x00000001
EXCVADDR: 0x00000000  LBEG    : 0x4000c2e0  LEND    : 0x4000c2f6  LCOUNT  : 0xffffffff

Backtrace: 0x4008c363:0x3ffb0060 0x4008c455:0x3ffb0090 0x40084e00:0x3ffb00b0 0x400850a3:0x3ffb00d0 0x400845c8:0x3ffb00f0 0x400f1099:0x3ffb0110 0x400ee30a:0x3ffb0130 0x400eed36:0x3ffb0150 0x400eeda1:0x3ffb0190 0x400ef154:0x3ffb01c0 0x400ef2ff:0x3ffb0240 0x400ef577:0x3⸮

Update
Exception can be fixed by making the variables global, but I now receive a repeating invalid certificate format error.
[ssl_client.cpp:56] start_ssl_client(): Free internal heap before TLS 256736
[V][ssl_client.cpp:58] start_ssl_client(): Starting socket
[V][ssl_client.cpp:93] start_ssl_client(): Seeding the random number generator
[V][ssl_client.cpp:102] start_ssl_client(): Setting up the SSL/TLS structure...
[V][ssl_client.cpp:115] start_ssl_client(): Loading CA cert
[E][ssl_client.cpp:33] _handle_error(): [start_ssl_client():122]: (-8576) X509 - The CRT/CRL/CSR format is invalid, e.g. different type expected
[E][WiFiClientSecure.cpp:132] connect(): start_ssl_client: -8576
[V][ssl_client.cpp:248] stop_ssl_socket(): Cleaning SSL connection.
[V][ssl_client.cpp:56] start_ssl_client(): Free internal heap before TLS 256124
[V][ssl_client.cpp:58] start_ssl_client(): Starting socket
[V][ssl_client.cpp:93] start_ssl_client(): Seeding the random number generator
[V][ssl_client.cpp:102] start_ssl_client(): Setting up the SSL/TLS structure...
[V][ssl_client.cpp:115] start_ssl_client(): Loading CA cert
[E][ssl_client.cpp:33] _handle_error(): [start_ssl_client():122]: (-8576) X509 - The CRT/CRL/CSR format is invalid, e.g. different type expected

Update 2
Added the following
// At top of file
#define FORMAT_SPIFFS_IF_FAILED true

// In setup()
if(!SPIFFS.begin(FORMAT_SPIFFS_IF_FAILED)){
   Serial.println("SPIFFS Mount Failed");
   return;
}

Can you provide a stack decode via https://github.com/me-no-dev/EspExceptionDecoder? It could also be that since you now allocate the buffers for the certificates on the stack of the function, that there's a stack overflow. Given that the error is Stack canary watchpoint triggered this is the most likely cause (a canary is a special value written into the end of the stack to check if it's been overwritten / overflowed). Please try: declare char AWS_CERT_CA_LOADED[] and friends variables as global variables (outside func) with some constant max memory size (2k), then load certs as usual

and retry the handshake.

@MaximilianGerhardt Thanks Maximilian.  That fixed the stack overflow error.  Now I receive an invalid format.  I'll continue to try additional approaches.

invalid format error is thrown by which function exactly? The certificate loading functions? Have you verified their content to be the same as when using static certificates?

@MaximilianGerhardt It seems I needed to format (?) SPIFFS for it to work properly.  Added a bit of code to "Update 2".


text:
Determining which raw IR code to use for AC
I'm new on this so go easy on me.
I'm trying to make an IR blaster to control my TV and ACs. I realized that when I capture the IR code, power button/temp up and down/mode send raw codes that are almost similar to each other.
I've searched the net(maybe missed some answers) and came through this. The raw IR code provided on the blog did turned on my AC but I wasn't able to turn it off. So I think that the code isn't the power button. That's because I remember leaving the AC off at 23°C and when I send that code, my AC started at 20°C.
So, how do I know which code to use for off, temp up etc? The codes I captured seems not to work when I send the codes to the AC. Nothing happened. No beep or anything. I'm using a GREE AC by the way.
Here's an example of the raw code that turned on my AC:
uint16_t irACon1[139] = {9050, 4500, 800, 1600, 750, 550, 700, 550, 700, 1600, 750, 550, 700, 550, 700, 550, 700, 550, 700, 550, 700, 550, 700, 1600, 750, 550, 700, 550, 700, 550, 700, 550, 700, 550, 700, 550, 700, 550, 700, 550, 700, 550, 700, 550, 700, 1600, 750, 1600, 750, 550, 700, 550, 700, 550, 700, 550, 700, 550, 700, 1600, 750, 550, 700, 1600, 750, 550, 700, 550, 700, 1600, 750, 550, 700, 19950, 750, 500, 700, 550, 700, 550, 700, 550, 700, 550, 700, 550, 700, 550, 700, 550, 700, 550, 700, 550, 700, 550, 700, 550, 700, 550, 700, 1600, 750, 550, 700, 550, 750, 550, 700, 550, 700, 550, 700, 550, 700, 550, 700, 550, 700, 550, 700, 550, 700, 550, 700, 550, 700, 550, 700, 550, 700, 1550, 800, 550, 750, 500, 700, 1600, 750};

And few other codes that I had captured:
Raw: (139) 9068, -4404, 708, -1580, 712, -488, 712, -484, 712, -1580, 712, -1580, 708, -1580, 712, -488, 708, -488, 708, -1584, 708, -1584, 708, -1580, 708, -492, 708, -488, 704, -496, 704, -492, 708, -492, 708, -492, 704, -492, 708, -492, 708, -488, 712, -488, 712, -1580, 708, -1580, 712, -488, 712, -484, 712, -488, 712, -488, 712, -484, 712, -1580, 712, -484, 712, -1580, 712, -484, 716, -484, 712, -1580, 712, -484, 712, -19848, 684, -512, 704, -496, 708, -492, 708, -488, 708, -492, 708, -488, 712, -488, 712, -488, 708, -488, 712, -488, 712, -484, 712, -488, 712, -488, 708, -1580, 712, -488, 712, -484, 712, -488, 708, -488, 712, -488, 712, -488, 708, -488, 712, -488, 708, -488, 712, -488, 712, -488, 708, -488, 712, -488, 708, -492, 708, -488, 708, -492, 708, -1584, 704, -1584, 708,

Raw: (139) 8988, -4540, 556, -1736, 564, -688, 520, -676, 524, -652, 548, -1688, 600, -1688, 604, -648, 548, -652, 548, -1688, 604, -1684, 604, -1688, 604, -648, 548, -652, 548, -648, 548, -652, 548, -652, 548, -648, 548, -652, 548, -652, 548, -648, 548, -676, 524, -1688, 600, -1688, 604, -676, 520, -676, 524, -676, 524, -672, 524, -676, 524, -1712, 576, -680, 520, -1688, 604, -756, 440, -788, 412, -1688, 600, -816, 384, -20092, 468, -840, 348, -848, 352, -848, 352, -820, 384, -812, 388, -788, 412, -784, 412, -784, 416, -760, 440, -760, 436, -760, 440, -756, 444, -756, 440, -1824, 468, -780, 416, -760, 440, -756, 444, -728, 468, -732, 468, -728, 472, -700, 496, -704, 496, -700, 496, -676, 524, -676, 520, -652, 548, -648, 552, -624, 572, -624, 576, -620, 580, -1740, 548, -620, 580,

PS: Sorry for my bad English. And I somehow feel that the title isn't specific so let me know if there's a better title I should put.
UDPATE: Now the off and temp up is working but the temp is somewhat like an on button. It instantly put my AC on 23°C and won't increase when pressed multiple time. I understand that AC's remote fires the whole setup string when a button is pressed so which means different temps has different codes?

It appears from the data you've posted, the remote is holding the presets for what the A/C unit needs to be doing when after every button is pressed.  This will keep the remote with LCD disply? in Sync with the A/C master.
Ie.  The remote is sending an entire setup string EVERY time ANY button is pressed.
Can you post a capture of an ON and OFF Raw's only?  Do not press any other buttons after pressing ON, or before pressing OFF.

I see. But surely there's a way to know which raw code control what, isn't it? And here's the on and off raw code: https://pastebin.com/sKVWecLh

You are on the right track, but I think you need an expert for a better answer.

source: Stack Exchange

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

sort: votes


text:
What killed my Arduino nano?
Yesterday evening everything worked well. Today morning I am trying to upload sketch to the Arduino (nano china, CH340) and get the following:
Writing |

avrdude: stk500_paged_write(): (a) protocol error, expect=0x14, resp=0x00

############avrdude: stk500_cmd(): programmer is out of sync

avrdude: stk500_recv(): programmer is not responding

Check wiring, settings, cable, another PC. The same result.
Took another Arduino from the same supply. Works.
What could damage my Arduino nano? Static voltage? This is the first time in 3 years of insensitive playing with Arduino. I was told that Arduino nano is quite tolerant to static voltage.
What can I do with this damaged Arduino? Is it possible to restore it?
The boards is still recognizable by PC and blinks with leds when it is connected.

why are you so certain that it is damaged?

Since the Arduino is still recognized, try to open a serial monitor and send some data to the Arduino. The RX LED should light up shortly. That would show, that the serial data is still transmitted. Then you can try to burn the bootloader again via an another Arduino

Could be that the flash in the main chip is dead and the data isn't being written correctly. That's what you get when you buy boards made with chips taken from the factory reject bin.

i saw that message a few years ago. iirc, rebooting my pc fixed it.

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


text:
Using SMS to send commands to the Arduino. Having problems in data parsing
I'm still inexperienced in programming and i apologize in advance if my mistakes are stupidly obvious. This sketch I'm working on is a basic GSM project using SIM900a Mini and an Arduino UNO that could send a message to a recipient with a press of a button. I created a function so that if i send a command to the GSM, i could change the recipient and check the current recipient through my phone.
One thing to note is that before i resorted to creating this sketch, I created an almost working project with the same concept using SIM800L and an arduino Nano and i used the GSM Library. However, when it was hooked up to a variable Step-up converter for the needed supply of the ~4 V using a 3.7V Li-Po battery, it was damaged because the booster suddenly supplied 12V to the GSM. The SIM800L won't connect to the network anymore after that incident. I resorted to using SIM900a-Mini and it wasn't compatible with the GSM Library i guess because it can't get pass the initialization stage. Though i've seen youtube videos using both the SIM900 and the GSM Library, though i can't seem to make it work even though the two share the same chipset (i think). This current sketch works with some issues. Here's the sketch:
#include <SoftwareSerial.h>
#include <SIM900.h>
#include <sms.h>
#define button 10
SMSGSM sms;

char senderNumber[15], recipientNumber[15] = "No recipient", newRecipient[15], commandkey[30] = {0};
char SmsText[30], smsRecieved[30];;
boolean validRecip, GSMconnected = false;
int buttonState = 0;

void setup(){
  Serial.begin(9600);
  Serial.println("Micro_GSM_Project");
  Serial.print("Initializing Serial:");
  pinMode(button, INPUT);
  pinMode(buzzer, OUTPUT);
  while (!Serial){
    Serial.println("Serial not connected");
  }
  delay(500);
  Serial.println(" Done");
  delay(1000);
  Serial.print("Initializing GSM Module:");
  if (gsm.begin(2400)) {
    Serial.println("\nWaiting for messages");
    GSMconnected = true;
    delay(1000);
  }
  else Serial.print("GSM Connecting");
}

void loop() {
  if (GSMconnected)
    {
    buttonState = digitalRead(button);
    if (buttonState == HIGH)
    {
      activate();
    }
    if (gsm.readSMS(SmsText, 30, senderNumber, 15))
    {
      Serial.print("\nMessage received from: +");
      Serial.println(senderNumber);
      Serial.println(SmsText);
      parseData();

     if (strcmp(commandkey, "CURRENT RECIP") == 0)
        {
          currentRecip();
        }
     else if (strcmp(commandkey, "SET RECIP") == 0)
        {
          changeRecip();
          confirmation();
        }
     else
     Serial.println("Invalid Command");
     sms.SendSMS(senderNumber, "The command you sent is invalid");
    }
  }
}

void activate() {
  delay(800);
  Serial.println("I have become self aware. Run");
  sms.SendSMS(recipientNumber,"I have become self aware. Run");
}

void parseData() {
  char * strtokIndx;
  strtokIndx = strtok(SmsText, ",");  //Read first part of Command either "SET RECIP" or "CURRENT RECIP"
  strcpy(commandkey, strtokIndx);         //store to commandkey variable

  strtokIndx = strtok(NULL, ",");         //Read where the last call left off, separated by a comma
  strcpy(newRecipient, strtokIndx);       //store to newRecipient variable

  Serial.print("Command Selected:");
  Serial.println(commandkey);
}

void currentRecip() {
  Serial.print("Current Recipient is: ");
  Serial.println(recipientNumber);
  delay(1000);
  sms.SendSMS(senderNumber, "Current Recipient is: recipientNumber");// i currently dont know how to log the variable recipientNumber to this string
}

void changeRecip()
    {
  validate();
    if (validRecip == true)
    {
    strcpy(recipientNumber, newRecipient);
    sms.SendSMS(senderNumber, "The Recipient number you have entered is valid");
    Serial.print("Recipient Number: ");
    Serial.print(recipientNumber);
    Serial.println("a");
    Serial.print("Sender Number");
    Serial.println(senderNumber);
    }
    if (validRecip == false)
    {
      Serial.println("Invalid Recipient");
      sms.SendSMS(senderNumber, "The Recipient number you have entered is invalid");
    }
    }

void validate()
  {
  if (strlen(newRecipient) == 13)   //I've put 13 here as a reference because the output strlen of the parsed newRecipient is 13 instead of the 12 characters composing the newRecipient i sent through sms. I think this is the null terminating character used by the strtokIndx? Please correct me if I'm wrong
  {
    Serial.println("Recipient is Valid\n");
    validRecip = true;
  }
  else
  {
    validRecip = false;
  }
}

void confirmation()
{
    if (validRecip == true)
    {
    Serial.println("Recipient Number successfully changed");    //Serial Monitor confirmation (for troubleshooting)
    Serial.print("New Recipient: +");
    Serial.println(recipientNumber);
    Serial.println("Informing Admin...");
    }
    if (sms.SendSMS(senderNumber, "Recipient Number successfully changed\nNew recipient: recipientNumber"))  //same here
    {
    Serial.println("Message Sent\n\n");
    }
    else
    {
    Serial.println("Invalid Recipient");
    sms.SendSMS(senderNumber, "The Recipient number you have entered is invalid");     //uncomment for SMS confirmation, need load
    }
}

These are the current issues with my current code (in order of priority) .

Even though the serial monitor displays the correct new recipient, **the recipient doesn't receive any message when the device is activated.**I think this is because of the data parsing method i used which creates a null character which increases the byte size of the recipientNumber variable. Through strlen, I've found out that the recipientNumber's size is 13 while the senderNumber fetched by the library has a size of 12. Even though the displayed number of characters in the serial are both 12. I tried changing the byte size of the array to 12 but once i did that, whenever i send the command to change the recipient, the program doesnt recognize the parsed command. It comes as blank.
If i send the command "CURRENT RECIP" the serial outputs both the currentRecip() and the "Invalid command". If i put the "CURRENT RECIP" in the else if statement, swapping with the "SET RECIP", the "CURRENT RECIP" command works properly. For some reason, the command which is put in the else if statement works properly. I've tried adding another statement. i honestly don't fully understand what i wrote there myself. Still doesn't work tho.

else if ((strcmp(commandkey, "CURRENT RECIP") != 0) || (strcmp(commandkey, "SET RECIP") != 0){
Serial.println("Invalid Command");
}

The project is supposed to activate at a simple push of a button. However, with my current sketch, it only activates when the button is long pressed. The issue i have here is i dont know where to properly put the activate(). I've tried placing it at the beginning of the loop and inside the if (GSMconnected) statement. However, both have the same result. I still have to press it long enough for the arduino to stop checking for available messages and proceed to the if (buttonState) statement.

if (buttonState == HIGH){
activate();
}

This sketch uses this GSM Library and i implemented the data parsing method from Serial Input Basics. The sketch properly separates the command i send which is "SET RECIP,XX**********" and proceeds to save it to the recipientNumber variable. The button can then be pressed and the GSM sends the message to the newly set recipient. Unfortunately, I am currently in a deadline and i dont think i have to time to scrap this sketch i made and just resort to AT commands. Please feel free to ask about any details i haven't covered. Any help would be appreciated and again i apologize in advance because some issues here might be fixed with just a simple syntax correction. Thank you in advance.


text:
Reading DHT22 reboots arduino
I’ve got a quite weird behavior of DHT library.
I’ve got DHT22 sensor. If it’s signal cable is not connected, reading the sensor causes a problem: Arduino reboots or hangs in unpredictable places.
If I connect the signal cable again, the problem vanishes.
Is this normal behavior or some sort of bug? I think unsuccessful reading affects some part of Memory.
PS. The project is quite big and I can’t share the code here.
It happens that I found an evidence that dht object influences foreign memory. Look at this code:
DV("pClock->isInited 3", pClock->isInited); // prints 1
dht1.readHumidity();
DV("pClock->isInited 4", pClock->isInited); // print 0 !!!!
// nothing more can be called between these lines.

// DV is a macro which prints label and value.
// Both objects created before this.

DHT dht1(11, DHT22);
…
dht1.begin();
…
pClock = new ZhClock(); // uses RTC_DS1307
pClock->init(&rtc); // rtc is RTC_DS1307

It's not normal behaviour. What hardware are you using, what pins have you connected the DHT22 to, and what DHT library are you using?

@StarCat I use Arduino nano CH340. DHT library shipped with Arduino IDE. I tried pins D11 and A2.

Is that the DHT library from Adafruit (installed through the library manager)? I don't think there is a DHT library that comes standard with the Arduino IDE. A2 and D11 should work fine. But what do you expect it to do when you disconnect the signal cable? The library should return an error (NaN values returned by temperature and humidity) when the DHT is not connected. How do you handle these errors? If you continue using the NaN values returned by the library, you will mess up all subsequent calculations. Also remember you cannot read from a DHT22 more than once every 2 seconds.

@StarCat Why I cannot read more than once? Can this be the source of the problem? I was supposed that I get wrong results, but it cannot lead the memory leakage. Yes, this library is by Adafruit, I was wrong.

I meant that your code has to wait at least 2 seconds after reading it, before reading the DHT again (technically: 0.5Hz or less).

@StarCat , So, this is not the case. Please look an updated description, please.

Whatever you say, now I know that Adafruit DHT library is the worst library ever I met! It is occurred that simple reading call wastes a huge amount of memory! About 280 bytes or so. Shame, shame, shame!

@zhekaus Are you talking about RAM or the program memory? What do you mean by wasting memory? When you don't use the library, the compiler will optimize it out. When you then change your sketch to actually use it, the compiler will put the library (or only the needed parts of it) in, which results in a bigger sketch and partly in a bigger RAM usage.

@chrisl , I am talking about RAM, obviously. Shortage of RAM kills the device. Look into dht.cpp, DHT::read method, and you'll see it yourself.  I am sure, that, for instance , uint32_t cycles[80]; says quite something to you ;-).

Adafruit DHT library requires about 390 byte of free RAM. Check if you have so.

This problem is usual if you are in shortage of RAM.
Adafruit's libraries wastes lots of memory. You should be very careful to run their stuff if you are in shortage of memory.
I suggest you to try another library which quite old, but uses much lesser memory to read DHT sensor’s data:
https://github.com/markruys/arduino-DHT

Yep! That's solved my problem!


text:
How to use any module that has no library for arduino?
I am 2 years old in this Arduino world.
I am currently working on a project where I am about to make use of a fingerprint sensor. Now my question is that could we be able to make use of a sensor that we usually find in our mobile phones with ATmega328p microcontroller chip. And what if that there were no libraries written for Arduino so that will make my life easier. And I wonder how these tech companies make use of any sensor they would like to use without any trouble while there is no existing textbook that taught these employees while pursuing a degree in CSE or ECE about how to write code for a particular sensor. Now I know that there are certain protocols like SPI, I2C, UART, etc. But how do they do it, and how do they know about microcontrollers and IC's that were never taught to them in any degree or course? I always scratch my head while looking at the consumer electronics, and the IC's and Chips that they have on their PCB board were never found on google, And by chance, if an IC or microcontroller is found then I barely understand the datasheet or the documentation which was written in Chinese or some other language. I hope someone could help me understand how all this happens.

I assume the datasheet of the IC is the main thing you need. If that's not available, it's like reverse-engineering, but for a non trivial IC this mostly is not worth trying.

About the fingerprint sensors from mobile phones: You might find the answers to this question useful. They explain in detail, why it is not really worth the effort to try interfacing such a fingerprint sensor with Arduino.

How to use any module that has no library for arduino?

You need to read the datasheet of the module. It should explain in detail, how the module is used. When you understood, how it works, (and understanding it is really really important) you can start implementing it in code, for example by writing your own library. A library is just a wrapper around the interfacing code for that module. If the module uses common used interfaces or is even a commonly used component, you can often stand on the shoulders of giants by making use of other libraries in your library (for example using the Wire library in a library for a specific I2C sensor). That makes it easier.

But how do they do it, and how do they know about microcontrollers and IC's that were never taught to them in any degree or course?

The engineers don't get taught to use specific controllers or ICs. They get taught the fundamental principles, including common interfaces like I2C, SPI, UART, I2S ... . In the end it all comes down to the datasheet of a component. It should explain all details, that are needed to use the component correctly, or at least reference to further documents. For example most microcontroller datasheets directly explain, how I2C is implemented in these microcontrollers. You can use that to implement I2C communication, even without a preexisting library. Yes, that can be a tedious and complex task, but it is totally possible. Keep in mind, that most Arduino libraries are not written by the manufacturer of the used component, but by third party people (sometimes the community, sometimes resellers like Adafruit, e.g.).
I would say "it is not rocket sience", but yes, it can be rather difficult to dig into the very detail of interfacing a component. Without considering myself an especially smart guy, I'm writing a library for multi-master I2C communication on Attiny's (without having any degree in that field). I could start with code from others, which made the entry easier. But it also involves much time, to dig into it, write the code and test it correctly. It is difficult, but it is possible.

And by chance, if an IC or microcontroller is found then I barely understand the datasheet or the documentation which was written in Chinese or some other language.

Good manufacturers and resellers provide a datasheet in english for their products. That cannot be said for every product, that you can purchase. Writing documentation takes time and thus costs money. Chips directly from China (where most electronics is produced these days) might have less good or no documentation at all, though these chips are often way cheaper. As a hobbyist you should stick to the good documentated components, if you don't want to really dig into it.

the IC's and Chips that they have on their PCB board were never found on google

PCB designs are only found in the internet, if they are published under some open source license (or if they were illegally leaked by someone). If a company doesn't want to publish it's product designs, that is totally ok.
About the components in consumer electronics: I think you refer to that the chips often don't have a googleable product number/marking to find a datasheet. That is because often these chips are custom chips, made maybe only for this company or even this specific product. Why would they want to publish a datasheet for it? They are not meant for public use for all. The design of components is often a good kept secret, that the companies are not willing to share, since it generates their revenue.
Hobbyists and small companies use publicly available, good and publicly documented parts to make their life and investment in the project easier. Big companies can easily hire people to design a custom chip, that will only contain the needed features. (With mass produced products you can save money this way, by not always needing to buy even the unused resources of a standard controller). Another reason to use a custom (maybe even a not programmable) chip is to keep the code in it secret.

All in all keep in mind, that the hobbyist world of Arduino and the world of consumer electronics like smart phones are rather different. Sure, they rely on the same principles, but the way, how things are done and created, is very different.

Thank you so much for such a piece of detailed information. So what should I consider to learn so that I could be knowledgeable enough to develop my own custom IC? Are there any books and references for this.

To be honest: No I cannot recommend things to learn for this. There are certainly many good books out there, but I don't know enough about this field to recommend anything. Designing your own IC is way over anything here. It is not something, that you can easily learn. And you are on the wrong site here to ask for it, since Arduino is not about custom IC design. Why do you want to design your own IC in the first place? From your question I assumed, that you are not doing this as a job

I just asked to give it a try . I am actually not ready to design any custom IC. And by the way I am very much passionate to create a product and sell it. I have an idea and I wanted my imagination to get real . Since I am new to electronics as I am a CSE student. I always stick to software engineering projects. I have never really thought that I will be so much passionate about electronics as I am today. I wanted to tinker a new product that is making rounds all day in my head. But due to my background in electronics I feel like I am lost.

Electronics of IC internals are like electronics of discrete components, but much more complex. You first need to understand electronics in general, before you can even start with thinking about IC internals. I think this is out of your reach. Instead you can simply use publicly available parts to make your product and sell it. That will be way easier, especially if you want to start selling your product in this century. Take your passion and put it into normal electronics, not in designing ICs. When you have enough experience, you can still look into that topic.

Reading a datasheet is a bit of an art, and trying to start with something like an SPI sensor that lacks even demo code makes for a very steep learning curve.  If you want to learn about interfacing over one of these buses, try getting something like an LM75 temperature sensor, for which there are decent datasheets.  Then try to interface without too much googling - and without using a single line of code you don't understand


text:
Generate & Display QR using Nodemcu on TFT Display ST7789 240*240
I have NodeMCU & ST7789 TFT display. I want to generate QR Code of any dynamic input and display it on my TFT display. Not able to find any suitable reference. All Standard QR code libraries only work for Arduino & not for NodeMcu, board not supported for them. Can someone please help ?
Libraries Tried :
https://github.com/yoprogramo/ESP_QRcode
https://github.com/anunpanya/ESP8266_QRcode
https://github.com/ricmoo/qrcode
https://github.com/onelife/rtt-qrcode

I suspect the real question is why does the Arduino QR library not work for the Nodemcu?  Also, post a link to the QR library you are intending to use just to make things clear.  Lastly, to make the project easier - you may want to constrain the code to a fixed length or at least limit it.  I have see QR codes on the sides of trucks so complex they look like sand grains.

Thanks for helping, I tried all existing libraries : https://github.com/yoprogramo/ESP_QRcode , https://github.com/anunpanya/ESP8266_QRcode, https://github.com/ricmoo/qrcode/, https://github.com/onelife/rtt-qrcode, But they all seems to dont seem to work with NodeMCU. Can you correct me if I am wrong, or if you have a work around. I dont require very complex QR Code (Grainy), simple usual ones, that we we see around.


text:
Newbie trying to interface MLX90614 with Arduino Due
Im a newbie and Im trying to interface the temperature sensor mlx90614 to the arduino due using i2c bus. After a lot of digging I found this code which works,but it works only on the sda(20),scl(21) pins. I want to change this to SCL1 and SDA1 near the Aref and gnd pins. How do i modify this code? Thanks
#include <Arduino.h>
#include <include/twi.h>

#define ADDR      0x5A

//EEPROM 32x16
#define TO_MAX    0x00
#define TO_MIN    0x01
#define PWM_CTRL  0x02

//RAM 32x16
#define RAW_IR_1  0x04
#define RAW_IR_2  0x05
#define TA        0x06
#define TOBJ_1    0x07
#define TOBJ_2    0x08

#define SYNC_PIN  2

static const uint32_t TWI_CLOCK = 100000;
static const uint32_t RECV_TIMEOUT = 100000;
static const uint32_t XMIT_TIMEOUT = 100000;

Twi *pTwi = WIRE_INTERFACE;

static void Wire_Init(void) {
  pmc_enable_periph_clk(WIRE_INTERFACE_ID);
  PIO_Configure(
  g_APinDescription[PIN_WIRE_SDA].pPort,
  g_APinDescription[PIN_WIRE_SDA].ulPinType,
  g_APinDescription[PIN_WIRE_SDA].ulPin,
  g_APinDescription[PIN_WIRE_SDA].ulPinConfiguration);
  PIO_Configure(
  g_APinDescription[PIN_WIRE_SCL].pPort,
  g_APinDescription[PIN_WIRE_SCL].ulPinType,
  g_APinDescription[PIN_WIRE_SCL].ulPin,
  g_APinDescription[PIN_WIRE_SCL].ulPinConfiguration);

  NVIC_DisableIRQ(TWI1_IRQn);
  NVIC_ClearPendingIRQ(TWI1_IRQn);
  NVIC_SetPriority(TWI1_IRQn, 0);
  NVIC_EnableIRQ(TWI1_IRQn);
}

static void Wire1_Init(void) {
    pmc_enable_periph_clk(WIRE1_INTERFACE_ID);
  PIO_Configure(
      g_APinDescription[PIN_WIRE1_SDA].pPort,
      g_APinDescription[PIN_WIRE1_SDA].ulPinType,
      g_APinDescription[PIN_WIRE1_SDA].ulPin,
      g_APinDescription[PIN_WIRE1_SDA].ulPinConfiguration);
  PIO_Configure(
      g_APinDescription[PIN_WIRE1_SCL].pPort,
      g_APinDescription[PIN_WIRE1_SCL].ulPinType,
      g_APinDescription[PIN_WIRE1_SCL].ulPin,
      g_APinDescription[PIN_WIRE1_SCL].ulPinConfiguration);

  NVIC_DisableIRQ(TWI0_IRQn);
  NVIC_ClearPendingIRQ(TWI0_IRQn);
  NVIC_SetPriority(TWI0_IRQn, 0);
  NVIC_EnableIRQ(TWI0_IRQn);
}

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

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

  Wire_Init();
  // Disable PDC channel
  pTwi->TWI_PTCR = UART_PTCR_RXTDIS | UART_PTCR_TXTDIS;
  TWI_ConfigureMaster(pTwi, TWI_CLOCK, VARIANT_MCK);
}

void loop() {
  uint16_t tempUK;
  float tempK;
  uint8_t hB, lB, pec;

  digitalWrite(SYNC_PIN, HIGH);
  delayMicroseconds(10);
  digitalWrite(SYNC_PIN, LOW);

  TWI_StartRead(pTwi, ADDR, TOBJ_1, 1);

  lB = readByte();
  hB = readByte();

  //last read
  TWI_SendSTOPCondition(pTwi);
  pec = readByte();

  while (!TWI_TransferComplete(pTwi))
    ;
  //TWI_WaitTransferComplete(pTwi, RECV_TIMEOUT);

  tempUK = (hB << 8) | lB;
  if(tempUK & (1 << 16))
  {
    Serial.print("Error !");
    Serial.println(tempK);
  }
  else
  {
    tempK = ((float)tempUK * 2) / 100 ;
    //Serial.print("Temp UK: ");
    //Serial.print(tempUK);
    Serial.print(" C: ");
    Serial.println(tempK - 273.15);
  }
  //Serial.print(hB, HEX);
  //Serial.print(" : ");
  //Serial.print(lB, HEX);
  //Serial.print(" : ");
  //Serial.println(pec, HEX);

  delay(2000);
}

uint8_t readByte() {
  //TWI_WaitByteReceived(pTwi, RECV_TIMEOUT);
  while (!TWI_ByteReceived(pTwi))
    ;
  return TWI_ReadByte(pTwi);
}

static inline bool TWI_WaitTransferComplete(Twi *_twi, uint32_t _timeout) {
  while (!TWI_TransferComplete(_twi)) {
    if (TWI_FailedAcknowledge(_twi))
      return false;
    if (--_timeout == 0)
      return false;
  }
  return true;
}

static inline bool TWI_WaitByteReceived(Twi *_twi, uint32_t _timeout) {
  while (!TWI_ByteReceived(_twi)) {
    if (TWI_FailedAcknowledge(_twi))
      return false;
    if (--_timeout == 0)
      return false;
  }
  return true;
}

static inline bool TWI_FailedAcknowledge(Twi *pTwi) {
  return pTwi->TWI_SR & TWI_SR_NACK;
}


text:
MCore(Arduino) - Python bluetooth communication
Pc and Mcore with bluetooth module are paired. The port is COM9 outgoing in PC. However, when I send message Arduino does not get anything. I just disconnect arduino from pc and write simple code in Mcore that turn on LED when input message is 1. However still nothing. These are the codes in python and arduino side:
import time
import serial

port="COM9"          #This will be different for various devices,COM port.
bluetooth=serial.Serial(port, 9600)         #Start communications with the bluetooth unit
bluetooth.flushInput()      #This gives the bluetooth a little kick
bluetooth.write(b'1')       #These need to be bytes not unicode
bluetooth.close()          #Otherwise the connection will remain open until a timeout

Arduino code:
char a;

void setup()
{
  Serial.begin(9600);
  pinMode(13, OUTPUT);
}

void loop()
{
if(Serial.available()){a = Serial.read();}

if (a == '1'){
  digitalWrite(13, HIGH);
  }

  else{
  digitalWrite(13, LOW);}

  delay(100);
}

I have tried to install Pybluez for WIN10, however, there was error. Do you think that this is the reason?
Thanks in advance

first I would remove the else part to debug

I also increased delay much like 3 seconds, still no response. From the led of bluetooth module it is felt that it receives something, but either format is problem or maybe it is not working properly.

I have tried many combinations including your suggestion.

I can't add the comment that's why add an answer. Check this link and you will get your result. https://github.com/huberf/Computer-to-Arduino-Bluetooth

Thank you all for answers, but the reason was very simple: The baud rate of Mbot bluetooth was 115200 and hence it could not get proper data.

Probably because you never called bluetooth.open().
What would be much easier to do is use pySerialTransfer and SerialTransfer.h to guarantee reliable and robust serial communication between Python and your Arduino.
pySerialTransfer is pip-installable and cross-platform compatible. SerialTransfer.h runs on the Arduino platform and can be installed through the Arduino IDE's Libraries Manager.
Both of these libraries have highly efficient and robust packetizing/parsing algorithms with easy to use APIs and come with examples.

kindly add a serial print before the if statement(if (a == '1')) to see what value of a is recieved so we can debug it


text:
Using SMS to receive password, then to choose whether to turn the relay on or off
I'm trying to use SMS messages to turn a relay on/off but before doing that i need to have a password system before allowing the user to turn the relay on/off. Basically, you have to send the password to the GSM via SMS first, then have an option select of ON or OFF, which you also send to the GSM. I can already do the password and ON/OFF of the relay separately, but I'm having trouble trying to combine them together. Here is the code:
String _buffer;
String number = "+639562284415";
String textMessage;
String relayState = "HIGH";

int relay = 24;
int _timeout;

void setup() {
  pinMode(relay, OUTPUT);
  digitalWrite(relay, HIGH);

  Serial.begin(9600);
  Serial1.begin(9600);
  delay(1000);
  Serial.print("SIM900 ready...");
  Serial1.print("AT+CMGF=1\r");
  delay(100);
  Serial1.print("AT+CNMI=2,2,0,0,0\r");
  delay(100);
}

void loop() {
  if (Serial1.available() > 0) {
    textMessage = Serial1.readString();
    Serial.print(textMessage);
    delay(10);
  }
  if (passFlag == 0) {
    if (textMessage.indexOf("1231") >= 0) {
      commandList();
      passFlag++;
      if (textMessage.indexOf("ON") >= 0) {
        // Turn on relay and save current state
        digitalWrite(relay, LOW);
        relayState = "on";
        Serial.println("Relay set to ON");
        textMessage = "";
      }

      if (textMessage.indexOf("OFF") >= 0) {
        // Turn off relay and save current state
        digitalWrite(relay, HIGH);
        relayState = "off";
        Serial.println("Relay set to OFF");
        textMessage = "";
      }
    }
  }
}

void commandList() {
  Serial.println ("Sending Message");
  Serial1.println("AT+CMGF=1");    //Sets the GSM Module in Text Mode
  delay(1000);
  Serial.println ("Set SMS Number");
  Serial1.println("AT+CMGS=\"" + number + "\"\r"); //Mobile phone number to send message
  delay(1000);
  String SMS = "Enter your command!";
  Serial1.println(SMS);
  delay(100);
  Serial1.println((char)26);// ASCII code of CTRL+Z
  delay(1000);
  _buffer = _readSerial();
}

String _readSerial() {
  _timeout = 0;
  while  (!Serial1.available() && _timeout < 12000  )
  {
    delay(13);
    _timeout++;
  }
  if (Serial1.available()) {
    return Serial1.readString();
  }
}

Basically what happens with this code is that it succeeds with the password entry, but it somehow skips over the ON/OFF option select. Since I used a flag to increment the password entry (so it doesn't endlessly send me the "Enter your command" message), the loop completely stop after loop. I want to use switch case but I don't really know how to use it in this case. I don't really know how to best approach this problem, so if anyone can give some advice I would really appreciate it! BTW I'm using a SIM800L and Arduino MEGA for this

If you first receive a password and then receive a command separately, in my opinion, the password is useless, because the command can be send from another sender and would be aceepted even if the password comes from the first sender. So I would send the command and the password in one message. e.g #<password>#ON or so.

The problem with the code above is that you only look after the pass word or one of the commands if passFlag is 0 (btw the variable is not declared in the code above. So you check for the password that succeeds the give me a command SMS is send and then you test for the command before the command SMS was received. In a later loop run the command SMS will be received but the if statements that test for the command will never be executed, because passFlag>0.  You could try to move the if (textMessage.indexOf("???") >= 0) out of the if (passFlag == 0) { block.

i decided to go with making the password go together with the command, because what you said makes sense to me (password is useless if because command can come from another sender after entering the password). thanks!

That has been a wise decision IMHO. Your welcome.  Cheers.


text:
Line not printing int in Serial Monitor
I'm trying to make a kernel for a macro-key maker, this is the starting page's code:
char m[] = "What do you want to do? Type the following commands in this "
      "terminal:\nnew  --> Creates a new Keybinding\ndelete  --> Deletes a "
      "previous Keybind\nlookup --> Find what is bound to a key\n\nTurn off the "
      "switch to go back to the normal mode.";
Serial.println(m);
Serial.println(String(takenKeybinds) + "/64 Keybinds taken.");

When I run it, the screen displays:
What do you want to do? Type the following commands in this terminal:
new  --> Creates a new Keybinding
delete  --> Deletes a previous Keybind
lookup --> Find what is bound to a key

Turn off the switch to go back to the normal mode.

The last line is missing.  Is this a problem with object casting? takenKeybind is an int.

does it happen in minimal sketch?

What board are you compiling for?

You should never do this:
Serial.println(String(takenKeybinds) + "/64 Keybinds taken.");

Yes, it should cope with it and append the strings, but that's really nasty even if it does work. And there is absolutely no call to ever do concatenation when printing to serial.
Instead just use:
Serial.print(takenKeybinds);
Serial.println(F("/64 Keybinds taken."));

Note also the use of the F() macro when printing a string literal. This keeps the string in flash and prevents it being copied to RAM, which is just wasteful.
The same with your big long string - it's wasting RAM, and if you never want to modify it, why have it in RAM? Better is:
Serial.println(F("What do you want to do? Type the following commands in this terminal:"));
Serial.println(F("new  --> Creates a new Keybinding"));
Serial.println(F("delete  --> Deletes a previous Keybind"));
Serial.println(F("lookup --> Find what is bound to a key"));
Serial.println();
Serial.println(F("Turn off the switch to go back to the normal mode."));


text:
ESP8266 + Arduino Mega
I am currently carrying out a project where I am using an Arduino Mega2560, to recover data from two ultrasonics sensors (HC-SR-04).
For the purpose of my project, I must add HTTP requests to this, unfortunately the Arduino Mega2560 does not allow me to connect to a WIFI.
I contacted my school, they gave me an ESP32, but as far as I understand I will not be able to connect it to my Arduino 2560?
I also have an esp8266, I found the documentation for the code, but despite many attempts (ex: connecting ESP8266 to mega 2056), I cannot connect, I cannot connect it to my MEGA 2560.
Anyone have any ideas / advice?
Regards,
David

As this is a school assignment, do you really have to use the Mega for the project? They gave you an ESP32, which is way more capable than the Mega. With a 5V (depending on your exact board for example from USB) source and a voltage divider you can directly connect the HC-SR-04 to the ESP.

https://github.com/jandrassy/WiFiEspAT


text:
Arduino NANO (CH340) error while flashing bootloader
Ok. So I'm close to tearing me hair out on this one.
I have a batch of cheap Arduino Nano clones, that just straight up won't work. (I HAVE gotten one of them to work, but I suspect that was by pure coincidence)
Anyway, I feel like I've tried everything to make them work.
I am consistently getting

Device signature = 0xffffff

errors from avrdude, which I believe is a hardware problem. Up til now I have tried:

Installed CH340 drivers, no difference
Tried to burn bootloader using Uno as an ISP (with 10uF cap between reset and ground!)
Tried the "(Old Bootloader)" option in the IDE

All I have left is to desolder the entire board and troubleshoot each single component, but... no, I want to keep my sanity intact, thaaank you!
Any ideas on how I should move forward here?

Does this answer your question? Arduino Nano clone doesn't upload Linux

was the bootloader burning successful?

Had the same problem on Windows 10, using the CH340 drivers from their website:
http://www.wch.cn/download/CH341SER_EXE.html

@Juraj no, unfortunately :(

@VE7JRO I am running Ubutnu 16.04, with the 4.15.0-76-generic kernal

Realize that my Ubuntu install is severely outdated. The problem is that it wont even flash the bootloader on Windows 10, which is up-to-date

Hit reset randomly in the first few seconds of uploading/burning.

Tried, no change. Thank you though!


text:
ESP32 HTTPS server - how to get POST request string
I'm trying to set up an ESP32 (DOIT ESP32 DEVKIT V1 in the Arduino IDE, with Espressif's WiFi libraries) with the following includes so far:
#include <WiFi.h>
#include <WiFiClient.h>
#include <WiFiAP.h>
#include <HTTPSServer.hpp>
#include <SSLCert.hpp>
#include <HTTPRequest.hpp>
#include <HTTPResponse.hpp>

Now, if I have a callback routine that's set up with
ResourceNode * nodeEchoPost = new ResourceNode("/cmd", "POST", &handleEcho);

how can I parse out the POST request string? On the serial console I get
[HTTPS:I] Request: POST /cmd

which is a debug output from the HTTPSRequest library itself. But I have no clue how to get that '/cmd' string for my own use!
I've tried the example code of
byte buffer[256];
size_t s = req->readBytes(buffer, 256);

getting a buffer that only returns garbage, probably because all the request is in the POST statement and the body is empty.
Since all I need is the request-info
'/cmd?command1=foo&command2=bar&etc'

to chop up and use, well.. how do I get that out from the library? I've been googling around, and looking in the library header files, without much luck.
Also, is there any advantage to using the WiFiClientSecure library instead, since everything already goes over HTTPS? That's more of a side question, though if it makes it easier to grab the Request string that way, I'm totally fine with accepting that.

That's a GET and not a POST, so variables are accessible with
auto params = req->getParams();
std::string command1;
std::string cmd2;
bool hascommand1 = params->getQueryParameter("command1", command1);
bool hascmd2 = params->getQueryParameter("cmd2", cmd2);

See example at
https://github.com/fhessel/esp32_https_server/blob/master/examples/Parameters/Parameters.ino
The .c_str() is required to transition from std::string to what println needs, not a problem related to the getRequestString() function itself
I came across this question while looking for ways to read actual POST variables, which is not documented (and the source code does not show sign of it)

I think I found the answer, by looking through examples in the github repo of Hessel's HTTPS library.
In short, this seems to be it:
void handleEcho(HTTPRequest * req, HTTPResponse * res) {

Serial.print("in handleEcho. request is:");
Serial.println(req->getRequestString().c_str());

Output from serial console:
"in handleEcho. request is:/cmd?command1=foo&cmd2=bar"

Now I have a plain-text string that I can use plain string commands on to chop up in parts with strtok or similar. I don't mind the extra hassle of finding keywords in the string, I'm happy to just have gotten the damn thing.
Since I have all the data I want in that request, I'll just use req->readBytes as mentioned in examples to empty the buffer and discard all 'body' data.
And someone's gotta agree with me that adding the .c_str() to an already existing function just seems extra complicated. :/


text:
Arduino Ethernet shield frequently drops its IP address
Im working on a sketch that needs to display some internal variable values and analogue reads in a simple webpage. The only catch is that it needs to be as reliable as possible.
Im getting some odd behaviour across multiple shields where the sketch will work briefly (sometimes as long as 5-6 minutes) before cutting out and setting the IP to something weird (commonly 0.0.0.0 or something similar)
My main loop has some other code in it for reading buttons, values, sensors, etc, but the bulk of it is basically
void loop()
{
  ... do some stuff ...
  // listen for incoming clients
    EthernetClient client = server.available();
    if (client) {
        Serial.println("new client");
        // an http request ends with a blank line
        boolean currentLineIsBlank = true;
        while (client.connected()) {
            if (client.available()) {
                char c = client.read();
                Serial.write(c);
                // if you've gotten to the end of the line (received a newline
                // character) and the line is blank, the http request has ended,
                // so you can send a reply
                if (c == '\n' && currentLineIsBlank) {
                    // send a standard http response header
                    client.println("HTTP/1.1 200 OK");
                    client.println("Content-Type: text/html");
                    client.println("Connnection: close");
                    client.println();
                    client.println("<!DOCTYPE HTML>");
                    client.println("");
                    // add a meta refresh tag, so the browser pulls again every 5 seconds:
                    client.println("<meta http-equiv=\"refresh\" content=\"5\">");
                    // output the value of each analog input pin
                    client.println(getStrDivByTag("MyWebPage", "h3"));
                    client.println("
");

                    client.println("");
                    break;
                }
                if (c == '\n') {
                    // you're starting a new line
                    currentLineIsBlank = true;
                } else if (c != '\r') {
                    // you've gotten a character on the current line
                    currentLineIsBlank = false;
                }
            }
        }
        // give the web browser time to receive the data
        delay(1);
        // close the connection:
        client.stop();
        Serial.println("client disconnected");
    }

  ... do some more stuff ...

}

When the server is working as expected, my serial output gives me something like:

new client
GET / HTTP/1.1
Host: 192.168.1.17
User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:73.0)
  Gecko/20100101 Firefox/73.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,/;q=0.8

But just before it stops working, I get two back to back requests:

GET / HTTP/1.1 Host: 192.168.1.17 User-Agent: Mozilla/5.0 (X11;
Ubuntu; Linux x86_64; rv:73.0) Gecko/20100101 Firefox/73.0 Accept:
text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,/;q=0.8
Accept-Language: en-CA,en-US;q=0.7,en;q=0.3 Accept-Encoding: gzip,
deflate Connection: keep-alive Upgrade-Insecure-Requests: 1
Cache-Control: max-age=0
client disconnected Current Draw: -0.341
192.168.1.17 new client GET /favicon.ico HTTP/1.1 Host:
  192.168.1.17 User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux
  x86_64; rv:73.0)
Gecko/20100101 Firefox/73.0 Accept: image/webp,/ Accept-Language:
en-CA,en-US;q=0.7,en;q=0.3 Accept-Encoding: gzip, deflate Connection:
  keep-alive Cache-Control: max-age=0
client disconnected Current Draw: -0.048
0.0.0.0
Accept-Language: en-CA,en-US;q=0.7,en;q=0.3
Accept-Encoding: gzip, deflate
Connection: keep-alive
Upgrade-Insecure-Requests: 1
Cache-Control: max-age=0
client disconnected

What is that request, something about favicon.ico? After these back to back requests, the IP resets to 0.0.0.0, sometimes jumping to something odd like 0.64.1.0, 0.1.0.64, etc.
Is there an issue with my network configuration, the ethernet2 library Im using?

use the Ethernet library

Make sure you explicitly disable the SD Card slot if you don't use it, by setting pin 4 to high in your setup (at least that's the pin my Ethernet2 shield uses). I almost tore out my hair finding the reason why my (autonomous) sketch would sometimes run for 10 minutes, sometimes an hour, but always stopped responding after some time. It seems the SD Card SPI interface sometimes interferes with Ethernet SPI traffic unless you explicitly disable it.

There are many Ethernet sketch examples that are not reliable at all. They basically handle the network setup in setup(), and the TCP connections in loop(). This is wrong. It just means that if there is anything wrong in your network connection, it won't restart correctly. You should check Ethernet.localIP(); and restart your sketch if it doesn't fit.
This routine should do the trick : void reset() { asm volatile ("jmp 0"); }
Also, you should be ready for requests for a favicon.ico from usual browsers (that's the small icon that comes in your tabs and favorites) and reply to it (you can use a 404 reply if you don't want to send a file). Providing a robots.txt is also good practice.

I dont want to reset the entire sketch as it will bring down some relays transmitting power that the sketch is meant to keep open, but Id imagine it should be possible to just redo the network setup process every time the IP changes, right?

Is there any way of smoothly restarting the Ethernet instance without hard resetting the sketch?

Yes, you have to move the Ethernet start routine from setup, into loop, but in a 'if' statement that checks whether the Ethernet is active or not. I remember having seen a few sketches that did exactly that on github, but I couldn't find them back for referencing them in the answer (maybe they used the old Ethernet ENC28J60 chip). Sorry about that.


text:
How can I make the Serial Monitor work with the Serial Commands library?
I am using the library SerialCommands and I am just trying to print the first text message in the Serial Monitor. But this code does not work for some reason.
The expected result is that the Serial monitor prints a message ("Hello world !!") when I write "hello" and press "enter" as input. Is there something wrong or is this not working like I was expecting? Is there another way to check if these commands work? Is there anythin that I am missing?
#include <SerialCommands.h>

char serial_command_buffer_[32];
SerialCommands serial_commands_(&Serial, serial_command_buffer_, sizeof(serial_command_buffer_), "\r\n", ",");

void cmd_hello(SerialCommands* sender) {
  sender->GetSerial()->println("Hello world !!");
}

SerialCommand cmd_hello_("hello", cmd_hello);

void cmd_unrecognized(SerialCommands* sender, const char* cmd) {
  sender->GetSerial()->print("ERROR: Unrecognized command [");
  sender->GetSerial()->print(cmd);
  sender->GetSerial()->println("]");
}

void setup() {
  Serial.begin(9600); // Serial comm begin at 9600bps
  serial_commands_.AddCommand(&cmd_hello_);
  serial_commands_.SetDefaultHandler(&cmd_unrecognized);
  Serial.println("Ready");
}

void loop() {
  serial_commands_.ReadSerial();
}

Have you chosen the correct line ending in the serial monitor?

Ah that was my mistake, thanks @chrisl. I had to chose "Both NL & CR" ("\r\n"). If you want to post it as answer I will accept it

You defined, that every command will end with \r\n. So you need to choose "Both NL & CR" as line ending in the Serial monitor, so that it appends the line ending to your command. If you don't send the correct line ending, the library will think, that the command hasn't finished yet, and thus will do nothing, until it receives the correct line ending.


text:
Is it possible to modify the animal tags (EM4305) with any module that works with Arduino? 134,2Khz
i have a lot of tags (Animal tags rounded yellow) EM4305, this have 15 spaces of memory and i need change ID writed, currently i'm using this module but it did not can possible write on tag, exist a similar function to Write() from EEPROM, i see that already exist external writers to EM4305, but, is only external?

Why are you linking to a google ad? Please provide a direct link to the module. And what are you talking about EEPROM? I really don't understand, what you mean there and with the "external"

What are the tags used for? In some places ID tags are used to track animals through the supply change and there could be legal consequences to changing the IDs.


text:
ESP8266 GPIO limitations with HC-SR04
I want to build a systems that measures if some parking spots are occupied or not. I chose to use an ESP8266 12-E NodeMCU Kit with multiple HC-SR04 ultrasonic sensors. In my project, it is essential to connect as many ultrasonic sensors to one ESP. Unfortunately, I have found out that if I connect the input/output of the HCSR04 to GPIO 10/9 and GPIO 1/3, The board can't boot. Can anyone explain to me why I cannot use those GPIO pins and what alternatives I have in order to connect more sensors to the ESP (other microcontrollers, pin extenders etc.)?

https://randomnerdtutorials.com/esp8266-pinout-reference-gpios/

The ESP8266 is a very poor choice if you want to use multiple GPIOs. There are very few you can actually use. You are better off using something else. Even the ESP32 is better, though that is still somewhat picky with some GPIOs.


text:
How to connect MPU6050 with Arduino Uno without using A0-A5 pins?
Connecting MPU6050 with Arduino without using A0-A5 pins.

You could use a Software I2C library, like this one on github, which can be used on almost any pin of a board. But keep in mind, that doing such communication in software imposes some limits (for example the linked library can only be a master). Keeping it in hardware is often the better choice, depending on your requirements.

Thanks. I want to connect 5 flex sensors and MPU6050 to arduino uno and i don't know how to make the circuit and code it. Can you help me.

Have you tried to google the individual parts of your project? That should help you a lot. Depending on your flex sensor, they are either a resitive voltage divider by themselves (in which case they exactly behave like a potentiometer, where you can easily google tons of tutorials) or you need an additional resistor to build a voltage divider. For the MPU: With a quick google I haven't found a library for it, that can directly use Software I2C. Depending on how deep you wanna go: You can create your own library or modify an existing one for the MPU6050 to use SoftwareI2C.

Or you can change your plan: Using an external ADC board for measuring the flex sensors or using a different MPU board, which can for example use SPI (like the MPU6000). Think about how you want to build your project and how much time you wanna invest. You can always come to this site and as a specific question


text:
Reading sensor with current ouput with Arduino
I am having diffuclt times with this sensor, so I kndliy ask for your help!
The sensor is named "SPUVA-CS-C3535-A", datasheet here.
The sensor I use (cs3535) has just two pins (+ and -).
From my undesrstanding the ouput is a current corresponding on the UV light exposed to this sensor.
Max value of the current is difficult to understand from the datasheet that also do not have a typical suggested circuit. It seems that a medium value is 200nA, it seems really low!
I have connected (+) of the sensor to 3.3V, (-) of the sensor to A0, and a 220ohm resistor from A0 to Gnd. But readings are always 0.
Any help would be really appreciated! Thanks

The "sensor" is just a photodiode that is sensitive to UV. You use it the same as any photodiode.
The simplest (and crudest) way is to use a very large (eg 1MΩ) pullup resistor to 5V on an ADC pin, then connect the sensor (reverse biased) between the ADC pin and GND.

Thanks. I tried your suggestion, I get an high value (about 600) from the analog input, without UV light on the sensor, and it goes down to 100 when it is exposed. Is this normal? I connected 3.3V -- 1mohm -- (+) sensor (-) Gnd.  A0 to (+) of sensor. Also the read value is not instantyl changed, instead it "drifts" to a value during several seconds...

That sounds about right, yes. As light falls on it some small current leaks through it, reducing the voltage across it.

Ok. Thank you very much for your answer.


text:
Using Arduino Sensors with STM32 based NUCLEO boards
Right now I'm programming an Arduino Uno Rev3, I'm using a Sensor Shield v5 (image at the bottom) to be able to have several Ultrasonic sensors and Servos. Right now I'm thinking about getting a Nucleo board, due to the better CPU, more memory and more flash. Although on the page, Arduino compatibility is listed, I don't quite understand what it means in my case. I understand that it has the same pins as the Arduino, but can I be sure that my Sensor Shield (v5) will work?
I found too little resources about this, one concern was that Arduino and Nucleo board have separate needs (3V or 5V), but the Sensor Shield can get power separately. (Lower right corner.)
Also, there is a Bluetooth shield for the Nucleo, I will buy it if I buy the Nucleo board, how can I know that it will work with the Sensor Shield? Or how can I know how many shields can I connect to a Nucleo or an Arduino?

The "sensor shield" is nothing more than a replacement for wires. You really don't need it. It's just lazy.

buy Arduino Mega if you need more flash and SRAM. what for do you need so much faster CPU? with Mega you will not have problems with 5 V to 3.3 V logic levels.

the support for STM32F4 in the STM32 Arduino core is very new.

Wow! Thanks for the fast reply.
So with Sensor Shield, I wouldn't have problems with 3.3/5V as I mentioned, because it can use a separate power supply.
I wasn't aware of theat Sensor Shield is lazy, I got it with my Arduino and it helped me a lot, also I think I would need a breadboard for 7 sensor without it, so it stays.
I just don't understand how many shields I can get to Arduino/STM32 because I don't quite understand how I can read values from them if I connect (for example) a Bluetooth Shield and several other shield.


text:
How can I display text on OLED?
I'm trying to print the information, which is received from the other ESP32 by CAN transceiver, on an OLED. The CAN bus is working perfectly, as the 'HELLO WORLD' is already be received. But I can't print the received 'HELLO WORLD' on OLED (also the OLED is work). The code shows below,

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

#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 32 // OLED display height, in pixels

Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);

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

  if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
    Serial.println(F("SSD1306 allocation failed"));
    for (;;);
  }
  delay(2000);
  display.clearDisplay();
  display.setTextColor(WHITE);

  Serial.println("CAN Receiver");
  CAN.setPins(16, 17);
  // start the CAN bus at 500 kbps
  if (!CAN.begin(500E3)) {
    Serial.println("Starting CAN failed!");
    while (1);
  }
}

void loop() {
  // try to parse packet
  int packetSize = CAN.parsePacket();

  if (packetSize) {
    // received a packet
    Serial.print("Received ");

    if (CAN.packetExtended()) {
      Serial.print("extended ");
    }

    if (CAN.packetRtr()) {
      // Remote transmission request, packet contains no data
      Serial.print("RTR ");
    }

    Serial.print("packet with id 0x");
    Serial.print(CAN.packetId(), HEX);

    if (CAN.packetRtr()) {
      Serial.print(" and requested length ");
      Serial.println(CAN.packetDlc());
    } else {
      Serial.print(" and length ");
      Serial.println(packetSize);

      // only print packet data for non-RTR packets
      while (CAN.available()) {
        Serial.print((char)CAN.read());
      }
      Serial.println();
    }

    Serial.println();
  }
  delay(5000);

  display.clearDisplay();

  display.print((char)CAN.read());

  display.display();
}

To show code in your question, please edit your question, highlight the entire code segment, and click the '{}' button. It will be much easier for potential contributors to read it and answer your question.

please format your code ... use the {} button or put ``` before and after your code

Are we asking noah to fix his post formatting so he learns how to post a question the includes formatted code rather than editing his question and doing the formatting for him?

@DuncanC - noah is a "New contributor", so it's possible that one of our users was trying to be nice and help them out. Editing and improving Q+A's is encouraged by Stack Exchange, and there are 3 levels of "badges" awarded for editing them. Users with less than 1000 reputation are given 2 reputation for editing a question. I know of one Arduino SE user that has over 500 reputation and has never asked nor answered a single question. I agree with you about teaching, but I also have to "be nice", and lets not forget about those hardworking volunteers who edit questions to make our site better.

@VE7JRO, I was tempted to apply the edit myself, but didn't because I wondered if the "please code format your question" suggestions are "teach a user to post" moments. I'm fairly new on the Arduino site, but have a >100K rep on Stack Overflow, so pretty familiar with how Stack Exchange works.

Just guessing but looks to me like you read the CAN message and print it character by character to the Serial console but you don't save those characters in a buffer as you get them from CAN.read(). So when you then try to display.print((char)CAN.read()); at that point there are no more characters to available for the CAN.read() to read so nothing is printed by the display.print(). I'm just guessing though.

@RichardChambers Thanks mate! you save my life.

@RichardChambers Consider pasting your reply as an answer below, so it can be selected by Noah as the correct answer. For those sweet, sweet internet points ;) (and because then this question won't show up in the "unanswered" list)

@KenVanHoeylandt Thanks for the note. I just didn't think of it.

Just guessing but looks to me like you read the CAN message and print it character by character to the Serial console but you don't save those characters in a buffer as you get them from CAN.read().
So when you then try to display.print((char)CAN.read()); at that point there are no more characters to available for the CAN.read() to read so nothing is printed by the display.print().
So what you need to do is to read the characters into a buffer so that you save them after reading them so that you can use the text string for other purposes.


text:
Controlling VFD with ModBus RTU via RS485 and Arduino
I am attempting to control a Folinn VFD (Manual: Manual) with an Arduino Uno via a MAX485 module such as this.

Pins for MAX485:

DI > D8
DE & RE > D10
RO > D11

VFD settings:

F00.01 set to 2
F00.06 set to 9
F13.00 set to 1
F13.01 set to 5
F13.02 set to 3

At this stage I am attempting a very simple code just to turn the VFD on:
/*

   ModBus RTU control VFD

   Address               : 01H  (is the address of the VFD)
   Function              : 06H  (write function code)
   Starting data address : 20H
                         : 00H  (2000H  is the address of control command)
   Data(2Byte)           : 00H
                         : 01H  (0001H is forward command)
   CRC CHK Low           : 43H
   CRC CHK High          : CAH

*/

#include <SoftwareSerial.h>

#define SSerialRX        11  //Serial Receive pin
#define SSerialTX        8  //Serial Transmit pin
#define SSerialTxControl 10   //RS485 Direction control
#define RS485Transmit    HIGH
#define RS485Receive     LOW
#define Pin13LED         13

// From manual vfd Forward command = 01H 06H 2000H 0001H 43CAH

byte request1[] = {0x01, 0x06, 0x20, 0x00, 0x00, 0x01, 0x43, 0xCA};

SoftwareSerial RS485Serial(SSerialRX, SSerialTX); // RX, TX
byte byteSend;

void setup()
{
  // Start the built-in serial port, probably to Serial Monitor
  Serial.begin(9600);
  Serial.println("SerialRemote");  // Can be ignored

  pinMode(Pin13LED, OUTPUT);
  pinMode(SSerialTxControl, OUTPUT);

  // digitalWrite(SSerialTxControl, RS485Receive);  // Init Transceiver

  RS485Serial.begin(9600);

}
void loop()
{
    digitalWrite(SSerialTxControl, RS485Transmit);
    RS485Serial.write(request1, sizeof(request1));

}

With the MAX485 connected to the correct ports (S+ and S-) on the VFD, this current setup receives no response is someone able to spot where I am going wrong? I have taken the values for CRC CHK Low & High from a different example, is this the issue?
Have also tried setting F00.01 to an unlisted '3' setting that I have seen pop up in other discussions but this made no difference. Any advice would be much appreciated, let me know if I can supply further details.
(I chose this method based on this example

User on other site (https://forum.arduino.cc/index.php?topic=663365.0) Might have default run conditons on VFD set differently or by hardware.
Check the VFD is listening to the ModBus Comms.  OK.
Check VFD is 'Ready to Run'. Hardwire e-stop or 'Active' inputs.
F00.22 Check Binding source
F00.05 Check Set min Hz
F01.01 Check Set min Hz
Give drive MIN Hz So when received RUN signal has default speed to goto.
Are you doing a Hard Reset on the UNO every time you want to send the Modbus string? Code runs once, does not actively transmit.

Hi Spannerz, thanks for the suggestion
I have set:

F00.01 Command source selection - 2:RS 485 communication control
F00.06 Frequency A command selection - 9:RS 485 Communication

Is there another setting I need to look at to be sure it is listening to ModBus?

OK.   F00.06 is the frequency setpoint.   Sure you can send it a number of the speed you want to run at, but are you?  Almost suggest setting to 1:Keypad value, retentive on power failure.        RUN signal is different to SPEED setpoint.

I'll be back tomorrow.   Cheers.

That makes a lot of sense. Will try setting the frequency via keypad and just sending the run command.
Will give it a crack in the morning and let you know how it goes.

Hi Spannerz, thanks for the additional information.
I have been hard resetting the UNO so I think the problem lies in one of the settings you have mentioned.
Flat out this morning but will try adjusting these settings later today and report back

Hi Spannerz, have still not been getting the VFD to operate via the Arduino even with F00.06 set to keypad. What settings should I be inputting for F00.22? I think this may be the issue.

I'd try = 1.   Making sure keypad value is the running frequency the drive is referencing.

Couldn't get it going through Modbus unfortunately.
But managed to get Start/Stop & Frequency control using the digital inputs with the Arduino controlling relays. Bit more of a clumsy work around but will work for the needs of this project.
Thanks so much for your advice.


text:
Adafruit thermal printer prints weak
I am currently hooking up my arduino to an adafruit mini thermal printer. When a button is pressed, some code is executed which then sends some information to the thermal printer.
Everything works fine except the thermal printer print is very weak and can barely be seen as soon as the printer needs to print more than 3-5 chars. Any ideas why? Both, the arduino and the thermal printer are hooked up to 9V batteries.
Here is the code
#include "Adafruit_Thermal.h"

// Here's the new syntax when using SoftwareSerial (e.g. Arduino Uno) ----
// If using hardware serial instead, comment out or remove these lines:

#include "SoftwareSerial.h"
#define TX_PIN 6 // Arduino transmit  YELLOW WIRE  labeled RX on printer
#define RX_PIN 5 // Arduino receive   GREEN WIRE   labeled TX on printer

SoftwareSerial mySerial(RX_PIN, TX_PIN); // Declare SoftwareSerial obj first
Adafruit_Thermal printer(&mySerial);     // Pass addr to printer constructor

int buttonIn = 8;
int val = 0;

void setup() {
  pinMode(7, OUTPUT);
  digitalWrite(7, LOW);

  pinMode(buttonIn, INPUT);

   mySerial.begin(19200);  // Initialize SoftwareSerial
   //Serial.begin(19200); // Use this instead if using hardware serial
   printer.begin();        // Init printer (same regardless of serial type)
}

void loop() {
  // put your main code here, to run repeatedly:
     val = digitalRead(buttonIn);
     if(val == HIGH)
     {
        printer.println("test");
        printer.sleep();      // Tell printer to sleep
        delay(3000L);         // Sleep for 3 seconds
        printer.wake();       // MUST wake() before printing again, even if reset
        printer.setDefault();

     }
}

Did I set up anything false? Is the power supply not enough?
The adafruit was sent with a selftest from the seller where everything seemed to be fine.
Left, seller test, second from left, my selftest, third and fourth from left are example printer and charset tests.

And here you can see how everything is wired together.

Thank you very much!

the problem is always the 9 V battery

9V batteries are utter $%^*. The printer needs a proper power supply (2A) or some big meaty high current bateries (lithium rechargeables).

The datasheet states:
Requires 5-9VDC @ 1.5Amp power supply during print.
In my experience this printer provides best results when operated at its upper limit. I am using a 9V 2A power supply for that. A bettery is definitiverly not enough.

So how would I provide a mobile power source? Many people state that powerbanks aren't a sufficient power source either.

There are beefy powerbanks that can provide up to 3A @ 5V. Those are not cheap and sadly most powerbanks do not provide the current that is printed on the case. I'd suggest you use batteries for RC cars. These are beefy and you will find a model that provides around 7.2V. Which perfectly fits in the range of the printer.

Just an example: This Battery can provide up to 40A. (2Ah * 20C = 40A) So you might get away with a smaller one.

The keyword here is Li Ion or a LiPo battery (the one linked by Kwasmich is a Li Ion battery). These are used in high power applications like drones, so with these you are good to go. 9V block batteries are for low power projects, nothing more.

@chrisl Okay thank you all. I'll definitely look into Li Ion and LiPo batteries. I want to use a small power source since the whole build should be portable in a box. I got a powerbank that can output 2.1A / 5V. Would this be sufficient?

5-9 V and 1.5 A? Sounds like a job for a 2s2p 18650 setup.

In theory, yes. But my experience is that the voltage breaks down to around 4V at this current. So the answer is most certainly: NO.

Okay, I hooked up the powerbank directly to the thermal printer. The print is way better now and sufficient for my needs. Thanks guys!

Proper care of your thermal transfer printer is critical to keeping it at peak performance for as long as possible. Keep reading for five tips to keep your thermal transfer printer running optimally so you don’t have to spend on unnecessary new parts or wasted media down the line.

Maintain The Right Heat And Speed Ratio
These two things are true:

High print speeds can improve throughput
Higher heat increases the darkness of your print and therefore the contrast of your barcodes.
However, the wrong ratio can lead to print issues and even damage your printhead.
We generally recommend running your printer on a relatively slow setting. This uses less heat and ensures a crisp, clear printed image. On a similar note, we recommend you avoid increasing heat settings without guidance from a professional.
If you work with a supplier who sets up and tests your printer with your media prior to shipping it to you, they have likely adjusted the heat and speed ratio to one suitable for your application.
Maintaining a proper heat and speed ratio will ensure a scannable barcode and extend the life of your printhead so you can avoid costly waste and unnecessary part replacements.

Keep The Print Head Clean
Keeping your print head clean is imperative to maintaining your printer. Without regular cleaning, your print head will be more susceptible to abrasion during printing. This can reduce image quality and shorten the life of your printer.

We recommend you establish a schedule for regular print head cleaning. Our technical team endorses cleaning this part whenever you replace the label roll or install a new ribbon.

Protect The Print Head From The Media
To safeguard the print head against abrasion, use a thermal transfer ribbon that’s slightly wider than the media.

Don’t Use Razor Blades Or Box Cutters
Unless you’re using a model with a peeler or applicator, you should only use tools such as the printer’s tear bar or scissors to remove labels. Razor blades, box cutters, and other inappropriate tools can easily slip and cut the driver roller. These cuts can create voids in your printed labels leading to misreads.

Avoid “Ribbon Wrinkles”
If you’re seeing seemingly random diagonal lines on your print you’re probably dealing with ribbon wrinkles. The main culprit of ribbon wrinkles is too much heat, so your first option is to lower the heat setting. If that doesn’t work, make sure your printer is set up properly. Check that the ribbon is loaded correctly, the media guides are set properly, and the head pressure is balanced. If you’re still experiencing issues you might want to reach out to your supplier to ensure your media and ribbon combination is ideal.

Regards,
Peter

whenever you replace the label roll or install a new ribbon ... Avoid “Ribbon Wrinkles” - what ribbons are you referring to? Thermal printers don't have ribbons. We recommend you establish a schedule - who is "we" here? Are there two Peter Grofts?


text:
multiple RC522 RFID on arduino yun
I was trying for one month to make multiple RC522 rfid readers work together on SPI on an arduino yun, one works fine, but if I plug 4, each with a specific slave select, only one, sometimes 2, sometimes none are working.
The library i use is RFID.h (i think the miguelbalboa one) , but I had the same results with MFRC522.h wich have a specific readUidMultiReader so I dont think my code is at fault.
Searching for this issue, I found this question wich is basically my issue, as I suspect the readers I bought are not supporting multidrop. These readers dont work either.
I read about solutions using multiplexers for SPI lines, tristate buffers on miso lines and/or diodes but these are workarounds, and there should be a more straightforward solution.
Also I tested with no resistors most of the time, but tried putting 10kΩ from all MISO to 3v3, no change, as i really dont understand what their use are, even if I feel they could be mandatory.

I am using a yun for the builtin ethernet, because I tried nanos with ethernet shields and again the shields are ignoring the Slave select and thus not working with spi multidrop, so each time I plugged the shield on nano, even not using it, rfid stopped working.

your note about Ethernet shield makes me think you don't set all CS pin HIGH before begin() the individual devices in setup()

I have the same problem.
Did you find a solution ?
how to put HIGH the CSin the code ? Best regard.

Multiple SPI devices on the same bus shouldn't be a problem. I would try the following steps to narrow down the problem:

Add Pull-Up resistors to each CS line (10k should be enough)
(The is no need for resistors on the MISO, MOSI or CLK lines since they a push/pull when active)
Make sure each CS is set to HIGH before you attempt to access the reader
Use a simple sketch that only access 1 reader.

if you could access the first reader -> change the sketch to use the second one without changing the hardware setup. Continue until you've checked all readers.
if you are not able to communicate with one reader, you still have a bug in your hardware setup

When the readers work independently, you could start to write your sketch using more than one at a time. (depending on the libraries this could be quite difficult since the lib must support multiple instances, but first we should check the hardware setup)

I suppose that digital output power from yun is insufficient to drive all four readers - so, you need to add some digital buffers to MOSI, SCK, and RST lines.
74LS07 digital buffer:

can vcc and ground of the digital buffer be the ones of the yun (as they can output more intensity than the pins) or must they be from an external source then ?

Yes, they can ofk

You shouldn't need buffers for the SPI lines. The only power needed on these lines is the charge the input capacities on the slaves / master und 5 devices on a bus don't need much current.


text:
Mediatek GPS periodic mode
I'm trying to build a low power GPS datalogger and I am trying to get the Mediatek based GPS module (Quectel L80-R) to run in periodic mode. I've sent the PMTK225 code to the module with various parameters, but it never seems to go into stand by or back up mode. Code below.
//Testing that commands sent to the GPS unit work

#include <NeoSWSerial.h>
NeoSWSerial gpsPort(3,2); // pins 3/2

#include <NMEAGPS.h>
NMEAGPS gps;

void setup() {

  // connect at 115200 so we can read the GPS fast enough and echo without   dropping chars
  // also spit it out
  Serial.begin(115200);

  gpsPort.begin( 9600 );
  gps.send_P( &gpsPort, F("PMTK605")); //firmware version
  delay(100);
  //gps.send_P( &gpsPort, F("PMTK314,-1")); //reset to default
  //gps.send_P( &gpsPort, F("PMTK314,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0") ); // RMC_GGA
  //gps.send_P( &gpsPort, F("PMTK314,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0") ); // RMC only
  delay( 100 );
  //gps.send_P( &gpsPort, F("PMTK220,200") );  // 5Hz
  //gps.send_P( &gpsPort, F("PMTK220,1000") ); //1hz
  delay( 100 );
  //gps.send_P( &gpsPort, F("PMTK225,0")); // normal mode
  //gps.send_P( &gpsPort, F("PMTK223,1,25,180000,60000")); // ephemeris data receiving
  gps.send_P( &gpsPort, F("PMTK225,2,3000,10000")); //period mode but not working
  //gps.send_P( &gpsPort, F("PMTK161")); //stand by mode
  //gps.send_P( &gpsPort, F("PMTK103")); //cold start
  delay(100);
  gps.send_P( &gpsPort, F("PMTK314,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0") ); // RMC only

  //gps.send_P( &gpsPort, F("PGCMD,33,0") );   // No antenna status messages needed
  delay( 100 );

  Serial.println("Ready!");
}

void loop() {
  if (gpsPort.available())
    Serial.write( gpsPort.read() );
}

So what is the question?

Why will it not go into periodic standby with the code above?

Quectel L80-R does NOT have periodic mode, while the L80 does.


text:
I2C and SPI using sensor and Oled display
Im currently working on a project which displays vital signs such as pulse and oxygen on my display. Now, my sensor is connected through I2C while my OLED runs through SPI. Im trying to display the sensor readings on the OLED but that doesnt seem to work. Tried reading through the threads and wasnt able to come up with a concise solution.
Anyone with a similar case and working solution will truly appreciate the support.
#include <OneWire.h>
#include <DallasTemperature.h>
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <Arduino.h>
#include "algorithm.h"
#include "max30102.h"

#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels

// Declaration for SSD1306 display connected using
// software SPI (default case):
#define OLED_MOSI   11
#define OLED_CLK   13
#define OLED_DC    9
#define OLED_CS    12
#define OLED_RESET 8
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT,
  OLED_MOSI, OLED_CLK, OLED_DC, OLED_RESET, OLED_CS);

#define ONE_WIRE_BUS 4
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors( &oneWire );

#define MAX_BRIGHTNESS 255

#if defined(ARDUINO_AVR_UNO)
// Arduino Uno doesn't have enough SRAM to store
// 100 samples of IR led data and red led data in 32-bit format
// To solve this problem, 16-bit MSB of the sampled data
// will be truncated. Samples become 16-bit data.
uint16_t aun_ir_buffer[100]; //infrared LED sensor data
uint16_t aun_red_buffer[100];  //red LED sensor data
#else
uint32_t aun_ir_buffer[100]; //infrared LED sensor data
uint32_t aun_red_buffer[100];  //red LED sensor data
#endif

// data length
int32_t n_ir_buffer_length;
// SPO2 value
int32_t n_spo2;
// indicator to show if the SPO2 calculation is valid
int8_t ch_spo2_valid;

// heart rate value
int32_t n_heart_rate;

// indicator to show if the heart rate calculation is valid
int8_t  ch_hr_valid;
uint8_t uch_dummy;

void setup()
{
  //resets the MAX30102
  maxim_max30102_reset();

  // initialize serial communication at 115200 bits per second:
  Serial.begin(115200);

  // pin D10 connects to the interrupt output pin of the MAX30102
  pinMode(10, INPUT);
  delay(1000);

  // Reads/clears the interrupt status register
  maxim_max30102_read_reg(REG_INTR_STATUS_1,&uch_dummy);
  // wait until user presses a key
  while( Serial.available() == 0 )
  {
    Serial.write(27);       // ESC command
    Serial.print(F("[2J")); // clear screen command
    Serial.println(F("Press any key to start conversion"));
    delay(1000);
  }

  uch_dummy=Serial.read();
  maxim_max30102_init();

  Serial.begin(115200);
  sensors.begin();

  if(!display.begin(SSD1306_SWITCHCAPVCC))
  {
    Serial.println(F("SSD1306 allocation failed"));
  }

  display.clearDisplay();
  display.setTextSize(2);
  display.setTextColor(WHITE);
  display.setCursor(30,30);
  display.print("ATRAL:D");
  display.display();
  delay(1000);
  display.clearDisplay();
}

void loop()
{
  // Call sensors.requestTemperatures() to issue
  // a global temperature and Requests to all devices on the bus
  sensors.requestTemperatures();

  Serial.print("Celsius temperature: ");
  // Why "byIndex"? You can have more than
  // one IC on the same bus. 0 refers to the first IC on the wire
  Serial.print(sensors.getTempCByIndex(0));
  Serial.print(" - Fahrenheit temperature: ");
  Serial.println(sensors.getTempFByIndex(0));
  delay(100);

  // variables to calculate the on-board LED
  // brightness that reflects the heartbeats
  uint32_t un_min, un_max, un_prev_data, un_brightness;
  int32_t i;
  float f_temp;

  un_brightness=0;
  un_min=0x3FFFF;
  un_max=0;

  // buffer length of 100 stores 4 seconds
  // of samples running at 25sps
  n_ir_buffer_length=100;

  // read the first 100 samples, and determine the signal range
  for( i=0; i < n_ir_buffer_length; i++ )
  {
    // wait until the interrupt pin asserts
    while( digitalRead(10) == 1 );
    //read from MAX30102 FIFO
    maxim_max30102_read_fifo( ( aun_red_buffer + i ),
                              ( aun_ir_buffer + i ) );

    if(un_min>aun_red_buffer[i])
      un_min=aun_red_buffer[i];  //update signal min
    if(un_max<aun_red_buffer[i])
      un_max=aun_red_buffer[i];  //update signal max
    Serial.print(F("red="));
    Serial.print(aun_red_buffer[i], DEC);
    Serial.print(F(", ir="));
    Serial.println(aun_ir_buffer[i], DEC);
  }
  un_prev_data=aun_red_buffer[i];

  // calculate heart rate and SpO2 after first 100 samples
  // (first 4 seconds of samples)
  maxim_heart_rate_and_oxygen_saturation( aun_ir_buffer,
         n_ir_buffer_length, aun_red_buffer,
         &n_spo2, &ch_spo2_valid, &n_heart_rate,
         &ch_hr_valid );

  // Continuously taking samples from MAX30102.
  // Heart rate and SpO2 are calculated every 1 second
  while(1)
  {
    i=0;
    un_min=0x3FFFF;
    un_max=0;

    // dumping the first 25 sets of samples
    // in the memory and shift the last 75 sets
    // of samples to the top
    for( i=25; i<100; i++ )
    {
      aun_red_buffer[i-25]=aun_red_buffer[i];
      aun_ir_buffer[i-25]=aun_ir_buffer[i];

      //update the signal min and max
      if(un_min>aun_red_buffer[i])
        un_min=aun_red_buffer[i];
      if(un_max<aun_red_buffer[i])
        un_max=aun_red_buffer[i];
    }

    //take 25 sets of samples before calculating the heart rate.
    for( i=75; i<100; i++ )
    {
      un_prev_data=aun_red_buffer[i-1];
      while(digitalRead(10)==1);
      digitalWrite(9, !digitalRead(9));
      maxim_max30102_read_fifo((aun_red_buffer+i), (aun_ir_buffer+i));

      //calculate the brightness of the LED
      if(aun_red_buffer[i]>un_prev_data)
      {
        f_temp=aun_red_buffer[i]-un_prev_data;
        f_temp/=(un_max-un_min);
        f_temp*=MAX_BRIGHTNESS;
        f_temp=un_brightness-f_temp;
        if(f_temp<0)
          un_brightness=0;
        else
          un_brightness=(int)f_temp;
      }
      else
      {
        f_temp=un_prev_data-aun_red_buffer[i];
        f_temp/=(un_max-un_min);
        f_temp*=MAX_BRIGHTNESS;
        un_brightness+=(int)f_temp;
        if(un_brightness>MAX_BRIGHTNESS)
          un_brightness=MAX_BRIGHTNESS;
      }
#if defined(ARDUINO_AVR_LILYPAD_USB)
      analogWrite(13, un_brightness);
#endif

#if defined(ARDUINO_AVR_FLORA8)
      LED.setPixelColor(0, un_brightness/BRIGHTNESS_DIVISOR, 0, 0);
      LED.show();
#endif

      //send samples and calculation result to terminal program through UART
      Serial.print(F("red="));
      Serial.print(aun_red_buffer[i], DEC);
      Serial.print(F(", ir="));
      Serial.print(aun_ir_buffer[i], DEC);

      Serial.print(F(", HR="));
      Serial.print(n_heart_rate, DEC);

      Serial.print(F(", HRvalid="));
      Serial.print(ch_hr_valid, DEC);

      Serial.print(F(", SPO2="));
      Serial.print(n_spo2, DEC);

      Serial.print(F(", SPO2Valid="));
      Serial.println(ch_spo2_valid, DEC);
    }
    maxim_heart_rate_and_oxygen_saturation(aun_ir_buffer, n_ir_buffer_length, aun_red_buffer, &n_spo2, &ch_spo2_valid, &n_heart_rate, &ch_hr_valid);
  }

  display.clearDisplay();
  display.setTextSize(1);
  display.setTextColor(WHITE);
  display.setCursor(0,0);
  display.print("Temp: ");
  display.print(sensors.getTempCByIndex(0));
  display.print("C");
  display.setCursor(0,10);
  display.print("Temp: ");
  display.print(sensors.getTempFByIndex(0));
  display.print("F");
  display.setCursor(0,20);
  display.print("HR: ");
  display.print(n_heart_rate, DEC);
  display.setCursor(0,30);
  display.print("02: ");
  display.print(n_spo2, DEC);
  display.setCursor(0,50);
  display.setTextSize(2);
  display.print("BOX.E");
  display.display();
  display.clearDisplay();

}

Sure thing, Ill share two separate sketches, the sensor sketch that I want to combine with the Oled sketch that has a temperature sensor in it too

@VE7JRO I Hope the codes will help

"Doesn't seem to work" is not a good description of the problem. We cannot know, what that means. You need to tell us, what you expected with each code and what exactly is actually happening. Also: You have included 2 seperate sketches, but your question is more why the combination does not work. For answering that, we need to see your combined code.

@chrisl Thank you for highlighting and clarifying, Ill do what you've suggested and get back

@chrisl the code has been modified and thank you all for editing it.. kinda new to the whole community and formatting