text:
Connecting NFC reader and fingerprint scanner to arduino
Im new to NFC and am currently working on a project dealing with NFC and security, where I use biometrics to authenticate NFC cards, when being used during payments. I've been able to get both the reader and fingerprint scanner working seperately (connected when the other isn't), although when trying to connect both i came across some issues. I've redifined the digital pin locations for the fingerprint scanner assuming it would work, though it didn't work and so im now not sure what the issues maybe. On top of this i think that my fingerprint scanner maybe broken, which might also be the issue, but if someone could guide me on connecting these two types of devices to the board it would be very appreciated.
Code used for the fingerprint scanner from adafruit fringerprint scanner lib (incase anyone wanted to check it out)

#include <Adafruit_Fingerprint.h>

// On Leonardo/Micro or others with hardware serial, use those! #0 is green wire, #1 is white
// uncomment this line:
// #define mySerial Serial1

// For UNO and others without hardware serial, we must use software serial...
// pin #2 (switch to 8) is IN from sensor (GREEN wire)
// pin #3 (switch to 9) is OUT from arduino  (WHITE wire)
// comment these two lines if using hardware serial
SoftwareSerial mySerial(8, 9);

Adafruit_Fingerprint finger = Adafruit_Fingerprint(&mySerial);

uint8_t id;

void setup()
{
  Serial.begin(9600);
  while (!Serial);  // For Yun/Leo/Micro/Zero/...
  delay(100);
  Serial.println("\n\nAdafruit Fingerprint sensor enrollment");

  // set the data rate for the sensor serial port
  finger.begin(57600);

  if (finger.verifyPassword()) {
    Serial.println("Found fingerprint sensor!");
  } else {
    Serial.println("Did not find fingerprint sensor :(");
    while (1) { delay(1); }
  }
}

uint8_t readnumber(void) {
  uint8_t num = 0;

  while (num == 0) {
    while (! Serial.available());
    num = Serial.parseInt();
  }
  return num;
}

void loop()                     // run over and over again
{
  Serial.println("Ready to enroll a fingerprint!");
  Serial.println("Please type in the ID # (from 1 to 127) you want to save this finger as...");
  id = readnumber();
  if (id == 0) {// ID #0 not allowed, try again!
     return;
  }
  Serial.print("Enrolling ID #");
  Serial.println(id);

  while (!  getFingerprintEnroll() );
}

uint8_t getFingerprintEnroll() {

  int p = -1;
  Serial.print("Waiting for valid finger to enroll as #"); Serial.println(id);
  while (p != FINGERPRINT_OK) {
    p = finger.getImage();
    switch (p) {
    case FINGERPRINT_OK:
      Serial.println("Image taken");
      break;
    case FINGERPRINT_NOFINGER:
      Serial.println(".");
      break;
    case FINGERPRINT_PACKETRECIEVEERR:
      Serial.println("Communication error");
      break;
    case FINGERPRINT_IMAGEFAIL:
      Serial.println("Imaging error");
      break;
    default:
      Serial.println("Unknown error");
      break;
    }
  }

  // OK success!

  p = finger.image2Tz(1);
  switch (p) {
    case FINGERPRINT_OK:
      Serial.println("Image converted");
      break;
    case FINGERPRINT_IMAGEMESS:
      Serial.println("Image too messy");
      return p;
    case FINGERPRINT_PACKETRECIEVEERR:
      Serial.println("Communication error");
      return p;
    case FINGERPRINT_FEATUREFAIL:
      Serial.println("Could not find fingerprint features");
      return p;
    case FINGERPRINT_INVALIDIMAGE:
      Serial.println("Could not find fingerprint features");
      return p;
    default:
      Serial.println("Unknown error");
      return p;
  }

  Serial.println("Remove finger");
  delay(2000);
  p = 0;
  while (p != FINGERPRINT_NOFINGER) {
    p = finger.getImage();
  }
  Serial.print("ID "); Serial.println(id);
  p = -1;
  Serial.println("Place same finger again");
  while (p != FINGERPRINT_OK) {
    p = finger.getImage();
    switch (p) {
    case FINGERPRINT_OK:
      Serial.println("Image taken");
      break;
    case FINGERPRINT_NOFINGER:
      Serial.print(".");
      break;
    case FINGERPRINT_PACKETRECIEVEERR:
      Serial.println("Communication error");
      break;
    case FINGERPRINT_IMAGEFAIL:
      Serial.println("Imaging error");
      break;
    default:
      Serial.println("Unknown error");
      break;
    }
  }

  // OK success!

  p = finger.image2Tz(2);
  switch (p) {
    case FINGERPRINT_OK:
      Serial.println("Image converted");
      break;
    case FINGERPRINT_IMAGEMESS:
      Serial.println("Image too messy");
      return p;
    case FINGERPRINT_PACKETRECIEVEERR:
      Serial.println("Communication error");
      return p;
    case FINGERPRINT_FEATUREFAIL:
      Serial.println("Could not find fingerprint features");
      return p;
    case FINGERPRINT_INVALIDIMAGE:
      Serial.println("Could not find fingerprint features");
      return p;
    default:
      Serial.println("Unknown error");
      return p;
  }

  // OK converted!
  Serial.print("Creating model for #");  Serial.println(id);

  p = finger.createModel();
  if (p == FINGERPRINT_OK) {
    Serial.println("Prints matched!");
  } else if (p == FINGERPRINT_PACKETRECIEVEERR) {
    Serial.println("Communication error");
    return p;
  } else if (p == FINGERPRINT_ENROLLMISMATCH) {
    Serial.println("Fingerprints did not match");
    return p;
  } else {
    Serial.println("Unknown error");
    return p;
  }

  Serial.print("ID "); Serial.println(id);
  p = finger.storeModel(id);
  if (p == FINGERPRINT_OK) {
    Serial.println("Stored!");
  } else if (p == FINGERPRINT_PACKETRECIEVEERR) {
    Serial.println("Communication error");
    return p;
  } else if (p == FINGERPRINT_BADLOCATION) {
    Serial.println("Could not store in that location");
    return p;
  } else if (p == FINGERPRINT_FLASHERR) {
    Serial.println("Error writing to flash");
    return p;
  } else {
    Serial.println("Unknown error");
    return p;
  }
}

And code for the NFC reader from adafruit pn532 lib
   #include <Wire.h>
#include <SPI.h>
#include <Adafruit_PN532.h>

// If using the breakout with SPI, define the pins for SPI communication.
#define PN532_SCK  (2)
#define PN532_MOSI (3)
#define PN532_SS   (4)
#define PN532_MISO (5)

// If using the breakout or shield with I2C, define just the pins connected
// to the IRQ and reset lines.  Use the values below (2, 3) for the shield!
#define PN532_IRQ   (2)
#define PN532_RESET (3)  // Not connected by default on the NFC Shield

// Uncomment just _one_ line below depending on how your breakout or shield
// is connected to the Arduino:

// Use this line for a breakout with a software SPI connection (recommended):
Adafruit_PN532 nfc(PN532_SCK, PN532_MISO, PN532_MOSI, PN532_SS);

// Use this line for a breakout with a hardware SPI connection.  Note that
// the PN532 SCK, MOSI, and MISO pins need to be connected to the Arduino's
// hardware SPI SCK, MOSI, and MISO pins.  On an Arduino Uno these are
// SCK = 13, MOSI = 11, MISO = 12.  The SS line can be any digital IO pin.
//Adafruit_PN532 nfc(PN532_SS);

// Or use this line for a breakout or shield with an I2C connection:
//Adafruit_PN532 nfc(PN532_IRQ, PN532_RESET);

void setup(void) {
  Serial.begin(115200);
  while (!Serial) delay(10); // for Leonardo/Micro/Zero

  Serial.println("Hello!");

  nfc.begin();

  uint32_t versiondata = nfc.getFirmwareVersion();
  if (! versiondata) {
    Serial.print("Didn't find PN53x board");
    while (1); // halt
  }
  // Got ok data, print it out!
  Serial.print("Found chip PN5"); Serial.println((versiondata>>24) & 0xFF, HEX);
  Serial.print("Firmware ver. "); Serial.print((versiondata>>16) & 0xFF, DEC);
  Serial.print('.'); Serial.println((versiondata>>8) & 0xFF, DEC);

  // configure board to read RFID tags
  nfc.SAMConfig();

  Serial.println("Waiting for an ISO14443A Card ...");
}

void loop(void) {
  uint8_t success;
  uint8_t uid[] = { 0, 0, 0, 0, 0, 0, 0 };  // Buffer to store the returned UID
  uint8_t uidLength;                        // Length of the UID (4 or 7 bytes depending on ISO14443A card type)

  // Wait for an ISO14443A type cards (Mifare, etc.).  When one is found
  // 'uid' will be populated with the UID, and uidLength will indicate
  // if the uid is 4 bytes (Mifare Classic) or 7 bytes (Mifare Ultralight)
  success = nfc.readPassiveTargetID(PN532_MIFARE_ISO14443A, uid, &uidLength);

  if (success) {
    // Display some basic information about the card
    Serial.println("Found an ISO14443A card");
    Serial.print("  UID Length: ");Serial.print(uidLength, DEC);Serial.println(" bytes");
    Serial.print("  UID Value: ");
    nfc.PrintHex(uid, uidLength);
    Serial.println("");

    if (uidLength == 4)
    {
      // We probably have a Mifare Classic card ...
      Serial.println("Seems to be a Mifare Classic card (4 byte UID)");

      // Now we need to try to authenticate it for read/write access
      // Try with the factory default KeyA: 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
      Serial.println("Trying to authenticate block 4 with default KEYA value");
      uint8_t keya[6] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };

      // Start with block 4 (the first block of sector 1) since sector 0
      // contains the manufacturer data and it's probably better just
      // to leave it alone unless you know what you're doing
      success = nfc.mifareclassic_AuthenticateBlock(uid, uidLength, 4, 0, keya);

      if (success)
      {
        Serial.println("Sector 1 (Blocks 4..7) has been authenticated");
        uint8_t data[16];

        // If you want to write something to block 4 to test with, uncomment
        // the following line and this text should be read back in a minute
        //memcpy(data, (const uint8_t[]){ 'a', 'd', 'a', 'f', 'r', 'u', 'i', 't', '.', 'c', 'o', 'm', 0, 0, 0, 0 }, sizeof data);
        // success = nfc.mifareclassic_WriteDataBlock (4, data);

        // Try to read the contents of block 4
        success = nfc.mifareclassic_ReadDataBlock(4, data);

        if (success)
        {
          // Data seems to have been read ... spit it out
          Serial.println("Reading Block 4:");
          nfc.PrintHexChar(data, 16);
          Serial.println("");

          // Wait a bit before reading the card again
          delay(1000);
        }
        else
        {
          Serial.println("Ooops ... unable to read the requested block.  Try another key?");
        }
      }
      else
      {
        Serial.println("Ooops ... authentication failed: Try another key?");
      }
    }

    if (uidLength == 7)
    {
      // We probably have a Mifare Ultralight card ...
      Serial.println("Seems to be a Mifare Ultralight tag (7 byte UID)");

      // Try to read the first general-purpose user page (#4)
      Serial.println("Reading page 4");
      uint8_t data[32];
      success = nfc.mifareultralight_ReadPage (4, data);
      if (success)
      {
        // Data seems to have been read ... spit it out
        nfc.PrintHexChar(data, 4);
        Serial.println("");

        // Wait a bit before reading the card again
        delay(1000);
      }
      else
      {
        Serial.println("Ooops ... unable to read the requested page!?");
      }
    }
  }
}

use hardware SPI for NFC reader

I believe that i am using SPI communication with the NFC reader, but what do you mean by using hardware SPI, cause i've connected the reader using the defined pins for SPI connection

All the information is actually available in the comments of your sample code, Adafruit_PN532 nfc(PN532_SCK, PN532_MISO, PN532_MOSI, PN532_SS); is for software SPI. Hardware SPI is available at SCK = 13, MOSI = 11, MISO = 12 and all you need to do is to instantiate it with Adafruit_PN532 nfc(SS); to specify the SS pin you want to use. Also, when you use SPI, you don't need #include <Wire.h>, and #define PN532_IRQ 2 in your code.


text:
Storing IR Sensor value not working
This is my first time working on Arduino for my project and I ran into an issue. I'm trying to make a very simple Vending Machine. Coin or any obstacle passes in front of the IR sensor and based on that, the user can either press button 1 or 2 and based on that motor 1 or 2 would run respectively.
The overall logic works exactly how I want it to, the issue I'm facing is that the variable (sensorStatus) storing the IR sensor value isn't working correctly. Whether anything passes in front of it or not, it lets me press the buttons anyways and the motor starts working.
void loop() {

  int sensorStatus;

  //this is where im having the issue
  if (digitalRead(inSensor) == LOW) sensorStatus = LOW;

  if(sensorStatus == LOW) {
      buttonStatus1 = digitalRead(inButton1);

      if(buttonStatus1 == HIGH) {
        digitalWrite(relayControl1_1, LOW);
      } else {
        digitalWrite(relayControl1_1, HIGH);
      }

      buttonStatus2 = digitalRead(inButton2);

      if(buttonStatus2 == HIGH) {
        digitalWrite(relayControl2_1, LOW);
      } else {
        digitalWrite(relayControl2_1, HIGH);
      }

      sensorStatus = HIGH;
   }
}

If I don't use this logic and store the value of the sensor directly into the variable (sensorStatus), the whole program seems to be working till I have an obstacle in front of the sensor continuously. I don't want this to happen, I want it to work in such a way that once an obstacle passes in front of the sensor it keeps the value (even after the obstacle is gone) until a button is pressed and after that, it gets rid of the value to repeat the process once again. It seems to be a code logic issue but I can't seem to figure out the logic behind it.
My Complete Source Code:
const int relayControl1_1 = 13; // relay 1 of 1 (input 1)
const int relayControl1_2 = 12; // relay 1 of 2 (input 2)
const int relayControl2_1 = 11; // relay 2 of 1 (input 3)
const int relayControl2_2 = 10; // relay 2 of 2 (input 4)

const int inButton1 = 9; //input button 1
const int inButton2 = 8; //input button 2

int buttonStatus1 = 0;
int buttonStatus2 = 0;

const int inSensor = 7;

void setup() {
  Serial.begin(9600);
  pinMode(relayControl1_1, OUTPUT);
  pinMode(relayControl1_2, OUTPUT);
  pinMode(relayControl2_1, OUTPUT);
  pinMode(relayControl2_2, OUTPUT);

  pinMode(inButton1, INPUT_PULLUP);
  pinMode(inButton2, INPUT_PULLUP);

  pinMode(inSensor, INPUT_PULLUP);

}

void loop() {

  int sensorStatus;

  //this is where im having the issue
  if (digitalRead(inSensor) == LOW) sensorStatus = LOW;

  if(sensorStatus == LOW) {
      buttonStatus1 = digitalRead(inButton1);

      if(buttonStatus1 == HIGH) {
        digitalWrite(relayControl1_1, LOW);
      } else {
        digitalWrite(relayControl1_1, HIGH);
      }

      buttonStatus2 = digitalRead(inButton2);

      if(buttonStatus2 == HIGH) {
        digitalWrite(relayControl2_1, LOW);
      } else {
        digitalWrite(relayControl2_1, HIGH);
      }

      sensorStatus = HIGH;
   }
}

Make sensorStatus static and give it a default value?

It does seem to stop it from taking garbage value and making it not work without input from sensor by setting it as static int sensorStatus = HIGH; but it stops it from how I want it to work. I want it to be able to store the value until I press the buttons for the motor even if the obstacle from the sensor is gone. Setting it as static ends up making it only work as long as I have an obstacle in front of the sensor, once the obstacle is gone it seems to lose the value.

So change the sensorStatus back to HIGH only when a button is pressed?

I set sensorStatus to HIGH right after the digitalWrite(relayControl1_1, HIGH); in the else part of the buttonStatus conditional statements. It seems to work this way but the motor keeps on working until I interrupt it by putting an obstacle in front of the IR sensor. I fixed it by adding delay(2000); digitalWrite(relayControl1_1, LOW); after it and it works exactly how I want. Thanks a lot for the help, kind stranger.

@Majenko can you post your comment as an answer so the OP can accept it? As it is now, I had to read the question and 4 comments to figure out that the problem has already been solved.

I posted the answer but I can only accept it as the answer after 2 days.

Thanks to the help from @Majenko♦ I was able to fix the issue.
1 - int sensorStatus; should have been set to static int sensorStatus = HIGH; to make the program remember the value of the sensor.
2 - sensorStatus = HIGH; should have been right after digitalWrite(relayControl1_1, HIGH); in the buttonStatus conditional else part to make the program set the sensorStatus back to HIGH correctly.
3 - Unrelated to the question posted, doing the above steps made the program run the motors continuously unless they were stopped by an obstacle from the IR sensor. This was fixed by adding delay(2000); digitalWrite(relayControl1_1, LOW); after the sensorStatus = HIGH; mentioned in the 2nd step.
Source Code after fixing:
const int relayControl1_2 = 12; // relay 1 of 2 (input 2)
const int relayControl2_1 = 11; // relay 2 of 1 (input 3)
const int relayControl2_2 = 10; // relay 2 of 2 (input 4)

const int inButton1 = 9; //input button 1
const int inButton2 = 8; //input button 2

int buttonStatus1 = 0;
int buttonStatus2 = 0;

const int inSensor = 7;

void setup() {
  Serial.begin(9600);
  pinMode(relayControl1_1, OUTPUT);
  pinMode(relayControl1_2, OUTPUT);
  pinMode(relayControl2_1, OUTPUT);
  pinMode(relayControl2_2, OUTPUT);

  pinMode(inButton1, INPUT_PULLUP);
  pinMode(inButton2, INPUT_PULLUP);

  pinMode(inSensor, INPUT_PULLUP);

}

void loop() {

  static int sensorStatus = HIGH;

  if (digitalRead(inSensor) == LOW) {
    sensorStatus = LOW;
  }

  if(sensorStatus == LOW) {
      buttonStatus1 = digitalRead(inButton1);

      if(buttonStatus1 == HIGH) {
        digitalWrite(relayControl1_1, LOW);
      } else {
        digitalWrite(relayControl1_1, HIGH);
        sensorStatus = HIGH;
        delay(2000);
        digitalWrite(relayControl1_1, LOW);
      }

      buttonStatus2 = digitalRead(inButton2);

      if(buttonStatus2 == HIGH) {
        digitalWrite(relayControl2_1, LOW);
      } else {
        digitalWrite(relayControl2_1, HIGH);
        sensorStatus = HIGH;
        delay(2000);
        digitalWrite(relayControl2_1, LOW);
      }
   }
}

couple of observations ... it appears that your code does not work as described ... you said obstacle passes in front of the IR sensor ... your code never checks for obstacle passing sensor, it only checks for obstacle blocking sensor ....... the program line digitalWrite(relayControl1_1, LOW); gets called regardless of the state of buttonStatus1 ... put digitalWrite(relayControl1_1, LOW); after the if block .... same kind of thing in the other if block

the code would be clearer if sensorStatus was boolean named coin or paid

source: Stack Exchange

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

sort: votes


text:
Char buffer for serial input: char str[2] vs char* str = (char*) malloc(2)
I am using software serials on my Arduino nano to read data from my esp01 in functionality testing for the software serial. I simply make the esp01 to send a string "OK" to an Arduino's software rx serial port (in this case pin 9) , and then the Arduino prints it on the monitor via its hardware serial (USB).
I've found that when I allocate space for the string in Arduino using char str[2], the message seems to be correct. However, with char* str = (char*)malloc(2), there appear to be an unkown character tai
ling the string "OK"
Below is the code I use
#include<SoftwareSerial.h>

SoftwareSerial s(9,10);
void setup() {
  pinMode(2,OUTPUT);
  Serial.begin(9600);
  s.begin(9600);      // link to esp01
}

void loop() {

  if(s.available() > 0){
    char txt[2];
    int indx = 0;

   // read input
    while(s.available() > 0 && indx <=SIZE-1){
        char buff;
        buff=  s.read();
        txt[indx] =  buff;
        Serial.println(indx);
        indx++;

    }
   // bink an LED for debugging
   if((String)txt == "OK"){
    digitalWrite(2,HIGH);
    delay(500);
    digitalWrite(2,LOW);
    delay(500);
   }

   //reset index
   if(indx ==2){

     Serial.println(txt);
     Serial.print("Size of string:");
     Serial.println(sizeof(txt));
    indx = 0;
   }
  } // if(s.available())

}

here is the print-out of the serial monitor

That tailing square is the myster for me.
Any help would be grateful!!
Boris

To store two characters you need three slots in the array.  You forgot about the null terminator to mark the end of the string.  So depending on where the array is in memory there may or may not be extra junk behind it that gets printed because the string isn’t terminated.

you need 3 positions. 'O 'K' '\0'

Re “while(s.available() > 0 && indx <=SIZE-1)”: where did you define SIZE?

First, a few general notes:

The difference between char str[2] and
char* str = (char*) malloc(2) is irrelevant to you problem. It
changes the place where the array is stored, the meaning of
sizeof str, and malloc() will blow up your RAM if you call it
repeatedly and forget to free().
In your code, sizeof(txt) is the constant 2: the actual size in
bytes of the array txt, irrespective of how much relevant data it
holds.
You want txt and indxto remember their contents across calls to
loop(). You should either make them global or qualify them as
static.
Avoid the String class if at all possible. Here, since you use it
only to compare two strings, you can use the traditional
strcmp() function instead.

Now, the bulk of my answer is just about expanding on what has already
been said about properly terminating strings.
A string is a variable-length list of characters. Whenever you are
dealing with a list that has a variable length, you need to somehow keep
track of this length. There are two common ways to do so:

either you store the length in a variable,
or you put a sentinel value (a value that would be invalid within
the list) after the last element to mark the end of the list.

Both methods are valid, and I am going to illustrate both of them below.
However, in the case of strings, the C++ language uses method 2,
with the ASCII “NUL” character (numeric value 0) as a sentinel.
Method 1:
void loop() {
  static char txt[2];
  static size_t indx = 0;

  while (s.available()) {
    // read input
    char c = s.read();
    txt[indx++] = c;

    // report
    Serial.print("Received: '");
    Serial.print(c);
    Serial.print("', string: \"");
    Serial.write(txt, indx);
    Serial.print("\", size: ");
    Serial.println(indx);
    if (indx == 2 && memcmp(txt, "OK", 2) == 0) {
      Serial.println("Correct message");
    }

    // reset index
    if (indx >= sizeof txt) {
      indx = 0;
    }
  } // if(s.available())
}

Some things to note:

The indx variable holds the length of the string. It also happens to
be the index of the next available cell in the txt array, if any.
The string is printed using the
write(const char *buffer, size_t size) method, which accepts a size
as a second argument. Unlike print(const char *), it doesn't depend
on the string being NUL-terminated.
In order to check that we received “OK”, we have to check for both the
correct length (indx == 2) and correct contents. The contents is
checked using the memcmp() function, which can compare arbitrary
byte arrays and, again, does not depend on NUL-termination.
An important loop invariant here is idx < sizeof txt. It is true at
initialization and is restored by the “reset index” section at the end
of the loop. The “read input” section depends on this invariant to not
overflow the buffer.

Method 2:
void loop() {
  static char txt[3];
  static size_t indx = 0;

  while (s.available()) {
    // read input
    char c = s.read();
    txt[indx++] = c;
    txt[indx] = '\0';

    // report
    Serial.print("Received: '");
    Serial.print(c);
    Serial.print("', string: \"");
    Serial.print(txt);
    Serial.print("\", size: ");
    Serial.println(indx);
    if (strcmp(txt, "OK") == 0) {
      Serial.println("Correct message");
    }

    // reset index
    if (indx >= sizeof txt - 1) {
      indx = 0;
      txt[indx] = '\0';
    }
  } // if(s.available())
}

Again, some notes:

This is actually an hybrid of methods 1 and 2, as the indx variable
is still used to keep track of where to insert the next incoming
character. This just happens to be more convenient and efficient than
putting that character into its own length-1 string and using
strcat().
The array is now one cell longer, to make room for the terminating
NUL.
There is another loop invariant now: correct string termination
(txt[indx] == '\0'). This invariant has to be enforced both on
reading and on resetting.
The string being NUL-terminated, it can now be printed with print()
and compared with strcmp(). The string literal "OK" is guaranteed
to be NUL-terminated by the compiler.

This second method is generally safer because there are a lot of
functions and methods in Arduino and C++ that expect strings to be
NUL-terminated. If your strings are not, you have to be extra careful to
not use any of these string-oriented functions.

As others have pointed out, C strings are null-terminated. So to hold 2 characters of content you need a 3-byte array. Your code that reads the chacters into the buffer also needs to be changed. (That code isn't adding the required terminating null.)
You should probably rewrite your code to use the strncat() function.

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


text:
ESP8266 constantly crashes in malloc-related "check_poison_neighbors(unsigned short)" when networking happens
My project involves a bunch of peripherals, but most importantly for this project, a request to an NTP time server is done using the standard NTPClient library. Suddenly, after modifying some seemingly unrelated parts of the code involving SdFat, the ESP8266 started crashing each time in the same place, somewhere deep within the networking firmware.
I have now had this problem with multiple variations, but every time, the crashing function was something that the Exception Decoder calls check_poison_neighbors(unsigned short). It appears to be nested in some memory allocating functions (guessing by the malloc names).
Below is the entire output of ESP Exception Decoder from one of the crashes.
Exception 3: LoadStoreError: Processor internal physical address or data error during load or store
PC: 0x40100fb5: check_poison_neighbors(unsigned short) at C:\Users\USERNAME\Documents\ArduinoData\packages\esp8266\hardware\esp8266\2.7.1\cores\esp8266\umm_malloc/umm_local.c line 52
EXCVADDR: 0x40010059

Decoding stack results
0x4010109d: umm_malloc_core(size_t) at C:\Users\USERNAME\Documents\ArduinoData\packages\esp8266\hardware\esp8266\2.7.1\cores\esp8266\umm_malloc\umm_malloc.cpp line 422
0x4022cae4: mem_malloc at core/mem.c line 210
0x4010131c: umm_malloc(size_t) at C:\Users\USERNAME\Documents\ArduinoData\packages\esp8266\hardware\esp8266\2.7.1\cores\esp8266\umm_malloc\umm_malloc.cpp line 511
0x4010017c: ets_post(uint8, ETSSignal, ETSParam) at C:\Users\USERNAME\Documents\ArduinoData\packages\esp8266\hardware\esp8266\2.7.1\cores\esp8266\core_esp8266_main.cpp line 177
0x4010134b: umm_poison_malloc(size_t) at C:\Users\USERNAME\Documents\ArduinoData\packages\esp8266\hardware\esp8266\2.7.1\cores\esp8266\umm_malloc/umm_poison.c line 155
0x4010072e: malloc(size_t) at C:\Users\USERNAME\Documents\ArduinoData\packages\esp8266\hardware\esp8266\2.7.1\cores\esp8266\heap.cpp line 228
0x4022cae4: mem_malloc at core/mem.c line 210
0x40226984: pbuf_alloc_LWIP2 at core/pbuf.c line 284
0x4022443c: dns_send at core/dns.c line 777
0x402245f7: dns_check_entry at core/dns.c line 1096
0x40224b11: dns_gethostbyname_addrtype at core/dns.c line 1502
0x40208a0c: wifi_dns_found_callback(char const*, ip4_addr const*, void*) at C:\Users\USERNAME\Documents\ArduinoData\packages\esp8266\hardware\esp8266\2.7.1\libraries\ESP8266WiFi\src\ESP8266WiFiGeneric.cpp line 707
0x40224b68: dns_gethostbyname at core/dns.c line 1530
0x40208b80: ESP8266WiFiGenericClass::hostByName(char const*, IPAddress&, unsigned int) at C:\Users\USERNAME\Documents\ArduinoData\packages\esp8266\hardware\esp8266\2.7.1\libraries\ESP8266WiFi\src\ESP8266WiFiGeneric.cpp line 623
0x4020e554: operator new(unsigned int) at C:\Users\USERNAME\Documents\ArduinoData\packages\esp8266\hardware\esp8266\2.7.1\cores\esp8266\abi.cpp line 39
0x40209b3f: WiFiUDP::begin(unsigned short) at C:\Users\USERNAME\Documents\ArduinoData\packages\esp8266\hardware\esp8266\2.7.1\libraries\ESP8266WiFi\src\WiFiUdp.cpp line 83
0x4010072e: malloc(size_t) at C:\Users\USERNAME\Documents\ArduinoData\packages\esp8266\hardware\esp8266\2.7.1\cores\esp8266\heap.cpp line 228
0x4022cae4: mem_malloc at core/mem.c line 210
0x4020e554: operator new(unsigned int) at C:\Users\USERNAME\Documents\ArduinoData\packages\esp8266\hardware\esp8266\2.7.1\cores\esp8266\abi.cpp line 39
0x40209b3f: WiFiUDP::begin(unsigned short) at C:\Users\USERNAME\Documents\ArduinoData\packages\esp8266\hardware\esp8266\2.7.1\libraries\ESP8266WiFi\src\WiFiUdp.cpp line 83
0x40208c00: ESP8266WiFiGenericClass::hostByName(char const*, IPAddress&) at C:\Users\USERNAME\Documents\ArduinoData\packages\esp8266\hardware\esp8266\2.7.1\libraries\ESP8266WiFi\src\ESP8266WiFiGeneric.cpp line 605
0x402095bc: WiFiUDP::beginPacket(char const*, unsigned short) at C:\Users\USERNAME\Documents\ArduinoData\packages\esp8266\hardware\esp8266\2.7.1\libraries\ESP8266WiFi\src\WiFiUdp.cpp line 140
0x40209b3f: WiFiUDP::begin(unsigned short) at C:\Users\USERNAME\Documents\ArduinoData\packages\esp8266\hardware\esp8266\2.7.1\libraries\ESP8266WiFi\src\WiFiUdp.cpp line 83
0x40209db1: NTPClient::sendNTPPacket() at C:\Users\USERNAME\Documents\_H\Arduino\libraries\NTPClient\NTPClient.cpp line 174
0x40209df1: NTPClient::forceUpdate() at C:\Users\USERNAME\Documents\_H\Arduino\libraries\NTPClient\NTPClient.cpp line 76
0x40209e93: NTPClient::update() at C:\Users\USERNAME\Documents\_H\Arduino\libraries\NTPClient\NTPClient.cpp line 99
0x40205317: setup() at PROJECT_MAIN_FILE.ino line 173
0x4020e7e4: loop_wrapper() at C:\Users\USERNAME\Documents\ArduinoData\packages\esp8266\hardware\esp8266\2.7.1\cores\esp8266\core_esp8266_main.cpp line 194

Lines 170-173 in my main project file read:
// start ntp client
timeClient.begin();
timeClient.update();
yield();

The code before that ensures that a WLAN (WiFi) connection has been established, which I also confirmed from the ESP internal debug output to the serial port.
This is one of the lifecycle serial logs:
SDK:2.2.2-dev(38a443e)/Core:2.7.1=20701000/lwIP:STABLE-2_1_2_RELEASE/glue:1.2-30-g92add50/BearSSL:5c771be
# SD ok.
scandone
state: 0 -> 2 (b0)
state: 2 -> 3 (0)
state: 3 -> 5 (10)
add 0
aid 2
cnt

connected with ACCESS_POINT_NAME, channel 11
dhcp client start...
wifi evt: 0
ip:192.168.178.76,mask:255.255.255.0,gw:192.168.178.1
wifi evt: 3
# Display ok.
# Waiting on WLAN
# WLAN connected.
[hostByName] request IP for: europe.pool.ntp.org
[hostByName] Host: europe.pool.ntp.org IP: 212.92.16.193
:urn 48
:urd 48, 48, 0
# Checking status...

 ets Jan  8 2013,rst cause:4, boot mode:(3,6)

wdt reset
load 0x4010f000, len 3456, room 16
tail 0
chksum 0x84
csum 0x84
va5432625
~ld

The lines starting with "#" are my own logging output which confirms external hardware and WLAN connectivity. Note the [hostByName] lines, which are triggered by the NTP client's DNS lookup. Somewhat randomly, on some resets they will not show up and I will get the above exception and stack trace, and other times, like shown in this serial log, they do show up and the ESP8266 resets without causing an explicit exception and stack trace log. Weird.
I have checked multiple solutions and reflashed the firmware etc. Flash is 415660 Bytes (39%) and global variables 32848 Bytes (40%). Any help would be appreciated.

cause 4 is watchdog reset

If you're corrupting memory, the crash will most likely not happen where you cause the problem, it will happen in other code that's working with the damaged area of memory. If you can cut your program down to at the smallest program that still demonstrates the problem, someone may be able to point out the issue to you.  You might even find it yourself.

Thanks. I have found a wrong allocation inside some other code, fixing that leads to new poison errors I may be able to track futher.


text:
ESP8266 malloc/calloc-related crashes ("segfaults")
This is sort of the continuation of this problem. After getting hints that the problem I had were related to bad memory, I checked all of my heap-allocating code again and found a malloc that didn't allocate enough memory for an array. After fixing that and fiddling around with calloc, which may be safer for array-related stuff, I think I exposed the actual programming errors themselves. The crash message I get now is:
No poison after block at: 0x3fff0fb8, actual data: 0x84 0xf 0xff 0x3f

User exception (panic/abort/assert)
Panic umm_malloc.cpp:422 umm_malloc_core

which sounds to me like some sort of ESP segfault. The code where this happens according to the stack trace is the following:
Menu* createMenuStructure(ace_time::TimeZone* mainTZ) {
  // create an array of all clock faces, i.e. a pointer to an array of function pointers
  void (**allClockFaces)(T_DISPLAY*, ace_time::ZonedDateTime*);
  // funkiest malloc in the world; undefined behavior? I hope not.
  allClockFaces = (void (**)(T_DISPLAY*, ace_time::ZonedDateTime*)) calloc(DESIGN_MENU_SIZE, sizeof(*allClockFaces));
  // initialize array
  allClockFaces[0] = &basicDigitalCF;
  allClockFaces[1] = &digitalWithSecondsCF;
  allClockFaces[2] = &basicAnalogCF;
  allClockFaces[3] = &binaryCF;
  allClockFaces[4] = &fullDayBinaryCF;
  ClockFaceSelectMenu* cfMenu = (ClockFaceSelectMenu*) malloc(sizeof(ClockFaceSelectMenu));
  cfMenu = new ClockFaceSelectMenu((char**)design_menu, (size_t)DESIGN_MENU_SIZE, allClockFaces);

  // time zone select menu
  TimeZoneSelectMenu* tzMenu = (TimeZoneSelectMenu*) malloc(sizeof(TimeZoneSelectMenu));
  tzMenu = new TimeZoneSelectMenu();

  Menu** allMenus = (Menu**) calloc(3, sizeof(*allMenus));
  // initialize first layer of sub menus
  allMenus[0] = cfMenu;
  allMenus[3] = tzMenu;

  OptionsMenu* mainMenu = (OptionsMenu*) malloc(sizeof(OptionsMenu));
  mainMenu = new OptionsMenu((char**)main_menu, (size_t)MAIN_MENU_SIZE, allMenus);

  // for now, manually set the sub menu's parent to the main menu. When all menus are finished, the main menu will do this automatically
  allMenus[0]->parent = mainMenu;
  allMenus[3]->parent = mainMenu;

  ClockMenu* clk = (ClockMenu*) malloc(sizeof(ClockMenu));
  // timeClient is a global NTPClient variable
  clk = new ClockMenu(&timeClient, mainTZ, (Menu*)mainMenu);

  return clk;
}

All names containing Menu are classes derived from that base class, and the top couple of lines allocate an array of function pointers. And just to be clear: This code was working perfectly fine for the last several days of development until I made some changes to the SD card functionality that caused the constant crashes.
I am not very used to working in manual memory management. Is this way of allocating appropriate, and if so, correct? What am I doing wrong, or does the error lie somewhere else in the (~1500sloc) project?
Edit: Although the issue is already solved, thanks to the approved answer, I wanted to clarify that the constants used in the array allocation are all correct and correspond to the string array's length. E.g. main_menu is a string array of length 5 and MAIN_MENU_SIZE is a constant defined right next to the array definition that is also defined to 5. This is of course necessary as C arrays have no way (that I know of) of finding the length of complex pointer arrays such as these.

Where are the matching calls to free?

Not sure if it's related to your problem, but you should never use malloc in C++. It allocates memory without actually creating an object, which results in undefined behavior, which could very well crash your program. You should always be using smart pointers (std::unique_ptr, std::shared_pointer, std::make_unique, std::make_shared) to manage dynamically allocated memory. In the rare case where you do need raw allocations, you can use new/delete, but never malloc/free.

You wrote:

// funkiest malloc in the world

Funky, indeed. ;-) I kind of like its twisted beauty, but not everyone
does. Some may urge you to typedef that function type.

allClockFaces[4] = &fullDayBinaryCF;

Are you sure DESIGN_MENU_SIZE is strictly larger than 4? Maybe an
assert() would be good to use here.

ClockFaceSelectMenu* cfMenu = (ClockFaceSelectMenu*) malloc(...);
cfMenu = new ClockFaceSelectMenu(...);

You are assigning a value to cfMenu twice in a row, which means the
value assigned first is lost. This is a memory leak. You do not need
malloc() here, as new takes care of the memory allocation prior to
initializing the object. This error is repeated several times in this
function.

allMenus[3] = tzMenu;

allMenus has length 3: valid indices range from 0 to 2. This is an
out-of-bounds array access, and the likely cause of the errors you see.

OK, the behavior of new wasn't exactly clear to me, especially because Arduino isn't exactly standard C++. Thank you for clearing everything up for me and hinting me towards typedef.

Re “Arduino isn't exactly standard C++”: It's slightly preprocessed C++. Arduino.h is implicitly included, function prototypes are added for you, and then your code is handed to a regular C++ compiler (namely avr-gcc).

But which C++ standard? I found that some C++ functionality I researched online would not be accepted by avr-gcc, or needed to be modified. I knew about the implicit function prototypes, which I avoid anyways and just put void setup(); void loop(); in the beginning of my main files.

It's C++11 (platform.txt puts “-std=gnu++11” in compiler.cpp.flags) with no exceptions, RTTI or STL. The things that are supported (like new) generally work as expected.


text:
Arduino/Genuino 101 - EOL / Junk the board(s)?
https://hackaday.com/2017/07/25/the-end-of-arduino-101-intel-leaves-maker-market/
https://downloadcenter.intel.com/download/25832/Arduino-101-Firmware-Package-1-0
https://community.intel.com/t5/Intel-Makers/Intel-Curie-End-of-Life-Scheduled/td-p/397068?profile.language=en
Intel EOL'd the Arduino/Genuino 101 board.  The end is so complete that you cannot download the drivers using the Board Manager.
To make matters worse, my old Ubuntu machine, with an old Arduino IDE, is unable to upload to my existing 101 boards (PRESS MASTER RESET error).

Should I junk these boards?
Is there a 3rd party site that is hosting the drivers?

Arduino's brief partnership with Intel was an abortion that should never have happened. Junk the boards and use something sensible.

Ugh... hate throwing electronics in the trash almost as much as I hate wasting my time on a dead end.

You could always put it on eBay for some other sucker to be disappointed with...

Maybe one day it'll be a collectors' item and be worth millions ;)

This raises the obvious question:  How does one determine which Arduino flavor will be supported in the future?  I don't need things to last forever, but this is one of the few pieces of electronics I need to throw into the junk heap.

You can pretty much guarantee that the AVR based ones will last for the foreseeable future. ARM ones will probably change rapidly. Anything form third parties, like Intel, or any of the million-and-one ARM boards there are now, well, it's anyone's guess. The manufacturer will always support the chip for as long as they are making it. Whether you have the tools to work with that chip without the Arduino framework though is down to your abilities. You can probably still use the 101 just not with Ardiuno, and using a proper programmer (JTAG?)

I've heard of JTAG, but never used it.  I thought JTAG was a hardware (almost cable) standard.  What is the IDE?

I'm getting the picture from:  https://learn.sparkfun.com/tutorials/arm-programming/all and https://www.instructables.com/id/JTAG-ICE-With-Arduino-IDE/ .  However, doesn't Atmel Studio need to know something about the Intel 101 to compile for it?


text:
ESP8266 NodeMCU 3v3 current for fingerprint sensor
From what i see that 3.3Vpin provide 3.3V and 400mA. The fingerprint module i use is AS608. Connecting the fingerprint module power pin to 3.3V of the nodemcu. From the datasheet it only can handle 3.3VDC, operating current<60mA and peak current at <70mA. Do i need to add a resistor to take the current away. Since last time i use another fingerprint module which is R307 connecting to Vin of the nodemcu and now it not working anymore?

400mA is the maximum the regulator can provide. It's not what the regulator does provide. You may have a car with a 1.4l engine. That doesn't mean the fuel tank is only 1.4l as well. The engine only takes what it needs from the fuel tank.

uhmm so it mean if i directly plug the fingeprint power pin to 3.3v it will just draw the current it need and wont burn?

Correct. The 400mA basically means that "the sum of all the peak current requirements of all devices connected to 3.3V must not exceed 400mA".

Be careful using Vin on the NodeMCU for 3.3V devices! If you are powering it by 5V USB power, this Vin pin will probably have something like 4.76V on that pin. The circuit diagram shows that Vusb is connected to Vin with just a schottky diode, which drops the current about .34 volts and provides some noise isolation from the Vusb supply. If you connected a 3.3V device to this pin at 4.76V, you may have damaged your component.
You'd have to check the datasheet or documentation for the fingerprint module, but it sounds like the fingerprint module will only draw 60-70mA when it's given 3.3 volts. Datasheets often provide application examples and may specify that you do need additional resistors, capacitors, etc. The refrain in cases like this is always read the datasheet.
If your NodeMCU datasheet says it can provide 400mA then it should certainly be able to provide the 60-70mA that the fingerprint sensor needs. I've powered an ESP8266 by connecting its Vin pin to the Vin of another NodeMCU and they seem fairly happy together, although there tends to be quite a bit of noise on the Vin pin.

The question clearly mentioned the its 3.3v being connected, this answer is is not wrong, but is unsuitable

Dont want to be bad, but Vin is not a 3V3 output pin. as such the schotky is there just to protect the USB not to drop the voltage.The 3.3 output pis is often marked as 3V

You should not use Vin for taking power out

Dont mix your pins. and use 3V pin (NOT Vin), that should be able to output it.
AMS1117 used in most nodeMCU's I have seen can reasonably provide 800mA medium lenght periods with voltage drop of 8-9 Volts.
The MCU can reasonably take 100mA-350mA. This varies based on the amount of the work it does, running core frequency (I am not advanced enough to mess with that yet), Whether its communicating over wifi and how strong does it have to make the signal (influenced by distence, other wifi devices around). This leaves you with about 450mA to play about. As designers were responsible a good designers 50mA was cut as a margin.
Because of how voltage regulators work, the more voltage you are droping the lover current you can sustain. (worth researching heat decipation) Next is the matter of wether the device is enclosed etc.
So 60mA is OK for most nodeMCU as extra load.
If you reach few hundred mA and are really concerned you can reasonably control consumption simply by controling whether the nodeMCU is sending any majour communication over or if it does encryption (demanding tasks) etc.


text:
ds3231 rtc module weekly alarm
I have a ds3231 and Arduino UNO and I need to get an interrupt from ds3231 once a week for example every Fridays. I've searched a lot in the internet and forums but did not find any library or code that have weekly alarm or some of them that had, they didn't work well.
I also read the data sheet of ds3231 but didn't understand how to set the registers of it.
can anyone help?

check the DS3231 libraries in IDE in "Manage Libraries"

I never really like using the "alarm" function of the DS3231. I'd just check the data and time every loop (, or every few seconds). See if the day-of-week is different from the previous time I check. If so, and the day-of-week is Friday, run the code. This way you can have as many "alarms" as you want instead of using the (I think) two alarms in the DS3231.

Are you using the /INT/SQW pin of DS3231 to trigger the alarm?

@smajli  Yes Im using that.


text:
esp32 http client response only 200 didn't receive the data after that
i am using esp32 as a client and using following example. So here i am getting header response only that is 200. I am not getting any response after that. here is the example
#include <WiFi.h>
#include <HTTPClient.h>

const char* ssid = "yourNetworkName";
const char* password =  "yourPassword";

void setup() {

  Serial.begin(115200);
  delay(4000);
  WiFi.begin(ssid, password);

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

  Serial.println("Connected to the WiFi network");

}

void loop() {

  if ((WiFi.status() == WL_CONNECTED)) { //Check the current connection status

    HTTPClient http;

    http.begin("http://jsonplaceholder.typicode.com/comments?id=10"); //Specify the URL
    int httpCode = http.GET();                                        //Make the request

    if (httpCode > 0) { //Check for the returning code

        String payload = http.getString();
        Serial.println(httpCode);
        Serial.println(payload);
      }

    else {
      Serial.println("Error on HTTP request");
    }

    http.end(); //Free the resources
  }

  delay(10000);

}

given url works with me as well. but if i give other url then i am getting response as 200 only. but not receiving json data which is present on the request url.

Your code works without any problem. What do you means "but if i give other url"? BTW, if you are using esp32, don't tag esp8266.

A 200 response doesn't guarantee that your payload will actually contain any data. It depends on the server. The server might determine to respond with a 200 code but still not return any JSON code for your request.
I am not at all sure, but the server may be rejecting your request because it doesn't like your user agent. I have seen my own ESP8266 supply ESP8266HTTPClient as its user agent for HTTP requests. You can see from the source code of the HttpClient class that this is the default:
HTTPClient::HTTPClient()
    : _client(nullptr), _userAgent(F("ESP8266HTTPClient"))
{
// etc...
}

You might consider setting the user agent for your http client object:
http.setUserAgent("Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:78.0) Gecko/20100101 Firefox/78.0");

If you'd like to investigate a bit more, you might use curl from the command line (this works on linux) to emulate the http request being formulated by your ESP device:
curl -vA "ESP8266HTTPClient" http://jsonplaceholder.typicode.com/comments?id=10

On my linux machine, this returns all the HTTP header information, followed by some JSON for the url you've specified in your code:
[
  {
    "postId": 2,
    "id": 10,
    "name": "eaque et deleniti atque tenetur ut quo ut",
    "email": "REDACTED@EXAMPLE.COM",
    "body": "voluptate iusto quis nobis reprehenderit ipsum amet nulla\nquia quas dolores velit et non\naut quia necessitatibus\nnostrum quaerat nulla et accusamus nisi facilis"
  }
]

Maybe try that with the other url and see what comes out?
You might also modify your post with the Serial output of your sketch to provide more detail.


text:
Arduino Joystick Library not Recognized by Games (Steam)
I have an Arduino Pro Micro running code that uses the Arduino joystick library to act as a gamepad.  I'm just doing testing right now so there's a single button wired up and configured in the code.
Windows recognizes the gamepad just fine and I can read button presses in the properties dialog for that controller.  However the gamepad doesn't work in games that work with a usb gamepad normally (I testing using Rocket League).
I would like to get my Arduino to act just like a normal gamepad (i.e. an xbox controller).
There is lots of discussion on the internet about making custom USB devices (which is what I'm trying to do) but they never seem to get answered very well or at all.  I want to achieve this on the hardware/firmware/driver side rather than having some windows application running on the computer.  If I have to write firmware on the Arduino, buy a USB PID, and/or write a USB driver for the computer, I'll do whatever it takes.

I don't know if Windows needs this, but on Linux I usually need to use the steam controller configuration to map my generic gamepad to an xbox controller emulation mode to get it working.

Hello did you get any solution? The library cited is not commercial. I am also looking for answers.

There is an Arduino Xbox 360 (XInput) library. But I do not use Steam so I have
no idea if this works.
https://github.com/dmadison/ArduinoXInput


text:
Not able to setup Arduino port
I bought my Robotics kit yesterday. And, I am not able to set up my Arduino port.
I have tried every method I could find on the internet. I am attaching images of my device manager and error I am getting while trying to update my ports. Any help would be highly appreciated.

So the error says, that the best drivers are already installed. Can you choose the port COM3 or COM5 in your IDE? Or don't they show up?

@chrisl they don't show up. I am not able to select the option for ports.

add a sreenshot from the Tools menu

@Juraj Yes, added. Do let me know what might be the error.

@Juraj yes, I just did that. Followed https://forum.arduino.cc/index.php?topic=572898.0 for reference. Can you tell me how to proceed?

@Juraj I followed the instructions. Still getting the same error. Moreover, I have an Arduino Uno. So, it doesn't show me Duo Port programming under Ports(COM&LPT).

so your Uno is detected by Windows as Due?

@Juraj I am not quite sure of that. My model is Arduino UNO R3, and it detects the ports as COM3 and COM5.

uninstall the drivers you installed for the com port(s). do you have a link to description of the kit?

@Juraj Yes. https://www.amazon.in/gp/product/B08CBLDNVL/ref=ppx_yo_dt_b_asin_title_o01_s00?ie=UTF8&psc=1


text:
Recommendations For High Capacity Microcontrollers
For a new project I'm working on, I'm turning an old Casio Personal Mini into a Speak & Spell (with possibly other functions). However, the speech library I plan on using is Talkie, and it takes up quite a bit of program space. I've been trying to look around for some microcontrollers I could use that have high program storage capacity, but I really don't know much about what I should look for, nor how to find ones that are compatible with the Arduino boot loader. Would any of you have any good suggestions? I'd probably need one with over 256KB of program storage.

Personally I always recommend the PIC32, but ... it's not the bootloader you want to care about. It's what will work with this "Talkie" library, whatever that is. If it's doing sound reproduction then it's probably going to have very specific non-portable requirements. So the only people that can recommend anything would be the author(s).

In a comment, Juraj wrote:

the ATmega MCUs are similar so a port to Arduino Mega should be
possible

This seems indeed to be very much the case.
Looking at the source code of the library, it appears it uses
timer 2 for generating the PWM signal and timer 1 for
scheduling the samples. These timers are almost identical between the
ATmega328P of the Uno and the ATmega2560 used in the Arduino
Mega 2560. The only relevant difference between these boards, as
far as the library is concerned, is the output pin, which is the “OC2B”
pin of the microcontroller:

on the Uno, OC2B is digital pin 3
on the Mega, OC2B is digital pin 9

So my guess is that the library should work on the Mega with just this
tiny change:
--- a/Talkie/talkie.cpp
+++ b/Talkie/talkie.cpp
@@ -71,7 +71,7 @@ void Talkie::say(uint8_t* addr) {
        //
        // Enable the speech system whenever say() is called.

-       pinMode(3,OUTPUT);
+       pinMode(9,OUTPUT);
        // Timer 2 set up as a 62500Hz PWM.
        //
        // The PWM 'buzz' is well above human hearing range and is

Also, make sure you plug your headphones on pin 9 rather than
pin 3.
If you try this and it works, please report that either here or directly
to the author of the library. It should then be easy to modify the
library to support both boards out of the box.

Edit: If you download Talkie through the Arduino library manager,
you will get this version, which does supports the Arduino
Mega 2560.


text:
Problem with STM32 and SDFat lib on other SPI port
I am using STM32F103C8 and I am triing to compile a code with SDFat library. The problem is I need to use the second channel of the SPI1 (pins PB5,PB4,PB3, PA15):

I found out that is possible to use SDFat lib and include SPIClass inside its constructor. Then I could use this code:
SPIClass SPI_1(PB5,PB4,PB3, PA15);
SdFat sd(&SPI_1);

The problem is this compliation error:
no matching function for call to 'SdFat::SdFat(SPIClass*)'

Do you have any idea how to solve this error or how to work with SD card on different pins?
Here is source code of this library:
https://github.com/greiman/SdFat/blob/master/src/SdFat.h

is IMPLEMENT_SPI_PORT_SELECTION or DOXYGEN defined anywhere?  What is it defined as?

That´s inside SDFat library. I am not sure what does it mean

Well if it is defined as 0 or isn’t defined then that constructor you underlined is not part of the code.  That preprocessor directive decides if that line will be included or not.  You’ll have to look and see if you can find it.

Can you share your schematic? I am trying to do the same but it is always failing to initialize.

Ok, I found out that the sdFat library is not supported on stm32 bluepill (sd card HAL peripherals are not enabled), so I decided to use basic Arduino SD library (it uses SPI commands, not HAL).
Also I have to change pins (from SPI1_1 to SPI1_2) in variant.h and PeripheralPins.c files of bluepill board. - And finally it works (SPI1_2).


text:
I am tying to split a float variable into bytes and then re combine to the original float
Here is the code I am currently using, there have been many and various alternatives I have tried all so far without success, this being the latest incarnation sitting within my main program loop (void loop)...
// get temperature from Dallas Temperature Sensor
  sensors.requestTemperatures();
  sen0_data = sensors.getTempC(sensor_0_address);             // read temperature sensor0

// split float
  float f1 = sen0_data;
  byte* fb = (byte*) &f1;

  Serial.println(f1);
  Serial.println(fb[0]);    // Take a look at the bytes
  Serial.println(fb[1]);
  Serial.println(fb[2]);
  Serial.println(fb[3]);

// rebuild float
  temp = (fb[0] << 24) + (fb[1] << 16) + (fb[2] << 8) + (fb[3]);
  Serial.println(temp);

Now for the result as seen in the serial monitor - original float, split byte 0, byte 1, byte 2, byte 3, and finally rebuilt float. What am I doing wrong? as no doubt can be seen from the dirty coding I am a relative newbe
The starting float value -127.00 is because I currently have no temperature sensor connected to the Arduino, but I would still expect the rebuilt float to be the same and not -318.00. Even if I connect a sensor the rebuilt float does not mirror the original...
-127.00
0
0
254
194
-318.00

I look forward to any advice...
Regards,
Simon.

AVR is little-endian...

I have been told to be careful about a simple casting of non-byte variables to an array of bytes because there's no guarantee that the memory allocated for certain data types will be contiguous. I.e., the bytes might be spread out to non-adjacent spots in memory. For example, I was encouraged to use a union to convert a unit64_t, which is 8 bytes, to a byte array on an ESP8266. This involves declaring a union type:
union u64_bytes {
  uint64_t u64;
  uint8_t u8[sizeof(uint64_t)];
};

And then you can use this to convert either way, for example:
  uint64_t myNum = 1;
  u64_bytes splitNum;
  splitNum.u64 = myNum;
  // now i can loop thru the bytes
  for(int i=0; i<sizeof(uint64_t); i++) {
      uint8_t myByte = splitNum.u8[i];
      Serial.print("byte ");
      Serial.print(i);
      Serial.print(" is ");
      Serial.println(myByte);
  }
  // or just refer to individual bytes
  uint8_t oneByte = splitNum.u8[0];

  // you can also take bytes and convert the other way
  u64_bytes rebuilt;
  for(int i=0; i<sizeof(splitNum); i++) {
      rebuilt.u8[i] = splitNum.u8[i];
  }

  Serial.print("The rebuilt value is ");
  Serial.println(rebuilt.u64);

EDIT: I added some code to show conversion the other way.
That said, it's probably pretty safe in your case to use the bitwise operators you are using. A float is in all likelihood 4 bytes on your hardware, and most hardware allocates memory these days in four-byte blocks.
HOWEVER you still have to take into account the Endianness of the system when it stores values. The basic idea is that if you have four bytes that represent one number, are the most significant bytes first or are the least significant bytes first?
For example, if you are talking about a four byte unsigned integer the number 1, aka 0x00000001, it would be stored like this in Big-Endian hexadecimal:
0x00 0x00 0x00 0x01

But on little endian hardware (like mine) the order is different. They put the least significant bytes first in memory like so:
0x01 0x00 0x00 0x00

This might be very confusing, but the bottom line is you might have to think twice about what the byte order is for your data. I'd add that floats and signed integers might have some aspects that surprise you, and when you try and communicate any information over a serial line (SPI, I2C, etc.) or over a network then you might have to worry about what sort of conversions are happening. You must have to make sure that you know what order your bytes are and you unpack them in a way that's appropriate to the way you packed them.
Lastly, I would encourage you maybe think about (and possibly elaborate) what you are hoping to accomplish by taking apart a float into bytes? If you don't know about the structure of bits inside a float, you would need to get better acquainted with that before you start monkeying with the bytes inside it.
EDIT 2: here's an example where I use a struct to convert a float:
  union float_bytes {
    float flt;
    uint8_t u8[sizeof(float)];
  };

  float myNum = -127.0;
  float_bytes splitNum;
  splitNum.flt = myNum;
  // now i can loop thru the bytes
  for(int i=0; i<sizeof(splitNum); i++) {
      uint8_t myByte = splitNum.u8[i];
      Serial.print("byte ");
      Serial.print(i);
      Serial.print(" is ");
      Serial.println(myByte);
  }
  // or just refer to individual bytes
  uint8_t oneByte = splitNum.u8[0];

  // you can also take bytes and convert the other way
  float_bytes rebuilt;
  for(int i=0; i<sizeof(splitNum); i++) {
      rebuilt.u8[i] = splitNum.u8[i];
  }

  Serial.print("The rebuilt value is ");
  Serial.println(rebuilt.flt);


text:
Can't read PWM signal from 2-pin fan header
I'm trying to get PWM values from a 2-pin fan header on DuetWifi board (it is a 3D Printer Controller Board). Here is some info about the fan connection on that board.
From their forum, I got to know that fan output is open-drain and can operate with frequency up to 65535 Hz (frequency for each fan is configurable).
First of all, I connected Duet FAN- to Arduino D7 and tried that code:
int pin = 7;
unsigned long duration;

void setup() {
  Serial.begin(9600);
  pinMode(pin, INPUT_PULLUP);
}

void loop() {
  duration = pulseIn(pin, HIGH);
  Serial.println(duration);
}

But it shows constant readings between 6-7 in Serial Monitor:
7
6
7
7
7
7
7
6
6
7

Also, any fan speed adjustment in the Duet UI doesn't affect those readings as well.
After that, I have tried a lot of different libraries and codding approaches from Arduino forum to get suitable PWM readings from FAN- pin, but have no luck.

Please show us how you connected the Arduino to the fan.

Your picture shows that you have only connected one line to the Arduino.  You do not have a common ground between the Arduino and the fan controller.  You need to connect the grounds together.
Voltage is like height, it requires two points to measure.  If I point at a hill and I say, "How high is that hill?" that seems like a pretty easy question to answer at first.  But it becomes ambiguous quickly.  Do we want to say how high it is compared to the ground around it?  Or how high from sea level?  Or how high from where we are standing?  You simply can't say how high a hill is unless you agree on where to measure from.
It's the same with voltage.  You can't measure a voltage unless you have a potential that you can consider the 0 point to measure from.  That 0 point is the ground wire.  And as you have drawn the circuit the two boards don't agree on where they will consider 0 volts.

Thank you for such a detailed explanation.


text:
Can I use a MCP23017 to connect multiple RC522 modules?
I want to connect multiple (exactly 64) RFID-RC522 modules to one Nodemcu ESP8266.
I already know, that it is possible to connect multiple RC522's by just using different pins for the SDA pin, while the rest of the RC522 pins can be connected to the same pins on the ESP8266. But not that many, of course.
My research on "how do I get more pins", got me to the MCP23017 port expander.
Further research is not exactly clear, if I can use these pins as ChipSelect/SlaveSelect pins for the RC522.
The two libaries I found for MCP23017 (blemasle/arduino-mcp23017 and Adafruit-MCP23017 seem not to support this, when I use miguelbalboa/rfid (which I have to use, as there seems to be no alternative), because the MCP-Libs do not provide a "Pin Number" for the MFRC522 constructor(?).
So, is this just a "software" thing, or a technical limitation, and what I want is simply not possible? My research was not exactly clear about this, but I'm also very new to electronics and might be researching in the wrong direction.

For a chip select pin you just need a digital HIGH or LOW.  Any digital pin on any expander can do that.  You can connect multiple of those expanders to the same SDA and SCL pins as long as they have different addresses.  I'm not sure how many possible addresses there are for those chips.  If there are at least 8 possibilities then you can get this all from two pins on the Arduino.

You will probably suffer from bus capacitance and fanout issues long before you get to 64 devices regardless of expanders. Think outside the box.

Sure, you can use IO expanders for the chip-select pins of SPI devices. You will have to modify the device libraries to support them, though, because no one is going to do that by default unless it's a very very specific library.
However you will probably not have much luck with your project anyway, since you will more than likely run into problems with fan-out and bus capacitance before you even remotely approach 64 devices on your bus.
You would need to be adding extra bus drivers and partition your bus to reduce and spread the load - at which point it would be simpler and cheaper to just use multiple microcontrollers with just a few RC522s one each.


text:
Is there any way or command to do the double reset of the esp8266 through CODE(sketch)?
I just want to do the double reset of the ESP8266 through code (sketch) .Is there any command or function for this ?is it possible??

Double reset? What's that?

Why would you want to? If the device is already under your control, couldn’t you just run the code you would otherwise run after a double reset (like reconfiguring Wifi)?

you have an esp8266 module wired to Arduino and you want to reset it from the sketch in Arduino?

In node mcu we have one double reset button .when we press that button it will re start the wifi .

yes sir ,how do i go for that???@Juraj

I think we are all confused with the term you are using: "double reset button".  We have no idea what you are talking about as none of us use this term.  If all you want is to restart the WIFI, look at any code that uses the WIFI radio and study how it starts the WIFI radio.  Chances are if you run that code again the WIFI radio will be re-initialized.

Of course then there is this project at github.

@kiran, there is no "double reset button". There is a procedure that involves pressing reset twice, which tells the NodeMCU to enter Wifi reconfiguration mode (or whatever), but only if it's configured to detect a double reset and act on it. If you want to generate a double reset programatically, I presume you could also just run the piece of code that you'd run upon detecting a (manually generated) double reset.

wire a pin of Arduino to reset pin of the esp8266. in setup set the pin as INPUT. if you want to reset the esp8266, set the pin as OUTPUT, then write it LOW, then set it again as INPUT. don't write it HIGH. for double reset repeat the reset.

There are not enough details in the question so we need to guess the goal of the project.  Assuming the goal is to have alternative behaviors depending on pressing the reset button once or twice with in a given span of time.
This project at github likely uses the RTC and some of the RTC flash memory in an ESP8266 to determine if the reset button has been pressed once or twice in a given span of time.
From that project:

PURPOSE: Detects a double reset so that an alternative start-up mode
can be used. One example use is to allow re-configuration of a
device's wifi.

This does not answer the question. The question is about generating a double reset programatically, not detecting it.

I am not sure generating a double reset (what ever this turns out to be) is the end goal.  Let us hear a response from the person (@kiran) posting the question.  I had hoped he would respond to this answer and by doing so would give us enough information to make a better question and answer.

I agree. The question and the underlying reasons for it are far from clear.


text:
Displayng 2 error messages on a 16x02 display
I am trying to display on a 16x02 LCD display 2 error codes. The error message is when one or both thermocouple wires get disconnected and the second error message is when the soldering iron temp goes higher than 432 C. I am using MAX6675 module.
The problem is that when I disconnect one thermocouple wire (the + or the -) sometimes the displayed message is "Overheating !!!" instead of "No tc conn !!!".
Is there any way to display the correct error ?
heaterTemp = thermocouple.readCelsius();
  Input = heaterTemp - 100;
   //No TC connection
  if (isnan(Input)) // No TC Connection
  {
    while (true) {
      digitalWrite(relay_pin, LOW);
      digitalWrite(11, LOW);
      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print("NO TC CONN !!!");
      delay(1000);
    }
  }

  //Soldering Iron overtemperature
  if (Input >= 432)
  {
    while (true) {
      digitalWrite(relay_pin, LOW);
      digitalWrite(11, LOW);
      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print("OVERHEATING !!!");
      delay(1000);
    }
  }

Edit: I finally decided to use the same message for both errors - no TC connection and overheating. I used the code below:
heaterTemp = thermocouple.readCelsius();
  Input = 0.779828 * heaterTemp - 10.3427;
  if (isnan(heaterTemp) or Input >= 432) // No TC Connection OR over-temperature
  {
    while (true) {
      digitalWrite(relay_pin, LOW);
      digitalWrite(11, LOW);
      for (int i=0; i<=1; i++){
      lcd.clear();
      lcd.setCursor(0, i);
      lcd.write((byte)0);
      lcd.setCursor(1, i);
      lcd.write((byte)0);
      lcd.setCursor(5, i);
      lcd.print("ERROR!");
      lcd.setCursor(14, i);
      lcd.write((byte)0);
      lcd.setCursor(15, i);
      lcd.write((byte)0);
      delay(1000);
      }
    }
  }

and
byte thermometer[8] = //icon for termometer
{
  B00100,
  B01010,
  B01010,
  B01110,
  B01110,
  B11111,
  B11111,
  B01110
};

The code displays the thermometer symbol at the beginning and at the end of the row and the text (including the symbols) are moving from one to another row.
Now it is sufficiently to display a error message when the thermocouple gets disconnected or when the iron temperature goes above 432 *C.
I have also left the 2 while(true) loops because I need the program to stay in the loop and display the error message until I turn off the power and start again the soldering station.

What is the type of Input? an int? float? unsigned?

The type of Input is a double

I think before the disconnection is detected, it goes into overheating (maybe just for some milliseconds).
However, because there is a while (true) loop within the overheating part, it will never show the NO TC CONN error.
If you consider the NO TC CONN error to be higher than the OVERHEATING error, than check within the while loop of the OVERHEATING error also for the NO TC CONN error and display NO TC CONN when it is detected.

I'd reserve line #1 for one message, line #2 for the other
  heaterTemp = thermocouple.readCelsius();
  Input = heaterTemp - 100;
  lcd.clear();
  //No TC connection
  if (isnan(Input)) // No TC Connection
  {
    while (true) {
      digitalWrite(relay_pin, LOW);
      digitalWrite(11, LOW);
      // lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print("NO TC CONN !!!");
      delay(1000);
    }
  }

  //Soldering Iron overtemperature
  if (Input >= 432)
  {
    while (true) {
      digitalWrite(relay_pin, LOW);
      digitalWrite(11, LOW);
      // lcd.clear();
      // lcd.setCursor(0, 0);
      lcd.setCursor(1, 0);
      lcd.print("OVERHEATING !!!");
      delay(1000);
    }
  }

According to MAX6675 datasheet page 5, it will set Bit 2 of SPI register to HIGH when the thermocouple is open. Adafruit's MAX6675 library however changed this to return a NAN when Bit 2 is set when you call the readCelsius() method of the library, so what you should do is to check is isnan(heaterTemp) instead of innan(Input).
heaterTemp = thermocouple.readCelsius();
if (isnan(heaterTemp)) // No TC Connection
{
    while (true) {
      digitalWrite(relay_pin, LOW);
      digitalWrite(11, LOW);
      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print("NO TC CONN !!!");
      delay(1000);
    }
}
else
{
  Input = heaterTemp - 100;
  //Soldering Iron over-temperature
  if (Input >= 432)
  {
    while (true) {
      digitalWrite(relay_pin, LOW);
      digitalWrite(11, LOW);
      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print("OVERHEATING !!!");
      delay(1000);
    }
  }
}

You should get rid of the while(true) loops, because when you enter one of them, you'll never get out.
void loop()
{
    heaterTemp = thermocouple.readCelsius();
    Input = heaterTemp - 100;

    //No TC connection
    if (isnan(Input)) // No TC Connection
    {
        digitalWrite(relay_pin, LOW);
        digitalWrite(11, LOW);
        lcd.clear();
        lcd.setCursor(0, 0);
        lcd.print("NO TC CONN !!!");
    }

    //Soldering Iron overtemperature
    if (Input >= 432)
    {
        digitalWrite(relay_pin, LOW);
        digitalWrite(11, LOW);
        lcd.clear();
        lcd.setCursor(0, 0);
        lcd.print("OVERHEATING !!!");
    }

    delay(1000);
}

EDIT: code below is needed to cut of the power

Don't know the purpose of
digitalWrite(relay_pin, LOW);
digitalWrite(11, LOW);

Maybe it's better to move these lines to setup()

The relay_pin is the relay that cuts down the power to the soldering iron's heater, and the pin 11 is the PWM output pin, which controls the power mosfet. Making them "low" will turn off the power mosfet and the relay will cut the power to the iron's heater.

I thought that I need the 2 while(true) loops to stop the loop() until I turn off the power and turn it again on

@mike_mike, you are correct in your thinking


text:
Setup of Arduino Uno as ArduinoISP for programming attiny45
I have an Arduino Uno SMD and an attiny45, which I want to use as a sensor communicating via i2c. For a first step in finding out how to work with the attiny45 I just want to use the attiny as controller for a blinking led.
When first setting up the Arduino as "Arduino as ISP" some questions came up:

I found a lot of different information about wheter or not to use a capacitor between RESET and GND on the Arduino. Also the capacity differs between 0.1uF and 10uF. Unfornately, I found not a single comment on why this capacitor is needed (or not) and which capacities are suitable. All tutorials used electrolytic capacitors (which I only have in 100uF at hand). I have 10nF and 0.1uF at hand but only the film capacitor type. It would be brilliant if some could help me with deciding if I should use a capacitor, which one is suitable and what's the reason for using it.

My second question is about the clock rate I should set in the Arduino IDE. I added the board package from https://github.com/SpenceKonde/ATTinyCore to my Arduino IDE, which offers a large variety of clock rates in the tools dropdown menu. In some tutorials they mentioned that it's crucial to pick the correct clock speed to avoid wrecking the attiny. But, unfortunately, the mentioned clock speeds vary between "1 MHz (internal)" and "8 MHz (internal)". In the attiny45 datasheet (http://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-2586-AVR-8-bit-Microcontroller-ATtiny25-ATtiny45-ATtiny85_Datasheet.pdf) I found the "Calibrated Internal Oscillator" to be the clock set up in freshly shipped chips, which I understand to operate at 8 MHz. But, the datasheet also says, that the CKDIV8 fuse is set on shipment, which leads to a clock prescale value of 8 and to a clock rate of 1 MHz. I'm highly confused... Maybe someone here can help me to find the correct clock rate to set.

I hope I didn't forget any important information. If so, please let me know.
Kind regards and thank you in advance,
Matthias

The capacitor is meant to prevent the programming Arduino from being reset. Normally, when you open the serial connection, the Arduino gets reset and first starts into the bootloader (which would be used to program it). But when using the Arduino as ISP programmer, you don't want to run the bootloader of the programmer. You want to let the programmer sketch work as intended. Thus you want to prevent the programmer from resetting on serial connection. The capacitor between Reset and ground holds the 5V level of the reset pin for the time, that the reset pulse from the USB Serial chip is trying to pull the pin to low. So it prevents the reset from happening.
The value and type of the capacitor is not critical here. I always use a 47uF bipolar electrolyte capacitor, because I have a bunch of them just laying around. The value just shouldn't be unreasonable small or big. The mentioned range of yours is just giving you a hint in which order the value should be. Also you can simply test, if the reset happens with your capacitor. You cannot break things with a wrong value here.

Which clock frequency to use is up to your exact requirements. There is no "this is the best for all occasions"-frequency. Also you are not wrecking the Attiny with any of the clock speeds. Though you should note, that choosing an external clock source means, that you actually need to provide that clock source for the ATTiny to work. The fuses can be reprogrammed, if you have chosen a wrong frequency by accident.
The datasheet states just as you wrote. The interal oscillator is by default set to 8MHz, while the prescaler divides that down to 1MHz as the main CPU clock. So by default the ATTiny runs on 1MHz. You can change that, if you like.
For my Attiny85s I always used internal 8MHz as the setting (the option, that appears in the IDE menu). That is the easiest way (internal means you need no external components for the clock), while being the fastest speed you can get with the internal clock, I think.

Great, that helped me a lot. Thank you very much @chrisl

The reset pulse goes through a 0.1 µF cap, so a 0.1 µF holding cap is really borderline. I would aim for ≥ 0.47 µF, or 0.22 µF as the very minimum.


text:
Program Nano Every using UPDI port
I have and Arduino Nano and an Arduino Nano Every. I'm doing some experiments and trying to program the Nano Every from the Nano, using the UPDI port.
I'm using tutorials like this one that does the same thing but instead of Arduino Nano Every he wants to program an ATtiny.
What I did so far:
1. Transform Arduino Nano into a UPDI programer:
1.1 Clone jtag2updi and open jtag2updi.ino. Connect Arduino Nano through USB to my computer and compile and upload jtag2updi with Arduino IDE just like any other sketch.
1.2 Connect a capacitor of 10uF between RST and GND pins of Arduino Nano
1.3 Install MegaCoreX into Arduino IDE.
2. Program  Arduino Nano Every from a UPDI:
2.1 Connect UPDI pin from Arduino Nano Every to pin D6 of Arduino Nano with a 4.7k resistor. Connect 5V and GND of both boards.
2.2 In Arduino IDE open the Blink example and chose from the Tools menu the following configuration:

2.3 Compile and upload sketch.
Error:
And the problem is that it gives this error:
Arduino: 1.8.12 (Mac OS X), Board: "ATmega4809, Nano Every, Reset, BOD 2.6V, Internal 20 MHz, No bootloader"

/Applications/Arduino.app/Contents/Java/arduino-builder -dump-prefs -logger=machine -hardware /Applications/Arduino.app/Contents/Java/hardware -hardware /Users/miguelwon/Library/Arduino15/packages -tools /Applications/Arduino.app/Contents/Java/tools-builder -tools /Applications/Arduino.app/Contents/Java/hardware/tools/avr -tools /Users/miguelwon/Library/Arduino15/packages -built-in-libraries /Applications/Arduino.app/Contents/Java/libraries -libraries /Users/miguelwon/Documents/Arduino/libraries -fqbn=MegaCoreX:megaavr:4809:pinout=nano_every,resetpin=reset,BOD=2v6,clock=internal_20MHz,bootloader=no_bootloader -vid-pid=1A86_7523 -ide-version=10812 -build-path /var/folders/vp/2f2lk6gj16v00znk4lc6yrkw0000gn/T/arduino_build_818660 -warnings=none -build-cache /var/folders/vp/2f2lk6gj16v00znk4lc6yrkw0000gn/T/arduino_cache_974903 -prefs=build.warn_data_percentage=75 -prefs=runtime.tools.avr-gcc.path=/Users/miguelwon/Library/Arduino15/packages/arduino/tools/avr-gcc/7.3.0-atmel3.6.1-arduino7 -prefs=runtime.tools.avr-gcc-7.3.0-atmel3.6.1-arduino7.path=/Users/miguelwon/Library/Arduino15/packages/arduino/tools/avr-gcc/7.3.0-atmel3.6.1-arduino7 -prefs=runtime.tools.avrdude.path=/Users/miguelwon/Library/Arduino15/packages/arduino/tools/avrdude/6.3.0-arduino17 -prefs=runtime.tools.avrdude-6.3.0-arduino17.path=/Users/miguelwon/Library/Arduino15/packages/arduino/tools/avrdude/6.3.0-arduino17 -prefs=runtime.tools.arduinoOTA.path=/Users/miguelwon/Library/Arduino15/packages/arduino/tools/arduinoOTA/1.3.0 -prefs=runtime.tools.arduinoOTA-1.3.0.path=/Users/miguelwon/Library/Arduino15/packages/arduino/tools/arduinoOTA/1.3.0 -verbose /var/folders/vp/2f2lk6gj16v00znk4lc6yrkw0000gn/T/arduino_modified_sketch_697862/Blink.ino
/Applications/Arduino.app/Contents/Java/arduino-builder -compile -logger=machine -hardware /Applications/Arduino.app/Contents/Java/hardware -hardware /Users/miguelwon/Library/Arduino15/packages -tools /Applications/Arduino.app/Contents/Java/tools-builder -tools /Applications/Arduino.app/Contents/Java/hardware/tools/avr -tools /Users/miguelwon/Library/Arduino15/packages -built-in-libraries /Applications/Arduino.app/Contents/Java/libraries -libraries /Users/miguelwon/Documents/Arduino/libraries -fqbn=MegaCoreX:megaavr:4809:pinout=nano_every,resetpin=reset,BOD=2v6,clock=internal_20MHz,bootloader=no_bootloader -vid-pid=1A86_7523 -ide-version=10812 -build-path /var/folders/vp/2f2lk6gj16v00znk4lc6yrkw0000gn/T/arduino_build_818660 -warnings=none -build-cache /var/folders/vp/2f2lk6gj16v00znk4lc6yrkw0000gn/T/arduino_cache_974903 -prefs=build.warn_data_percentage=75 -prefs=runtime.tools.avr-gcc.path=/Users/miguelwon/Library/Arduino15/packages/arduino/tools/avr-gcc/7.3.0-atmel3.6.1-arduino7 -prefs=runtime.tools.avr-gcc-7.3.0-atmel3.6.1-arduino7.path=/Users/miguelwon/Library/Arduino15/packages/arduino/tools/avr-gcc/7.3.0-atmel3.6.1-arduino7 -prefs=runtime.tools.avrdude.path=/Users/miguelwon/Library/Arduino15/packages/arduino/tools/avrdude/6.3.0-arduino17 -prefs=runtime.tools.avrdude-6.3.0-arduino17.path=/Users/miguelwon/Library/Arduino15/packages/arduino/tools/avrdude/6.3.0-arduino17 -prefs=runtime.tools.arduinoOTA.path=/Users/miguelwon/Library/Arduino15/packages/arduino/tools/arduinoOTA/1.3.0 -prefs=runtime.tools.arduinoOTA-1.3.0.path=/Users/miguelwon/Library/Arduino15/packages/arduino/tools/arduinoOTA/1.3.0 -verbose /var/folders/vp/2f2lk6gj16v00znk4lc6yrkw0000gn/T/arduino_modified_sketch_697862/Blink.ino
Using board '4809' from platform in folder: /Users/miguelwon/Library/Arduino15/packages/MegaCoreX/hardware/megaavr/1.0.4
Using core 'coreX-corefiles' from platform in folder: /Users/miguelwon/Library/Arduino15/packages/MegaCoreX/hardware/megaavr/1.0.4
Detecting libraries used...
/Users/miguelwon/Library/Arduino15/packages/arduino/tools/avr-gcc/7.3.0-atmel3.6.1-arduino7/bin/avr-g++ -c -g -Os -w -std=gnu++11 -fpermissive -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -Wno-error=narrowing -flto -w -x c++ -E -CC -mmcu=atmega4809 -DF_CPU=20000000L -DARDUINO=10812 -DARDUINO_AVR_ATmega4809 -DARDUINO_ARCH_MEGAAVR -I/Users/miguelwon/Library/Arduino15/packages/MegaCoreX/hardware/megaavr/1.0.4/cores/coreX-corefiles/api/deprecated -I/Users/miguelwon/Library/Arduino15/packages/MegaCoreX/hardware/megaavr/1.0.4/cores/coreX-corefiles -I/Users/miguelwon/Library/Arduino15/packages/MegaCoreX/hardware/megaavr/1.0.4/variants/nano-every /var/folders/vp/2f2lk6gj16v00znk4lc6yrkw0000gn/T/arduino_build_818660/sketch/Blink.ino.cpp -o /dev/null
Generating function prototypes...
/Users/miguelwon/Library/Arduino15/packages/arduino/tools/avr-gcc/7.3.0-atmel3.6.1-arduino7/bin/avr-g++ -c -g -Os -w -std=gnu++11 -fpermissive -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -Wno-error=narrowing -flto -w -x c++ -E -CC -mmcu=atmega4809 -DF_CPU=20000000L -DARDUINO=10812 -DARDUINO_AVR_ATmega4809 -DARDUINO_ARCH_MEGAAVR -I/Users/miguelwon/Library/Arduino15/packages/MegaCoreX/hardware/megaavr/1.0.4/cores/coreX-corefiles/api/deprecated -I/Users/miguelwon/Library/Arduino15/packages/MegaCoreX/hardware/megaavr/1.0.4/cores/coreX-corefiles -I/Users/miguelwon/Library/Arduino15/packages/MegaCoreX/hardware/megaavr/1.0.4/variants/nano-every /var/folders/vp/2f2lk6gj16v00znk4lc6yrkw0000gn/T/arduino_build_818660/sketch/Blink.ino.cpp -o /var/folders/vp/2f2lk6gj16v00znk4lc6yrkw0000gn/T/arduino_build_818660/preproc/ctags_target_for_gcc_minus_e.cpp
/Applications/Arduino.app/Contents/Java/tools-builder/ctags/5.8-arduino11/ctags -u --language-force=c++ -f - --c++-kinds=svpf --fields=KSTtzns --line-directives /var/folders/vp/2f2lk6gj16v00znk4lc6yrkw0000gn/T/arduino_build_818660/preproc/ctags_target_for_gcc_minus_e.cpp
Compiling sketch...
/Users/miguelwon/Library/Arduino15/packages/arduino/tools/avr-gcc/7.3.0-atmel3.6.1-arduino7/bin/avr-g++ -c -g -Os -w -std=gnu++11 -fpermissive -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -Wno-error=narrowing -MMD -flto -mmcu=atmega4809 -DF_CPU=20000000L -DARDUINO=10812 -DARDUINO_AVR_ATmega4809 -DARDUINO_ARCH_MEGAAVR -I/Users/miguelwon/Library/Arduino15/packages/MegaCoreX/hardware/megaavr/1.0.4/cores/coreX-corefiles/api/deprecated -I/Users/miguelwon/Library/Arduino15/packages/MegaCoreX/hardware/megaavr/1.0.4/cores/coreX-corefiles -I/Users/miguelwon/Library/Arduino15/packages/MegaCoreX/hardware/megaavr/1.0.4/variants/nano-every /var/folders/vp/2f2lk6gj16v00znk4lc6yrkw0000gn/T/arduino_build_818660/sketch/Blink.ino.cpp -o /var/folders/vp/2f2lk6gj16v00znk4lc6yrkw0000gn/T/arduino_build_818660/sketch/Blink.ino.cpp.o
Compiling libraries...
Compiling core...
Using precompiled core: /var/folders/vp/2f2lk6gj16v00znk4lc6yrkw0000gn/T/arduino_cache_974903/core/core_27f4eba04d8686aefe2683c90c98eae6.a
Linking everything together...
/Users/miguelwon/Library/Arduino15/packages/arduino/tools/avr-gcc/7.3.0-atmel3.6.1-arduino7/bin/avr-gcc -w -Os -g -flto -fuse-linker-plugin -Wl,--gc-sections -Wl,--section-start=.text=0x0 -mmcu=atmega4809 -o /var/folders/vp/2f2lk6gj16v00znk4lc6yrkw0000gn/T/arduino_build_818660/Blink.ino.elf /var/folders/vp/2f2lk6gj16v00znk4lc6yrkw0000gn/T/arduino_build_818660/sketch/Blink.ino.cpp.o /var/folders/vp/2f2lk6gj16v00znk4lc6yrkw0000gn/T/arduino_build_818660/../arduino_cache_974903/core/core_27f4eba04d8686aefe2683c90c98eae6.a -L/var/folders/vp/2f2lk6gj16v00znk4lc6yrkw0000gn/T/arduino_build_818660 -lm
/Users/miguelwon/Library/Arduino15/packages/arduino/tools/avr-gcc/7.3.0-atmel3.6.1-arduino7/bin/avr-objcopy -O ihex -j .eeprom --set-section-flags=.eeprom=alloc,load --no-change-warnings --change-section-lma .eeprom=0 /var/folders/vp/2f2lk6gj16v00znk4lc6yrkw0000gn/T/arduino_build_818660/Blink.ino.elf /var/folders/vp/2f2lk6gj16v00znk4lc6yrkw0000gn/T/arduino_build_818660/Blink.ino.eep
/Users/miguelwon/Library/Arduino15/packages/arduino/tools/avr-gcc/7.3.0-atmel3.6.1-arduino7/bin/avr-objcopy -O ihex -R .eeprom /var/folders/vp/2f2lk6gj16v00znk4lc6yrkw0000gn/T/arduino_build_818660/Blink.ino.elf /var/folders/vp/2f2lk6gj16v00znk4lc6yrkw0000gn/T/arduino_build_818660/Blink.ino.hex
chmod +x /Users/miguelwon/Library/Arduino15/packages/MegaCoreX/hardware/megaavr/1.0.4/scripts/create_disassembler_listing.sh
/Users/miguelwon/Library/Arduino15/packages/MegaCoreX/hardware/megaavr/1.0.4/scripts/create_disassembler_listing.sh /Users/miguelwon/Library/Arduino15/packages/arduino/tools/avr-gcc/7.3.0-atmel3.6.1-arduino7/bin/avr-objdump "--disassemble --source --line-numbers --demangle --section=.text" /var/folders/vp/2f2lk6gj16v00znk4lc6yrkw0000gn/T/arduino_build_818660/Blink.ino.elf /var/folders/vp/2f2lk6gj16v00znk4lc6yrkw0000gn/T/arduino_build_818660/Blink.ino.lst
/Users/miguelwon/Library/Arduino15/packages/arduino/tools/avr-gcc/7.3.0-atmel3.6.1-arduino7/bin/avr-size -A /var/folders/vp/2f2lk6gj16v00znk4lc6yrkw0000gn/T/arduino_build_818660/Blink.ino.elf
Sketch uses 814 bytes (1%) of program storage space. Maximum is 49152 bytes.
Global variables use 4 bytes (0%) of dynamic memory, leaving 6140 bytes for local variables. Maximum is 6144 bytes.
Forcing reset using 1200bps open/close on port /dev/cu.usbserial-1440
/Users/miguelwon/Library/Arduino15/packages/arduino/tools/avrdude/6.3.0-arduino17/bin/avrdude -C/Users/miguelwon/Library/Arduino15/packages/MegaCoreX/hardware/megaavr/1.0.4/avrdude.conf -v -patmega4809 -cjtag2updi -P/dev/cu.usbserial-1440 -e -Uflash:w:/var/folders/vp/2f2lk6gj16v00znk4lc6yrkw0000gn/T/arduino_build_818660/Blink.ino.hex:i -Ufuse0:w:0x00:m -Ufuse1:w:0x54:m -Ufuse2:w:0x02:m -Ufuse4:w:0x00:m -Ufuse5:w:0xC9:m -Ufuse6:w:0x06:m -Ufuse7:w:0x00:m -Ufuse8:w:0x00:m -Ulock:w:0xC5:m

avrdude: Version 6.3-20190619
         Copyright (c) 2000-2005 Brian Dean, http://www.bdmicro.com/
         Copyright (c) 2007-2014 Joerg Wunsch

         System wide configuration file is "/Users/miguelwon/Library/Arduino15/packages/MegaCoreX/hardware/megaavr/1.0.4/avrdude.conf"
         User configuration file is "/Users/miguelwon/.avrduderc"
         User configuration file does not exist or is not a regular file, skipping

         Using Port                    : /dev/cu.usbserial-1440
         Using Programmer              : jtag2updi
JTAG ICE mkII sign-on message:
Communications protocol version: 1
M_MCU:
  boot-loader FW version:        1
  firmware version:              6.00
  hardware version:              1
S_MCU:
  boot-loader FW version:        1
  firmware version:              6.00
  hardware version:              1
Serial number:                   00:00:00:00:00:00
Device ID:                       JTAGICE mkII
         AVR Part                      : ATmega4809
         Chip Erase delay              : 0 us
         PAGEL                         : P00
         BS2                           : P00
         RESET disposition             : dedicated
         RETRY pulse                   : SCK
         serial program mode           : yes
         parallel program mode         : yes
         Timeout                       : 0
         StabDelay                     : 0
         CmdexeDelay                   : 0
         SyncLoops                     : 0
         ByteDelay                     : 0
         PollIndex                     : 0
         PollValue                     : 0x00
         Memory Detail                 :

                                  Block Poll               Page                       Polled
           Memory Type Mode Delay Size  Indx Paged  Size   Size #Pages MinW  MaxW   ReadBack
           ----------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- ---------
           signature      0     0     0    0 no          3    0      0     0     0 0x00 0x00
           prodsig        0     0     0    0 no         61   61      0     0     0 0x00 0x00
           fuses          0     0     0    0 no          9    0      0     0     0 0x00 0x00
           fuse0          0     0     0    0 no          1    0      0     0     0 0x00 0x00
           fuse1          0     0     0    0 no          1    0      0     0     0 0x00 0x00
           fuse2          0     0     0    0 no          1    0      0     0     0 0x00 0x00
           fuse4          0     0     0    0 no          1    0      0     0     0 0x00 0x00
           fuse5          0     0     0    0 no          1    0      0     0     0 0x00 0x00
           fuse6          0     0     0    0 no          1    0      0     0     0 0x00 0x00
           fuse7          0     0     0    0 no          1    0      0     0     0 0x00 0x00
           fuse8          0     0     0    0 no          1    0      0     0     0 0x00 0x00
           lock           0     0     0    0 no          1    0      0     0     0 0x00 0x00
           data           0     0     0    0 no          0    0      0     0     0 0x00 0x00
           usersig        0     0     0    0 no         64   64      0     0     0 0x00 0x00
           flash          0     0     0    0 no      49152  128      0     0     0 0x00 0x00
           eeprom         0     0     0    0 no        256   64      0     0     0 0x00 0x00

         Programmer Type : JTAGMKII_PDI
         Description     : JTAGv2 to UPDI bridge
         M_MCU hardware version: 1
         M_MCU firmware version: 6.00
         S_MCU hardware version: 1
         S_MCU firmware version: 6.00
         Serial number:          00:00:00:00:00:00
         Vtarget         : 5.0 V

avrdude: jtagmkII_set_devdescr(): bad response to set device descriptor command: RSP_NO_TARGET_POWER
avrdude: jtagmkII_initialize(): Cannot locate "flash" and "boot" memories in description
avrdude: AVR device initialized and ready to accept instructions

Reading | avrdude: jtagmkII_program_enable(): bad response to enter progmode command: RSP_NO_TARGET_POWER
avrdude: jtagmkII_program_enable(): bad response to enter progmode command: RSP_NO_TARGET_POWER
avrdude: jtagmkII_read_byte(): bad response to read memory command: RSP_NO_TARGET_POWER
avr_read(): error reading address 0x0000
    read operation not supported for memory "signature"
avrdude: error reading signature data for part "ATmega4809", rc=-2
avrdude: error reading signature data, rc=-2
avrdude: jtagmkII_program_disable(): bad response to leave progmode command: RSP_NO_TARGET_POWER

avrdude done.  Thank you.

the selected serial port
 does not exist or your board is not connected

use "Upload using programmer" in Sketch menu

Thanks but same error.

I'm not sure if you ever solved this issue but for me this error was occurring because the ATmega4809 chip was not powered on. By adjusting the wiring I managed to get rid of the "RSP_NO_TARGET_POWER" error.
So I would suggest double checking wiring and then use the "Upload using programmer" (in "Sketch" tool-bar menu) to upload as suggested by Juraj.


text:
How to specify a timer's name depending on the chip it will be compiled to?
I need to enable a timer interrupt for a chip, and in the mean time, I am testing the code on Arduino Nano rather than (feed the chip, test the chip)++.
So as part of the code I have to TIMSK0 |= (1 << OCIE0A); which works great on the Arduino Nano, but has to be changed to TIMSK (without the 0) for the ATtiny45.
I was planning to go for something along the line of
#define NANO//Put // in front for the AtTiny45
#ifdef NANO
  const char in  = A0;
  const char out = 3;
  const char pwr = 10;
  char *timer = &TIMSK0;
#else
  const char in  = 3;
  const char out = 0;
  const char pwr = 1;
  char *timer = &TIMSK;
#endif
//...
*timer  |= (1 << OCIE0A);

So here are my three questions:

Do #these commands take space on a chip?
Is a pointer the way to go for this kind of things?
Am, am I doing it right?

Just as a complement to Delta_G's answer:

The names TIMSK0, OCIE0A, etc. are already preprocessor macros
so, for consistency, it makes sense to define your own preprocessor
macros for them. I tend to be lazy and use one of the already defined
names, like
#ifdef TIMSK0  // support both ATtiny{25,45,85} and ATmega328P
# define TIMSK TIMSK0
#endif

A const pointer for &TIMSK0 is fine though.

The macros identifying the MCU are defined to the value 1. Thus you
have the choice between these three idioms:
#ifdef __AVR_ATtiny45__
...
#endif

#if defined(__AVR_ATtiny45__)
...
#endif

#if __AVR_ATtiny45__
...
#endif

The third one is convenient when you want to address several MCU
models with the same code:
#if __AVR_ATtiny25__ || __AVR_ATtiny45__ || __AVR_ATtiny85__
...
#endif


text:
DH11 and uno relay controle fridge
I want to control my bar fridge with temp sensor and relay,
This is my first project with code, i copied this:
https://robojax.com/learn/arduino/?vid=robojax-DHT22_11_TM1637_relay
But
I want some extra code that will prevent the fridge (ie relay) from going on too often.
For my purposes I want the relay to close if the temp is above 4c, but only if the relay has been off for say 20min or more.  FYI this is because my power source does not like to start the compressor when it is hot, so i don't want it cycling if it was just on.

Cool question! ;-) Instead of a fixed timer, I would build in some (so-called) hysteresis, which means turning refrigeration on above a certain temperature (say 4 °C) but only turning off when the temperature has dropped again to a temperature well below that (say 3 °C). This ensures the temperature stays within set limits while at the same time preventing fast cycling. You don’t need any timers for this and it will work in any situation (even when it’s very hot or very cold outside of the fridge). This is how commercial thermostats work.
If you really need to ensure the compressor cools enough between cycles, you just need to start a timer when it turns off, and not turn on again before it expires. Look at examples like BlinkWithoutDelay for some coding ideas.

Thanks, I actually found BlinkWithoutDelay about an hour before reading your message.  But i am relay out of my wheel house here, how to i put the 2 together?  BTW I like the Hysteresis idea, but the door opining can cause a 5 degree rise in temp, that takes a few minutes or longer to stabilize again.

You could add a tactile / magnetic (Reed / Hall Effect) switch to detect when the door is open, you could use this as a trigger to tell the software why such a dramatic drop has occurred and to wait x time till temperature settles again. The Hysteresis idea sounds like a good solution as well, you could achieve the same effect by calculating a rolling average over a defined time period and only enable the fridge when this rolling average drops below the trigger temp. This would help smooth out the sensor readings a little.