text:
Using MFRC522 along with other inputs (Bluetooth, keypad)
I'm making a little parking lot, which includes mostly opening a servo motor using either keypad, Bluetooth (hc-05) and freshly added, RFID (RC522).
I can't get inputs from other sources if I want to get the UID from the RFID meaning when I added the only piece of code that I found that returns the UID it seems to block all the void loop() hence all the other inputs/code don't work.
Here's the full code:
#include <LiquidCrystal.h>  //Lcd functions library
#include <Servo.h>          //Servo Motor
#include <SoftwareSerial.h>//Bluetooth functions library:HC05 IS SUPERIOR!
#include "TM1637.h"        //4 digit display functions library
#include <SPI.h>
#include <MFRC522.h>
//Credit to Baroryan

//copyright (c)*/
const int rs = 38, en = 39, d4 = 36 ,d5 = 37, d6 = 41, d7 = 40;//Defining LCD PINS
const int DA=31, D0=30,D1=33,D2=32,D3=35;//Defining KEYPAD data PINS
const int servoPin=43,buzzer=42,rx=53,tx=52;//Defining(By order): servo pin, buzzer pin, 4DD pins, and bluetooth pins(rx tx)
//buzzer pin is 36!
//,CLK=34,DIO=35

#define SS_PIN 45
#define RST_PIN 44
int count = 0;
int cnt=0;//this cnt is used later on to make sure all 5 chars are equal.
int cnt2=0;//used for switch case to count how many chars were already received
int cnt3=0;
char c=0;//this is where we place the char received from the user

char password[5] = {'8', '5', '2', '0', '#'};
char keysPressed[5] = "";
char keys[5]="";

byte customChar2[] = {
  B00000,
  B00000,
  B01010,
  B00000,
  B10001,
  B01110,
  B00000,
  B00000
};

byte customChar[] = {//Custom Char for lcd screen, in this case; a heart.
  0x00,
  0x00,
  0x0A,
  0x1F,
  0x1F,
  0x0E,
  0x04,
  0x00
};
//  #define DA 25 Used to define Keypad pins and other misc using #Define which talks to the processor->
//  #define D0 24  ->decided to use const int instead.
//  #define D1 27
//  #define D2 26
//  #define D3 29
//  #define servoPin 37
//  #define buzzer 36
//  #define CLK 34
//  #define DIO 35
void lcdSetup();
void gateOpenSequence();
void returnKey(int key);
void wrongPassword();
void Beep();
SoftwareSerial Bluetooth(rx,tx);//intialize bluetooth to pins
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);//intialize LCD to pins
MFRC522 mfrc522(SS_PIN, RST_PIN);   // Create MFRC522 instance.
Servo servo;//intialize servo
byte nuidPICC[4];

void printHex(byte *buffer, byte bufferSize) {
  for (byte i = 0; i < bufferSize; i++) {
    Serial.print(buffer[i] < 0x10 ? " 0" : " ");
    Serial.print(buffer[i], HEX);
  }
}

void setup()
{
  Serial.begin(9600);
  Bluetooth.begin(9600);
  SPI.begin();      // Initiate  SPI bus
  pinMode(DA ,INPUT);
  pinMode(D0 ,INPUT);
  pinMode(D1 ,INPUT);
  pinMode(D2,INPUT);
  pinMode(D3,INPUT);
  mfrc522.PCD_Init();   // Initiate MFRC522
  lcd.begin(20,4);
  lcdSetup();//Self Created function that turns lcd to our preffered default screen "Home screen"
  servo.attach(servoPin);
  servo.write(5);
  pinMode(buzzer,OUTPUT);
  digitalWrite(buzzer, HIGH);
  delay(200);
  digitalWrite(buzzer, LOW);
  Bluetooth.print("Enter 1 to open the gate!");//Write to user bluetooth terminal instructions
  lcd.createChar(2, customChar2);
  lcd.createChar(1, customChar);
}

void loop()
{

  if (!mfrc522.PICC_IsNewCardPresent())
  {
    return;
  }
  //Select one of the cards
  if (!mfrc522.PICC_ReadCardSerial())
  {
    return;
  }
  //Show UID on serial monitor
  Serial.print("UID tag :");
  String content= "";
  byte letter;

  for (byte i = 0; i < mfrc522.uid.size; i++)
  {
     Serial.print(mfrc522.uid.uidByte[i] < 0x10 ? " 0" : " ");
     Serial.print(mfrc522.uid.uidByte[i], HEX);
     content.concat(String(mfrc522.uid.uidByte[i] < 0x10 ? " 0" : " "));
     content.concat(String(mfrc522.uid.uidByte[i], HEX));
  }
  Serial.println();
  Serial.print("Message : ");
  content.toUpperCase();
  if (content.substring(1) == "17 27 C7 A6" || "BA FA 21 28") //change here the UID of the card/cards that you want to give access
  {
    Serial.println("Authorized access");
    Serial.println();
    delay(3000);
  }

 else   {
    Serial.println(" Access denied");
    delay(3000);
  }

  char Data=Bluetooth.read();//Recieves Data from bluetooth and places it in variable 'Data'
  if(Data=='1'){//if data from bluetooth equals to 1(1 recieved from bluetooth IS NOT an integer, it is a char.)
    gateOpenSequence();//Self created function that executes all actions when Gate need to be opened.
  }
  while(digitalRead(DA)==1){         //While recieving characters from keypad.
    int key =digitalRead(D3)*8 + digitalRead(D2)*4 +digitalRead(D1)*2 + digitalRead(D0);//Certain formula used to decipher what key has been pressed
    returnKey(key);//Self created function that translates key deciphered to keypad layout. puts key pressed into variable 'c'
    Serial.print(c);
    if(c!='D') keys[cnt3]=c;

    switch(cnt2){
      case 0:
        if(c!='D'){
          lcd.clear();
          lcd.setCursor(9, 0);
          lcd.print(keys[cnt3]);
          ++cnt3;
          ++cnt2;
          Beep();
          break;
        }
        else break;
      case 1:
        if(c!='D'){
          lcd.setCursor(8,0);
          lcd.print("*");
          lcd.print(keys[cnt3]);
          ++cnt3;
          ++cnt2;
          Beep();
          break;
        }
        else{
          lcd.clear();
          --cnt3;
          --cnt2;
          break;
        }

      case 2:
        if(c!='D'){
          lcd.setCursor(8, 0);
          lcd.print("**");
          lcd.print(keys[cnt3]);
          ++cnt2;
          ++cnt3;
          Beep();
          break;
        }
        else{
          lcd.clear();
          lcd.setCursor(9,0);
          cnt3--;
          cnt2--;
          lcd.print(keys[cnt3-1]);

          break;
        }

      case 3:
        if(c!='D'){
          lcd.setCursor(8, 0);
          lcd.print("***");
          lcd.print(keys[cnt3]);
          ++cnt2;
          ++cnt3;
          Beep();
          break;
        }
        else{
          lcd.clear();
          lcd.setCursor(9,0);
          lcd.print("*");
          cnt3--;
          cnt2--;
          lcd.print(keys[cnt3-1]);
          break;
        }
      case 4:
        if(c!='D'){
          cnt2=0;
          cnt3=0;
        }
        else{
          lcd.clear();
          lcd.setCursor(9, 0);
          lcd.print("**");
          cnt2--;
          cnt3--;
          lcd.print(keys[cnt3-1]);
        }
      break;
    }
    while(digitalRead(DA)==1);//Making sure we wont get double input from one press, forcing the loop to stay there as long as a key is pressed
    if(c!='D'){
      keysPressed[count] = c;//Placing key pressed into an array
      count++;//raising array index
    }
    else{
      keysPressed[count]="";
      count--;
     }
    if (count == 5)//when count reaches 5, meaning array is full check if array 'password' is equal to the 5 keys the user just entered.
    {
      for (int i = 0; i < 5; i++)
      {
        if (password[i] == keysPressed[i])//if keys are the same add one to cnt, if cnt equals to 5, it means all keys were the same
        {
          cnt++;
        }
      }
        if(cnt==5){
          gateOpenSequence();
          cnt=0;
        }
        else{
          wrongPassword();
          cnt=0;
        }
        }
      }
  }

void returnKey(int key)
{
  char arrkey[16]={ '1','2','3','A','4','5','6','B','7','8','9','C','*','0','#','D' };
  c=arrkey[key];

}

void lcdSetup(){
  lcd.setCursor(0,0);
  lcd.write(2);
  lcd.setCursor(1, 0);
  lcd.write(1);
  lcd.setCursor(18,0);
  lcd.write(1);
  lcd.setCursor(19,0);
  lcd.write(2);
  lcd.setCursor(2,0);
  lcd.print("----Welcome-----");
  lcd.setCursor(0,1);
  lcd.print("|  Enter password  |");
  lcd.setCursor(0,2);
  lcd.print("|and then press '#'|");
  lcd.setCursor(0, 3);
  lcd.print("|------------------|");
}
void gateOpenSequence(){
  int start = 0;
  int desired = 105;
  lcd.clear();
  lcd.setCursor(6,0);
  lcd.print("Welcome");
  lcd.setCursor(8,1);
  lcd.print("Home");
  count = 0;
  digitalWrite(buzzer,HIGH);
  while(start<desired){
  servo.write(++start);
  delay(10);
  }
  delay(1000);
  digitalWrite(buzzer,LOW);
  lcdSetup();
  while(start>5){
  servo.write(--start);
  delay(10);
  }

}
void wrongPassword(){
  lcd.clear();
  lcd.setCursor(7,0);
  lcd.print("Wrong");
  lcd.setCursor(6,1);
  lcd.print("Password");
  lcd.setCursor(4, 2);
  lcd.print("Achalta ota");
  count = 0;
  for(int jj=0;jj<3;jj++){
    Beep();
  }
  delay(2000);
  lcdSetup();

}

void Beep(){
  digitalWrite(buzzer,HIGH);
  delay(200);
  digitalWrite(buzzer,LOW);
  delay(200);
}

I will really appreciate help as I can't seem to find any explanations about these two functions:
if (!mfrc522.PICC_IsNewCardPresent())
  {
    return;
  }
  //Select one of the cards
  if (!mfrc522.PICC_ReadCardSerial())
  {
    return;
  }

mfrc522.PICC_IsNewCardPresent()

will check, if a new RFID card/tag was presented to the reader. So if this returns true, you can read the card.
mfrc522.PICC_ReadCardSerial()

will actually read the data from the card/tag, so that the UUID is then available via mfrc522.uid.

Your problem stems from how you are using these functions. Lets have a look at that exact code snippet:
if (!mfrc522.PICC_IsNewCardPresent())
{
    return;
}
//Select one of the cards
if (!mfrc522.PICC_ReadCardSerial())
{
    return;
}

When we translate the first if statement into english we get:
 If no new card is present restart the function `loop()`.

This code snippet is at the start of the function. This means, that you will only read the code below that, if a new card is present and could be read. This logic only works good, if the RFID code is the only thing done in that function, which is not the case for you.
Instead you can restructure your RFID code a bit:
if(mfrc522.PICC_IsNewCardPresent() && mfrc522.PICC_ReadCardSerial()){
    // Handling all RFID code in here
    //Show UID on serial monitor
    Serial.print("UID tag :");
    String content= "";
    byte letter;

    for (byte i = 0; i < mfrc522.uid.size; i++)
    {
        Serial.print(mfrc522.uid.uidByte[i] < 0x10 ? " 0" : " ");
        Serial.print(mfrc522.uid.uidByte[i], HEX);
        content.concat(String(mfrc522.uid.uidByte[i] < 0x10 ? " 0" : " "));
        content.concat(String(mfrc522.uid.uidByte[i], HEX));
    }
    Serial.println();
    Serial.print("Message : ");
    content.toUpperCase();
    if (content.substring(1) == "17 27 C7 A6" || "BA FA 21 28") //change here the UID of the card/cards that you want to give access
    {
        Serial.println("Authorized access");
        Serial.println();
        delay(3000);
    } else {
        Serial.println(" Access denied");
        delay(3000);
    }
}

This will execute the RFID code, if a new card could be read. Otherwise it will just continue with the rest of the code.
Note, that due to the delay(3000) call your code won't react to anything for 3 seconds after a card was presented to the reader. You might wanna ditch that delay in favor of a better responsiveness.


text:
Things stop working if I use Serial.println(tt) and when I use display.drawPixel(i - ii, 64 - Harray[ii], SSD1306_WHITE);
Things stop working if I use line 131 Serial.println(tt); and when I use line 145 display.drawPixel(i - ii, 64 - Harray[ii], SSD1306_WHITE); Also Serial Monitor gives very strange reading. Serial monitor is 9600 baud.
//Kamil Mambetov
//Feb 17 2023
//sht31 with display and plot on it.

#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <Arduino.h>
#include <Wire.h>
#include "Adafruit_SHT31.h"

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

uint8_t loopCnt = 0;
uint8_t i = 0;
int Tarray[128] = {};
int Harray[128] = {};
float tmax = 0;
float tmin = 0;
float hmax = 0;
float hmin = 0;

Adafruit_SHT31 sht31 = Adafruit_SHT31();

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

void setup() {
  display.begin(SSD1306_SWITCHCAPVCC);
  //u8g2_for_adafruit_gfx.begin(display);  // connect u8g2 procedures to Adafruit GFX

  Serial.begin(9600);

  while (!Serial)
    delay(10);  // will pause Zero, Leonardo, etc until serial console opens

  Serial.println("SHT31 test");
  if (!sht31.begin(0x44)) {  // Set to 0x45 for alternate i2c addr
    Serial.println("Couldn't find SHT31");
    while (1) delay(1);
  }
}

void loop() {
  display.clearDisplay();
  display.setTextSize(1);               // Normal 1:1 pixel scale
  display.setTextColor(SSD1306_WHITE);  // Draw white text
  display.setCursor(0, 0);              // Start at top-left corner
  display.cp437(true);                  // Use full 256 char 'Code Page 437' font

  float t = sht31.readTemperature();
  float h = sht31.readHumidity();

  if (t > tmax or tmax == 0) {
    tmax = t;
  } else if (t < tmin or tmin == 0) {
    tmin = t;
  }

  if (h > hmax or hmax == 0) {
    hmax = h;
  } else if (h < hmin or hmin == 0) {
    hmin = h;
  }

  char *Tchar = "";
  char *Hchar = "";
  char *Tmaxchar = "";
  char *Hmaxchar = "";
  char *Tminchar = "";
  char *Hminchar = "";

  display.setCursor(0, 0);  // start writing at this position
  //display.print("t:");
  //display.setCursor(12, 0);
  dtostrf(t, 4, 1, Tchar);
  display.print(Tchar);

  display.setCursor(30, 0);
  display.print("max:");
  display.setCursor(52, 0);
  dtostrf(tmax, 4, 1, Tmaxchar);
  display.print(Tmaxchar);

  display.setCursor(78, 0);
  display.print("min:");
  display.setCursor(100, 0);
  dtostrf(tmin, 4, 1, Tminchar);
  display.print(Tminchar);

  display.setCursor(0, 8);
  //display.print("h:");
  //display.setCursor(12, 8);
  dtostrf(h, 4, 1, Hchar);
  display.print(Hchar);

  display.setCursor(30, 8);
  display.print("max:");
  display.setCursor(52, 8);
  dtostrf(hmax, 4, 1, Hmaxchar);
  display.print(Hmaxchar);

  display.setCursor(78, 8);
  display.print("min:");
  display.setCursor(100, 8);
  dtostrf(hmin, 4, 1, Hminchar);
  display.print(Hminchar);

  // display.drawPixel(x, t, SSD1306_WHITE); //draw single pixel
  //Serial.println(h);
  // Serial.print("aaa");
  //Serial.println(t);
  // Serial.print("ttt");
  //float to int conversion
  int tt = 0;
  int hh = 0;
  tt = int(t);
  float c = 0;
  c = h/2;
  hh = int(c);
  //Serial.println(c);
  Serial.println(tt);

  //plot
  i++;
  loopCnt++;

  Tarray[i] = tt;
  Harray[i] = hh;
  //Serial.println(Harray[i]);

  int ii = 0;
  while (ii < i) {
    ii++;
    display.drawPixel(i - ii, 64 - Tarray[ii], SSD1306_WHITE);
    //display.drawPixel(i - ii, 64 - Harray[ii], SSD1306_WHITE);
  }

  if (i == 128) {
    i = 0;
  }

  display.display();  // make everything visible
  delay(2000);
}

Regarding your question about code formatting, you can see what I did in the side-by-side markdown view in the revisions on the question. In short triple-back-tics before and after the code. The editor has help under the question mark in the circle in the upper right. You can also indent the code with spaces, but that's somewhat more painful to work with and the language used cannot be hinted.

source: Stack Exchange

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

sort: votes


text:
Arduino Wire library master reader, slave sender example not working
I tried i2c EPROM and that worked pretty fine with arduino master. then i wanted to establish i2c communication between 2 arduinos such that both exchange each other's sensors data. I am not able to receive bytes from slave arduino. Unable to do what i was upto i resorted to example sketches of Wire library to assess what i was doing wrong and to my surprise even example sketches were not working. Definitely there is something wrong with my approach. Problem only appears when master requests data from another arduino slave (master sends data successfully to slave arduino but vice versa is not true) . i have assessed that problem is in requestEvent function of slave as that either doesnt send anything. or returns mysterious character. I am runnign proteous simulation. Master sends data seamlessly ( although here master is just reading but i was able to send data from master to slave successfully) but when master requests data from slave it does not get desired response. Please suggest some solution. Here is the code which is just copy pasted from Wire library examples ( master reader for master arduino and slave sender for slave arduino.  slave is just to send 6 bytes ("Hello ") to master when prompted.
Master code
// Wire Master Reader
// by Nicholas Zambetti <http://www.zambetti.com>

// Demonstrates use of the Wire library
// Reads data from an I2C/TWI slave device
// Refer to the "Wire Slave Sender" example for use with this

// Created 29 March 2006

// This example code is in the public domain.

#include <Wire.h>

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

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

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

  delay(500);
}

Slave code
// Wire Slave Sender
// by Nicholas Zambetti <http://www.zambetti.com>

// Demonstrates use of the Wire library
// Sends data as an I2C/TWI slave device
// Refer to the "Wire Master Reader" example for use with this

// Created 29 March 2006

// This example code is in the public domain.

#include <Wire.h>

void setup() {
  Wire.begin(8);                // join i2c bus with address #8
  Wire.onRequest(requestEvent); // register event
}

void loop() {
  delay(100);
}

// function that executes whenever data is requested by master
// this function is registered as an event, see setup()
void requestEvent() {
  Wire.write("hello "); // respond with message of 6 bytes
  // as expected by master
}

but proteous simulation shows that master is getting 6 bytes from slave instead of "Hello " which was sent by slave master is getting "|     "        "

Might very well be a problem with proteus. Simulations are finicky, complex and always incomplete

What are the parameters of the virtual terminal? Because so far as I can can tell, it supports a notion of virtual baud/line discipline. Or a different question: what happens if you keep the same settings for the virtual terminal but instead write a hello world type program that uses the same (9600) baud?

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


text:
Using RDM6300 and RC522 at once
I want to use both RDM6300 and RC522 at a single .ino code at once. But whenever I try them both, only one of them works. How to get the both working?
[Dev envt. ESP32 Dev module]

// LIBRARY ADDITION HERE
#include <SPI.h>
#include <rdm6300.h>
#include <MFRC522.h>

// PIN DEFINITIONS HERE
#define RC522_RST_PIN        22
#define RC522_SS_PIN          21
#define RDM6300_RX_PIN        5

// PIN DEFINITIONS
MFRC522 mfrc522(RC522_SS_PIN, RC522_RST_PIN);
Rdm6300 rdm6300;

void setup() {

  // LIBRARY INITIALTIONS
  Serial.begin(115200);
  SPI.begin();
  mfrc522.PCD_Init();
  delay(4);               // added this delay cus mc is slower than we expected. It takes some time to start the initiation
  rdm6300.begin(RDM6300_RX_PIN);
  delay(5);
}

unsigned long getID522() {

  if ( ! mfrc522.PICC_ReadCardSerial()) {
    return 0;
  }
  unsigned long hex_num;
  hex_num =  mfrc522.uid.uidByte[0] << 24;
  hex_num += mfrc522.uid.uidByte[1] << 16;
  hex_num += mfrc522.uid.uidByte[2] <<  8;
  hex_num += mfrc522.uid.uidByte[3];
  mfrc522.PICC_HaltA();
  return hex_num;
}

void loop() {

  if(mfrc522.PICC_IsNewCardPresent()) {
    unsigned long uid = getID522();
    if(uid != 0){
      Serial.println(uid);
    }
  }

  Serial.println("aaaaaaaaa");

  if (rdm6300.get_new_tag_id()) {
    Serial.println(rdm6300.get_tag_id(), HEX);
    Serial.println("ydfutfcfygfigi");
    Serial.println(rdm6300.get_new_tag_id());
  }

  delay(100);
}

please copy and paste the content of the serial monitor into your question

read the answer here https://arduino.stackexchange.com/questions/92291/using-mfrc522-along-with-other-inputsbluetooth-keypad


text:
How to declare PB3 reset pin of ATtiny44 in program (using arduino IDE platform)
As follow-up of my former question:
Hi, I want to know how I can access PB3 reset pin of ATtiny44 IC. I ran out of pins so I am using it as I/O pin, but I am unable to declare it in the code.

This picture above says that PB3 is pin 11. But if I declare it as pin 11, the reset pin does not function at all.
// in setup():
    DDRB |= (uint8_t)(1U << 3);

// in loop():
    PORTB |= (uint8_t)(1U << 3);    // set PB3 to "high"
    PORTB &= ~((uint8_t)(1U << 3)); // set PB3 to "low"

This code works with only direct declaration.
In my code I just need to add pin number to the command like #define CSN 2.

EDIT
#include <avr/io.h>

const int led = 0;

#define led1 11

// the setup function runs once when you press reset or power the board
void setup() {
  // initialize digital pin LED_BUILTIN as an output.
  pinMode(led, OUTPUT);

  pinMode(led1, OUTPUT);
}

// the loop function runs over and over again forever
void loop() {
    digitalWrite(led, HIGH);
    digitalWrite(led1, HIGH);

    delay(1000);                       // wait for a second

    digitalWrite(led1, LOW);

    digitalWrite(led, LOW);    // turn the LED off by making the voltage LOW
    delay(1000);                       // wait for a second
}

This is the code that does not work (led1 is reset pin as GPIO). Even if I change the led1 declaration to PB3 of PCINT11, it still does not work.

Show a complete compilable/testable example that demonstrates it affecting the pin using GPIO register manipulation and not affecting it using attinycore's already provided digital pin 11.

@timemage You can check the edit above

I see it. That does not look like what I described. Basically I'm looking for an excuse to actually test this. I fully expect if I take the time to dig out my high voltage programmer, and wire it so I can recover from RSTDISBL and I do my own test I will find that digital pin 11 with the correct layout in attinycore will work just fine and the problem is not really as written. If I put in that sort of effort, I'll know I'm not imagining things but I still won't be able to write an answer that I think will solve this for you. It is already documented.

excuse? i performed my test but the led on the reset remains full OFF and as per the code it should blink whereas, the second led connected to pin13 properly blinks. That is my issue. i have added my fusebit config for your reference.

I am using damellis library to use arduino as ISP

By excuse if you mean, the reason behind using reset. The reason is that I ran out of pins and in order to complete the project I need one more GPIO pin and using reset as GPIO is the only solution I can see.

That may be part of your problem if it leads to incompatible compilation of the sketch. I don't know why you're doing that, attinycore provides for programming via arduino as isp. By "excuse" I mean that I don't want to spend a few hours locating everything just to show that everything behaves exactly as I expected and "the problem is not really as written", like for example what you just said about trying to use two board support packages in a way that may easily screw things up. That was not in the question.

I think there is some misunderstanding. I am using just ATtiny44, for programming I am using HVP because I have to disable the reset pin. To write the code I use Arduino platform and I am at the final stage of my program.

That is in line with my understanding. If information shows in the question that makes me feel like I can replicate your test and I'm not dead-certain that it won't just work for me, I'll take the time recreate the problem here.

@timemage Ok, so you think that declaring it as pin11 would work

I have formatted you question a second time, please do not overwrite it again. ;-) -- If the pin works by direct access, as I showed you in the other question, and does not work with the pin number 11, this pin number or the board selection in the IDE do not match. Which board did you select in the IDE? -- Oh, BTW, this answer backs up my assumption that the pin PB3 does no have a pin number.

@thebusybee, notice they've been trying to use the damellis board package for their programmer definition for some inexplicable reason instead of the attinycore one. i wouldn't be surprised if it's recompiling under a damellis core prior to upload because they've selected that board package to use its version of arduinoisp.ino programmers.txt entry. I fully expect that if set up attinycore with an attinyX4 and use its own programmers.txt entry for arduinoisp.ino, disable reset, and use pin 11 it'll just work fine. so i've been trying to get them to update their question.

@thebusybee and timemage Hi, just an update, i have resolved my issue. I installed spencekonde attiny Core and it worked for me now i can assign reset pin as 11, use HVP to disable reset. Thank you.

Great news! Now, to help future visitors (including yourself after some weeks :-P) please write an actual answer and mark it as "accepted".

@thebusybee Okay, that issue has been resolved and i have written answer as well, i will create another post because i have some other issue now with the same project.

@thebusybee https://arduino.stackexchange.com/questions/92329/reading-constant-battery-voltage-and-using-the-obtained-value-in-sensor-formula  Could you please check this

i resolved my issue by installing spenceKonde ATtinyCore library, The RESET pin is pin 11 of attiny44 IC and in order to access it inside the code we need attinyCore library not Damellis( damellis does not have RESET programming access).


text:
Arduino Nano 33 BLE getting the current time using RTC
I have a an arduino NANO 33 BLE and I'm trying to get the current time and date. Based on the documentation, the arduino has nRF52840 microcontroller which comes with a 24 RTC timer It is listed in the nordic documentation as well. However, I'm not sure exactly how to use it to get the current time; Based on the MbedOS documentation for Time I wrote out the code to print out the current time and date in conjunction with reading the data:
#include "mbed.h"
#include <Time.h>
#include <RTClib.h>

time_t rawtime;
struct tm *info;

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

//resistor val = 100K

void loop() {
  rawtime = time(NULL);
  time(&rawtime);
  info = localtime(&rawtime);
  int val = analogRead(A1);
  Serial.print(val);
  Serial.print('-');
  Serial.print(asctime(info) );
  delay(5);
  }

However it just prints out this:

XX-Thu Jan 1  00:08:30 1970

Where the XX is the correct sensor data. Why is the time not the current time but the beginning unix epoch ? This code was run in the Desktop Arduino IDE in Win10

if you buy a wall clock, put a battery into it and don't do anything else, then do you expect the correct time to be shown?

@jsotola doesnt the   rawtime = time(NULL); time(&rawtime);  acts like setting the time ? Or am I misinterpreting that line of code ?

where would the current time/date come from? ... https://duckduckgo.com/?q=jan+1st+1970&ia=web

I was going to write something more elaborate, but in short the RTC in the NRF52840 is not a "clock" so much as an asynchronous timer/counter. As in, you can run it from a clock source that isn't related to the system clock that times your code and it may (or may not) continue to count when you're in a sleep mode. So, you may be able to use this async. timer/counter as a building block in constructing what amounts to an approximation of a real-time clock (like a DS3231). That you might use it that way isn't assumed by Nordic, or mbed, or Arduino, or libc/time.h, and RTCLib.h concerns itself with accessing specific models external realtime clock chips with no direct connection to time.h. So there's nothing to support your specific use case in each of these things.
So you can try to build a real-time clock functionality out of it. But if you're like most Arduino users you're probably better off getting a DS3231 or something like it. You will probably end up with more accurate time keeping and battery backup, etc than you would if you build this functionality yourself out of the NRF52's counter.
If you have a need or strong desire to use <time.h>, that can usually be done by completing its implementation in some implementation specific documented way. Basically you'd retrieve the time fields out of something like the DS3231 an then use that to set what amounts to a time_t variable that backs time() and then to call regularly call some kind of time advance function from an interrupt routine based on the square wave output from the DS3231 (or whatever). If you really want to make use of the async. counter yourself, all of that applies there as well.


text:
Cannot connect Arduino Mega 2560
I was able to work with the same Arduino on the same laptop yesterday. However, the Arduino IDE is unable to connect the Arduino Mega 2560 today. I tried with a different Arduino Mega 2560 but the Arduino IDE doesn't connect it. My laptop is able to recognize COM Port but in the Arduino IDE the "Tools - Ports option" is missing.

what is your question? ..... which version of Arduino IDE are you using?

I am using Arduino IDE 2.0.3. My question is that how do I connect my Arduino Mega 2560 to the Arduino IDE on my laptop? As the first picture shows, the Device Manager is able to recognize the device. However, in the Arduino IDE, it said "NO PORTS DISCOVERED". I have read most of the articles online and tried their methods but none of them works. I am wondering why my laptop can recognize the device while my Arduino IDE cannot. Furthermore, the Arduino IDE can connect with the device until yesterday. I changed nothing on my laptop.

2.0.3 may be broken ... try earlier versions ... or try the nightly build


text:
Need help writing to and then reading from a serial device
I have a serial device hooked up to my Arduino (ESP32 WROOM). I'm not a serial expert but I have at least some stuff working. The manual is chinese (or at least, very broken english) and I'm trying to make sense of it.
The device needs to be configured as such:

Baud rate: 115200
Word width: 8bit
Stop bit: 1
Parity: None
Flow control: none (no idea what that is?)
Receive/send settings: ASCII

I would assume that is done by doing: (it's on RX2/TX2)
MMWave.begin(115200, SERIAL_8N1, 16, 17);
When I try the following code I get the output from the device as expected:
#include <Arduino.h>

HardwareSerial MMWave(1);
const byte numChars = 32;
char receivedChars[numChars];   // an array to store the received data
bool newData = false;

void setup() {
    Serial.begin(115200);
    MMWave.begin(115200, SERIAL_8N1, 16, 17);
}

bool sent = false;

void loop() {
    byte index = 0;
    while(MMWave.available() > 0) {
        char rc = MMWave.read();
        receivedChars[index] = rc;
        index++;

        if (rc == '\n') {
            Serial.print(receivedChars);
            index = 0;
            delay(1000);
        }
    }
}

The output is exactly as in the manual:
mov, dis=2.95
mov, dis=2.83
mov, dis=2.83

Now comes the problem, I can write parameters to the device as well. They say to send/receive data in ASCII in the manual and that when I write the command "get_all" to the device I should get a response returning all the current configuration parameters.
If I do not get the feedback from the device the manual tell me to make sure that the command is sent "with a carriage return and line feed".
I would expect that when I:
MMWave.write("get_all");
MMWave.write('\r');
MMWave.write('\n');

And then use the above code to read again...I would get the output from the command. But instead it keeps outputing the mov lines (default output) and it doesn't respond at all to my command. I also tried to:
MMWave.println("get_all");

And
MMWave.print("get_all\r\n");

Nothing seems to work. Any advice would be greatly appreciated. I have read alot of serial introduction stuff but I can't seem to match the correct info to my use case.
Thank you guys in advance!
For anyone interested the manual can be downloaded here: Sensor manual

Try String myCMD="get_all";  myCMD += "\r\n";     MMWave.print(myCMD);  Looks like you are using some kind of serial assist program...and with no docs - you don't need to do that.

for RX2/TX2 I would use Serial2

Ì have switched over to Serial2 and tried the myCMD approach. Both to no avail, the output is still decent but the output from get_all doesn't show at all.

Note that your three ways of sending "get_all\r\n" are strictly equivalent.

That is what I thought @EdgarBonet but it returns nothing none the less.
Sometimes something but almost always nothing.


text:
6-pin BME280 not giving I2C signal

I'm creating a telemetry package for my my mom's model rocket with a MPU6050, a BME280, and a SD reader/writer. The code I found for the BME does not read any information. When I upload an I2C scanner, the MPU gives a signal, but the I2C gives "No i2c signal found". The wiring schematics are the same. I've tried different boards, and I've tried different code. Nothing works.

Re: 12C gives "No i2c signal found" The I2C (I'm guessing) can't talk. So, what exactly is reporting this message. A library? What library? Your code? What code? If you're having problems detecting I2C devices generally run the I2CScanner sketch before trying anything specific to the sensors.

When you don't give us more information, it makes it hard to help. The BME280 can use I2C OR SPI. If it is on a board set up for SPI, that might be the whole problem.....or it is something else. A picture of the board or a schematic of the circuit would help a lot.

Sorry I did not clarify. The code I was using was the 12C scanner code.

Basic debugging: try a minimal setup - connect only the BME280 to the CPU, not the other parts. Run the I2C scanner. Also let us know WHAT are you connecting it to and exactly how did you wire it?

From the datasheet "Interface selection is done automatically based on CSB (chip select) status. If CSB is connected to VDDIO, the I²C interface is active. If CSB is pulled down, the SPI interface is activated. After CSB has been pulled down once (regardless of whether any clock cycle occurred), the I²C interface is disabled until the next power-on-reset." Again, maybe show us a picture of the board or circuit?

Your image does not show VCC and GND connected to your BME280. If that's not your actual wiring, show your actual wiring.

That is the actual wiring, but the board is flipped around.

Is it a 3.3V or a 5V module?

the picture shows no power connection and no ground connection ... you are trying to fly a rocket without an engine

You mean that it's reversed left-to-right and that in actual use it's the CSB and SDO that are unconnected? Really you should just get a picture of it as wired so as not to confuse the crap out people.

sorry ill upload the proper picture, it all works except the pressure value is off the charts.

@ModelRocketeer - I appreciate your frustration and I hope this will be of some help.
First of all, you have to make sure the board is wired correctly and it is anyone's guess whether it is wired correctly because you have not shown that to us and that frustrates us because we would like to help.
Here is a very similar board attached to a D1 mini.

If I flip it over to show the signal names, AND line it up correctly, one can see how it is hooked up....or it is just confusing because it is flipped over.

BUT why not just tell us, like this:

D1 mini<->280
3.3v   <-> Vcc
GND    <-> GND
D1     <-> SCL
D2     <-> SDA

AND show us a clear picture because many eyes on it can increase the likelihood of solving the problem.
BTW: using colored leads helps with checking.
I have several of these generic 280 boards - they are cheap and when I bought mine, they were sold as BME280, but it turns out (after hours of frustration) that they were in fact BMP280. Apparently, the board can hold either. Be forewarned.
I tested my board with a D1, like yours at 3.3v, and an UNO at 5.0V and they both worked.
I then tested a known-to-be BME280 and it worked fine with the D1 mini.
In ALL cases, I was able to use a port scanner and see the I2C address (0x76).
Because you have not been able to detect any connection over I2C for the board but can detect a port for the MPU6050, I think you need to do the following:
Make sure you have the proper connections.
Remove the MPU6050 and have only the BMP/BME connected and run the scanner.
If you still see nothing, I would say the board is bricked. Because you said you tested several boards, I suspect (as have others) that you do not have it connected properly.
When you get it connected properly and can see a port when scanning - try running BME software but if you use the Adafruit programs you might need to force I2C since this is not an Adafruit board. The latter is able to use both I2C and SPI.
If you still don't get results, consider that it may, in fact be a BMP280 and try software for that.
In either event, please let us know what happens.

Did you wait until I finished responding to get it to work? :)

Feels like it, but I stepped away from it for a few hours, and when I came back to it I redid everything and it "worked" though the pressure value, the only one I need is giving me an absurd value and saying I'm 32,000  feet in the air.

Yes, it can't do exact altitude on its own - see https://arduino.stackexchange.com/questions/44715/bmp-280-exact-altimeter-readings


text:
Why can't my four batteries (6V) can't power this circuit while usb 5v from arduino can?
I have this circuit

And I want it to power all the led rgb (100 in total), I want to make a independent portable circuit, so I don't have to use the usb power. The thing is when I use this circuit it only power to 44 led.
WHile when I use the usb 5V it can full lights all led .

This is my code
#include <Adafruit_NeoPixel.h>

#define NUM_LEDS 100
#define LED_PIN 2
Adafruit_NeoPixel strip = Adafruit_NeoPixel(NUM_LEDS, LED_PIN, NEO_RGB+NEO_KHZ800);
void setup()
{

  strip.begin();
  strip.show();

}

void loop()
{

  for (int i = 0; i < NUM_LEDS; i = i+1)
  {
    strip.setPixelColor(i, strip.Color(255, 240, 255));

    strip.show();
    delay(1000);
  }

}

What may I be missing?

USB port capable of providing 5V with up to 1A current. Your 4 AA-battery obviously not capable to deliver the current it required for 100 LED. 2) Programmable LED is not just LED, it has chip inside and it supposed to operate at 5V, you drive it with 6V, even it not "work", but it could damage the chip in the long run. I' suggest you read Adafruit Neopixel Uber Guide which explain the power requirements and choice of power source.

As shown, your four batteries are delivering 1.6v to the MCU, not 6v

The current available from a computer's USB port is 500 mA; some ports can supply more if the device negotiates for it.
You show AA cells in your diagram. Even assuming they're Alkaline cells, batteries differ in their capacity vs. discharge rates, and presumably in their internal resistances. Most any power-supply's voltage will sag as you draw more current from it. The likely answer is that as you add LED's the battery voltage falls below either what is needed to light the LEDs; or 2) the dropout voltage of Arduino's voltage regulator, which shuts down the Arduino (assuming you're connected to 'V_in', not '5v', which neither diagram shows).  Less-than-fresh batteries will exhibit this voltage drop sooner and to a greater degree.
This study of AA battery capacity vs. current draw might help understand the apparent loss of capacity at greater currents. But even without that phenomenon, the battery voltage will fall as (I * R_battery); capacity loss just makes it worse.

Hello JRobert thanks for your observation. Besides the explanation, is there anything I can do to solve this?

add more batteries in parallel (not series) or start with a higher voltage and use a properly rated and efficent dc-dc converter to lower it

It would probably be worth asking another question about how to estimate power draw from the lights and how to design a proper battery pack to power it...

A quick and dirty solution would be to make another (or 2 more, if needed) 4-cells-in-series battery packs, and connect its/their +V and Gnd to the +V and Gnd (respectively) of the present pack. All of your batteries should be fresh. Run a test to see how many LEDs it will sustain, and whether it will sustain them for as long as you need it to. The better solution is @user10489's second suggestion - to calculate your current needs and an energy budget, and design a power-pack to meet it.

Exactly as JRobert says...  note that if the batteries are not "fresh" they will mutually charge each other, which could be bad for non-rechargable batteries.  (In other words, they don't have to be fresh or balanced if they are rechargeable.)


text:
Reading constant battery voltage and using the obtained value in sensor formula
there i am working on a project in which my system is connected to 3.7v~4.2V lithium battery, I have to read constant battery voltage irrespective of the current battery voltage and to do that I am using internal voltage reference (1.1V). My issue is that before adding sensor code my program was reading constant voltage irrespective of any battery level but the moment I add sensor code to it, the battery voltage readings fluctuate.

You still have some problems as all the other times you have asked this question. You need to make the minimal version of the code that works as you expect, and then show what change you make that produces output you do not expect. (1) do not mix Arduino analog pin functions with direct register access. Pick one or the other (you should pick arduino). (2) remember that you can only real voltages between 0-1.1V with the 1.1V. Any voltage higher than 1.1V will read as max value (1.1V) against this reference.(3) you are using A1 in your code, but A1 is not connected to anything in your schematic.

People want to help you, but you have to help them to help you! By continuing to ask the same question over and over and over again you wasting the time of the nice people trying to help you and you are not even getting solutions to your problem. Make the simplest version of the program that works. This is probably measuring the battery voltage though the bridge using A0 pin using only Arduino function. This should be a very short program. Make sure it really works as you expect across all potential voltages you might see.

I know you just want someone to give you a quick fix, but you have already spent way way more time asking this question over and over again than you would have to systematically work your way through this problem! Start simple, understand what is going on. I promise! :)

@bigjosh It is working, i needed stable output. As you said i have removed all register function and using simple arduino code. please check above

My issue is that i want to connect my solar panel to positive and negative of battery but the moment i make the connection my sensor reads 1023 which it obviously should. so, is there a way to separate out or connect.

i believe my measuring scale of 1.1 is way too small it reaches 1023 when the multimeter reads around 1V

"My issue is that i want to connect my solar panel to positive and negative of battery" this is a different question than the one asked here.

"i believe my measuring scale of 1.1 is way too small it reaches 1023 when the multimeter reads around 1V" Yes, when measuring a voltage using the 1.1V reference, you would expect voltages near 0V to read the value 0 and voltages near 1.1V to read a value near 1023 (remember the +/-10%).

You should re-check my answer on how to measure Vcc against the 1.1V from one of the first times you asked this question. This is what you actually want to do.

@bigjosh ok i understood now that it is not required to measure battery voltage in order to read sensor value. I used internal reference voltage and measured my panel and i was successful in reading exact proper values with the resolution of 0-1023.

@bigjosh Now the problem i face is, when i use the same code with attiny it does not work.

ok i think it will work now the issue was with the code, instead of >= i made <= that's why the code was not working

If you set the Vref with the internal reference of 1.1v, then the voltage presented at analog pin A1 is simply as:
const float Vref = 1.1; // according to datasheet there is a +/-10% variance, need calibration to confirm the actual value

analogReference(INTERNAL);
float VA1 = Vref / 1023.0 * analogRead(A1); // voltage at analog pin A1
float Vbat = VA1 * 5.7;                     // battery voltage

For more accurate measurement. you can use a multimeter to measure the actual Vref, and use the actual measurement in your sketch as the Vref value. BTW, if you are using battery, you may want to change your voltage divider to 47k and 10k to reduce the current draw by the voltage divider.

sure, i will use the exact vref value. Is it 47k or 4.7k? because i have used 4.7k and if i change my 1k to 10k, do i need to change the value (5.7) in the program?, we need one pin just to read the battery voltage right?

Use 47k and 10k resistors, the ration will still be the same (47000+10000)/10000. But this only draw current of 3.7/(47000+10000) = 65uA, versus when using 4.7k+1k which draw 0.65mA. 10 times difference.

Your original post mentioned nothing about any light sensor, it was asking how to read the battery voltage. If my answer help you answered that question, please accept the answer by click on the 'tick' and upvote it so that future reader know this is a correct answer. Feel free to post another question regarding your lighting sensor question with your code separately.


text:
Why does my IDE fail to open files?
I'm using Version: 2.0.3 - Date: 2022-12-05T09:30:25.33 on Windows 10 Pro. Installed under Local user - not for all users.
When I try and open a ino file (either double clicking on a ino file - or file->Open) - it spawns a new window - but then I just see the standard sketch with an empty setup() and loop()
I've uninstalled and re-installed both for my own users and all. But still, it does the same thing. I'm having to open all my sketches in notepad++ and then save them in whatever temp Arduino file it creates. Its hellishly annoying

2.0.3 may be broken ... try another version

Hmm. happening on 2.0.2 too

And if you run it as "Administrator" ?

And here https://forum.arduino.cc/t/arduino-2-0-not-starting-up/950998/2 in answer #3 you can start Arduino from CLI and debug it.

Thanks @MatsK - I think its a bug due to my dodgy filesystem on windows..   I see this in the output
2023-02-21T11:22:21.224Z sketches-service WARN Warning! The request sketch path was different than the response sketch path from the CLI. This could be a potential bug. Request: <\ace-svr02\Users$\wwade\Documents\GitHub\X80\firmware\x80Tester\x80Tester.ino>, response: <\ace-svr02\Users$\wwade\Documents\GitHub\X80\firmware\x80Tester>.

If you try to open a sketch from a shared drive on Windows, it does not work. See the bug here. When opening a sketch fails, IDE returns to a new temp sketch. That's why you see void setup(){} void loop(){}.


text:
Arduino code working via IDE, not via PlatformIO Arduino code
I have a working Arduino code. The code works as intended when I upload it to an Arduino Nano using the old bootloader via the Arduino IDE. However, when I upload the same code via PlatformIO, the code uploads successfully but does not work as intended. There are no errors or warnings during the upload process, and I am having trouble figuring out what could be causing the issue.
Now for troubleshooting I am using simple blink example.
#include <Arduino.h>
// the setup function runs once when you press reset or power the board
void setup() {
  // initialize digital pin LED_BUILTIN as an output.
  pinMode(LED_BUILTIN, OUTPUT);
}

// the loop function runs over and over again forever
void loop() {
  digitalWrite(LED_BUILTIN, HIGH);  // turn the LED on (HIGH is the voltage level)
  delay(1000);                      // wait for a second
  digitalWrite(LED_BUILTIN, LOW);   // turn the LED off by making the voltage LOW
  delay(1000);                      // wait for a second
}

1st PlatformIO configuration .ini
[env:nanoatmega328]
platform = atmelavr
board = nanoatmega328
framework = arduino
debug_port = COM3
monitor_speed = 115200

I have also tried following but no luck.
2nd PlatformIO configuration .ini
[env:nanoatmega328]
platform = atmelavr
board = nanoatmega328
framework = arduino
board_oldbootloader = true
debug_port = COM3
monitor_speed = 115200

Any suggestions on how to debug this problem or what might be causing the issue? Thank you.

The blink function gets programmed by the IDE. In case I program with Arduino IDE the code gets uploaded to the board and works as intended (i.e. LED blinks). In case I program with PlatformIO the code gets uploaded to the board but doesn't work as intended (i.e. (The LED doesn't blink).

It's very weird. I have tried different solutions but nothing seems to work.

turn on the LED in setup ... leave loop() empty ... what happens?

print the value of LED_BUILTIN to serial monitor to see its value ... also, try referring to the LED pin by number

My apologies. Not familiar, 1st ever question.

Ok, a weird thing happened. :D

I did as you said. I left the loop empty and turned on led in the setup. Result: The LED stays off.
I uncommented the loop and uploaded again. The LED started blinking.
The problem resolved itself. Any idea what went right.

you never loaded the sketch the first time around

I had a similar behavior for a while and nothing I would change in the PlatformIO .ini configuration file seemed to help. I tried to re-init and clean the project, but also didn't seem to help.
Eventually, what worked for me was to start a new fresh PlatformIO project and migrate the files over.
I suspect that under certain conditions (that may be related to the project settings), PlatformIO fails to upload the script, yet it claims that the upload was successful.


text:
Combined code to run a 2-zone radiant floor system. Cannot get 'RadiantMain' to work. Better description in beginning of code
Trying to combine code to run a 2-zone radiant floor heating system. The menu code works perfectly. When I select MenuC 'Run main' it executes to RadiantMain prints test and then returns to menu options again. Been working on this for weeks and don't how to fix it. The RadiantMain code works ok as a stand-alone.
The second sketch starts where it says //START RUN RADIANT MAIN CODE. The menu sketch and the Radiant Main are 2 separate sketches written by 2 different developers. They do run as stand-alone sketches. I modified the menu sketch to operate my relays (MenuA and MenuB) for the manual mode it works fine. I need to be able to use the menu sketch to run 3 different functions. MenuA & MenuB to manually run the system in manual mode and a third menu item (MenuC) to run the 2nd sketch in auto mode.
I need to combine the 2 sketches together into one code
I am using a D1 ROBOT LCD KEYPAD shield. A1 through A5 are connected to temp sensors. 4 relay shield controls 2 water valves and a pump, 4th relay is unused. the menu sketch controls the 2 water valves with MenuA and MenuB. I need MenuC to run the second sketch which reads sensors sets temps and controls 2 water valves and a pump.

//MENU CODE STARTS HERE

#include <LiquidCrystal.h>
LiquidCrystal lcd(8,9,4,5,6,7);

int keypad_pin = A0;
int keypad_value = 0;
int keypad_value_old = 0;

int pinCount = 4;
int relay_1 = 12;//zone 1
int relay_2 = 11;//zone 2
int relay_3 = 3;//pump
//int relay_4 = 2;//open

char btn_push;

byte mainMenuPage = 1;
byte mainMenuPageOld = 1;
byte mainMenuTotal = 3;

void setup() {
  Serial.begin(9600);
  pinMode(relay_1, OUTPUT);//zone 1
  pinMode(relay_2, OUTPUT);//zone 2
  pinMode(relay_3, OUTPUT);//pump
  //pinMode(relay_4, OUTPUT);
    lcd.begin(16,2);  //Initialize a 2x16 type LCD

    MainMenuDisplay();
    delay(1000);
}
void loop()

{
    btn_push = ReadKeypad();

    MainMenuBtn();

    if(btn_push == 'S')//enter selected menu
    {
        WaitBtnRelease();
        switch (mainMenuPage)
        {
            case 1:
              Zone1();
              break;
            case 2:
              Zone2();
              break;
            case 3:
              Radiant();
              break;
            /*case 4:
              MenuD();
              */break;
        }

          MainMenuDisplay();
          WaitBtnRelease();
    }

    delay(10);

}//--------------- End of loop() loop ---------------------

void MainMenuDisplay()
{
    lcd.clear();
    lcd.setCursor(0,0);
    lcd.print("Choose function");
    lcd.setCursor(1,1);
    switch (mainMenuPage)
    {
        case 1:
          lcd.print("Run zone 1");
          break;
        case 2:
          lcd.print("Run zone 2");
          break;
        case 3:
          lcd.print("Run main");
          break;
        case 4:
          lcd.print("4. Menu D");
          break;
    }
}

void Zone1()

{
    {
    digitalWrite(relay_1, HIGH);
    digitalWrite(relay_3, HIGH);
    lcd.clear();
    lcd.setCursor(0,0);
    lcd.print(" Running zone 1");
    lcd.setCursor(0,1);
    lcd.print(" Left to end");
    while(ReadKeypad()!= 'L');
    digitalWrite(relay_1, LOW);
    digitalWrite(relay_3, LOW);
    }
}
void Zone2()
{
    digitalWrite(relay_2, HIGH);
    digitalWrite(relay_3, HIGH);
    lcd.clear();
    lcd.setCursor(0,0);
    lcd.print(" Running zone 2");
    lcd.setCursor(0,1);
    lcd.print(" Left to end");
    while(ReadKeypad()!= 'L');
    digitalWrite(relay_2, LOW);
    digitalWrite(relay_3, LOW);
}

void Radiant()

    {
    RadiantMain();
    }

void MenuD()
{
    lcd.clear();
    lcd.setCursor(0,0);
    lcd.print("Inside Menu D");

    while(ReadKeypad()!= 'L')
    {
        //Insert Task for Menu D here

    }
}

void MainMenuBtn()
{
    WaitBtnRelease();
    if(btn_push == 'U')
    {
        mainMenuPage++;
        if(mainMenuPage > mainMenuTotal)
          mainMenuPage = 1;
    }
    else if(btn_push == 'D')
    {
        mainMenuPage--;
        if(mainMenuPage == 0)
          mainMenuPage = mainMenuTotal;
    }

    if(mainMenuPage != mainMenuPageOld) //only update display when page change
    {
        MainMenuDisplay();
        mainMenuPageOld = mainMenuPage;
    }
}

char ReadKeypad()
{
  /* Keypad button analog Value
  no button pressed 1023
  select  741
  left    503
  up      326
  down    142
  right   0
  */
  keypad_value = analogRead(keypad_pin);

  if(keypad_value < 100)
    return 'R';
  else if(keypad_value < 200)
    return 'D';
  else if(keypad_value < 400)
    return 'U';
  else if(keypad_value < 600)
    return 'L';
  else if(keypad_value < 800)
    return 'S';
  else
    return 'N';

}

void WaitBtnRelease()
{
    while( analogRead(keypad_pin) < 800){}
}
//END MENU CODE

// Title: 2 zone Radiant Heat Controller
// Date:12/01/14
// Author: Chris Biblis (My First Adruino Project )

//RADIANT MAIN CODE STRTS HERE_________________________________________________________

// #include <LiquidCrystal.h>

// LiquidC//rystal lcd(8, 9, 4, 5, 6, 7);
// define some values used by the panel and buttons
int lcd_key     = 0;
int adc_key_in  = 0;
#define btnRIGHT  0
#define btnUP     1
#define btnDOWN   2
#define btnLEFT   3
#define btnSELECT 4
#define btnNONE   5
// read the buttons
int read_LCD_buttons(){
 adc_key_in = analogRead(0);
 // buttons when read are centered at these valies: 0, 144, 329, 504, 741
 // we add approx 50 to those values and check to see if we are close
 if (adc_key_in > 1000) return btnNONE;
 if (adc_key_in < 50)   return btnRIGHT;
 if (adc_key_in < 250)  return btnUP;
 if (adc_key_in < 450)  return btnDOWN;
 if (adc_key_in < 625)  return btnLEFT; //Changed value to 625 do to double read from select button Default is 650.
 if (adc_key_in < 850)  return btnSELECT;
 return btnNONE;
}
// Setup relay shield pin array.
int relayPin[] = {2, 3, 11, 12};
//int pinCount = 4;

// Set On/Off Differentials for collector/tank temperatures.
const int diffON = 5;
const int diffOFF = 2;

// Set Default Thermostat temperature
int setTemp = 60;
int setTemp2 = 60;

//Used for calibration
int offSet[] = {-2, -1, 0, 1, 2};

//Button Variables.
int select = 0;
int up = 0;
int down= 0;
int backLight = 10;
boolean BLbutton = false;

//void RadiantMain()//RadiantMain setup
{
 lcd.begin(16, 2);
 lcd.setCursor(0,0);
 //Introduction Screen
 lcd.print("2 zone");
 lcd.setCursor(0,1);
 lcd.print("Radiant floor");
 delay(2000);

  for (int thisPin = 0; thisPin < pinCount; thisPin++)
   { pinMode(relayPin[thisPin], OUTPUT);}

 }
// Read average voltage from sensors
int ReadSens(int x)
{
  int i;
  int sval = 0;
    for (i = 0; i < 10; i++)
    { sval = sval + analogRead(x); }
  sval = sval / 10;
  return sval;
}
// Calculate temperature in F from voltage of sensors.
int getTemp(int y)
{
  //Convert to Celcius
  float a = (((y / 1024.0) * 5000)/10)-273.15;
  //Convert Celcius to Fahrenheit
  float b = a * 9.0 / 5.0 + 32.0;
  return b;
}

void RadiantRun()//need RadiantRun loop
{
 // Get average Voltage
 int z1flr = ReadSens(1);//zone  1 floor temp
 int z2flr = ReadSens(2);//zone2 floor temp
 int z1line = ReadSens(3);//zone 1 return line temp
 int z2line = ReadSens(4);//zone 2 return line temp
 int pmp = ReadSens(5);
 // Get Temperatures & Apply OffSet { -2, -1 , 0, 1, 2 }
 int zone1floortemp = (getTemp(z1flr) + offSet[0]);
 int zone2floortemp = (getTemp(z2flr) + offSet[0]);
 int zone1linetemp = (getTemp(z1line) + offSet[0]);
 int zone2linetemp = (getTemp(z2line) + offSet[0]);
 int pump = (getTemp(pmp) + offSet[0]);

  //Backlight button selection...
  if (BLbutton == true){pinMode(backLight, INPUT);} //turn backlight off
    else{pinMode(backLight,OUTPUT);} //turn backlight on
 // Display screens
  if (select == 3){select = 0;}
  if (select == 0){
    lcd.clear(); lcd.setCursor(0,0);
    lcd.print("  Ambient Temp ");
    lcd.setCursor(6,1);
    lcd.print(zone1floortemp);
    lcd.print(" F");
}
  if (select == 1)
{
    lcd.clear(); lcd.setCursor(0,0);
    lcd.print("Set Ambient To:");
    lcd.setCursor(6,1);
    lcd.print(setTemp);
    lcd.print(" F");
}
  if (select == 2)
{
    lcd.clear(); lcd.setCursor(0,0);
    lcd.print("Z1F ");
    lcd.print(zone1floortemp);
    lcd.print("F");

    lcd.setCursor(9,0);
    lcd.print("Z2F ");
    lcd.print(zone1floortemp);
    lcd.print("F");

    lcd.setCursor(9,1);
    lcd.print("Z2L ");
    lcd.print(zone2linetemp);
    lcd.print("F");

    lcd.setCursor(0,1);
    lcd.print("Z1L ");
    lcd.print(zone1linetemp);
    lcd.print("F");

}

lcd_key = read_LCD_buttons();  // read the buttons
 switch (lcd_key)
 {
   case btnSELECT:{ BLbutton = !BLbutton; delay(100); break; }
   case btnUP:    { setTemp++; select = 1; delay(100); break; }
   case btnDOWN:  { setTemp--; select = 1; delay(100); break; }
   case btnRIGHT: { select++; delay(100); break; }
   case btnLEFT:  { select--; delay(100); break; }
 }

// only 1 zone at a time_____________NOT IMPLEMENTED YET____________

// zone 1
// if floor temp zone 1 = less then set temp then open valve zone 1 turn on pump
  // if(z1flr <= (setTemp + diffOFF))
  // {digitalWrite(relayPin[3], HIGH);} // pump on
  // {digitalWrite(relayPin[12], HIGH);} // valve 1 on
  // {digitalWrite(relayPin[11], LOW);} // valve 2 off

// if floor temp zone 1 = set temp then close valve zone 1 turn off pump
  // if(z1flr = (setTemp + diffOFF))
  // {digitalWrite(relayPin[3], LOW);} // pump off
  // {digitalWrite(relayPin[12], LOW);} // valve 1 off

// // if floor temp zone 2 = less then set temp and  zone 1  = less then set temp zone 2 valve off
//   if(z1flr <= (setTemp + diffOFF) && (z1flr < (setTemp)))
//   {digitalWrite(relayPin[11], LOW);} // valve 2 off

// zone 2
// if floor temp zone 1 = less then set temp then open valve zone 1 turn on pump
  // if(z1flr <= (setTemp + diffOFF))
  // {digitalWrite(relayPin[3], HIGH);} // pump on
  // {digitalWrite(relayPin[11], HIGH);} // valve 2 on
  // {digitalWrite(relayPin[12], LOW);} // valve 1 off

// if floor temp zone 1 = set temp then close valve zone 1 turn off pump
  // if(z1flr = (setTemp + diffOFF))
  // {digitalWrite(relayPin[3], LOW);} // pump off
  // {digitalWrite(relayPin[11], LOW);} // valve 2 off

// if floor temp zone 1 = less then set temp and  zone 2  = less then set temp zone 1 valve off
  // if(z1flr <= (setTemp + diffOFF) && (z1flr < (setTemp)))
  // {digitalWrite(relayPin[12], LOW);} // valve 1 off

  delay(500);

}
//RADIANT MAIN CODE ENDS HERE___________________________________________________

//relay pinouts
//Digital 12 – controls RELAY 1 COM1 pin zone 1 valve
//Digital 11 – controls RELAY 2 COM2 pin zone 2 valve
//Digital 3 – controls RELAY 3 COM3 pump
//Digital 2 – controls RELAY 4 COM4 open

//sensors:
//flr1 = floor temp zone 1 sensor
//flr2 = floor temp zone 2 sensor
//pmp = pump OFF/ON
//z1= zone 1 line temp sensor
//z2 = zone 2 line temp sensor

what is the problem? ... what were you expecting to happen? ... what actually happened?

explanation at beginning of code

"When I select MenuC 'Run main' it executes to RadiantMain prints test and then returns to menu options again". If this is what you means "explanation at beginning of code", this merely described what your code does, it doesn't explain what you are expecting it to do. Your sketch works exactly as how you code it, that it, MenuC() called RadiantMain(), which doesn't do much other than setting up some pins to OUTPUT, and then back to main menu. If it not what expecting it to do, you need to be more elaborate on what it support to do...

Changed the names in the menu from MenuA to 'Zone1' and MenuB to 'Zone2' and MenuC to 'Radinat'. Zone1 and Zone2 work as expected. Using menu selection 'Radiant' to call RadiantMain which is the second sketch.
The menu sketch will run as a stand-alone.
The RadiantMain sketch will run as a stand-alone. I need the second sketch to run complete when I select the  Radiant menu selection.
The RadiantMain code starts after the //END MENU CODE.

Your code for RadiantMain is:
void RadiantMain()

{
 //Serial.println("test");

 lcd.begin(16,2);
 lcd.setCursor(0,0);
 //Introduction Screen
 lcd.print("Solar Collection");
 lcd.setCursor(0,1);
 lcd.print("& Radiant Heater");
 delay(2000);

   Serial.println("test");
   //CODE STOPS HERE LOOPS BACK TO 'void MainMenuDisplay()'

  for (int thisPin = 0; thisPin < pinCount; thisPin++)
   { pinMode(relayPin[thisPin], OUTPUT);}
 }

You say "CODE STOPS HERE" in a comment, but all it does after printing "test" is set some pins to output mode. Is that not happening? Are you expecting something else?
If you want some of the other functions (like RadiantRun) to do something then they must be called from RadiantMain or elsewhere.

I need to be able to use the menu sketch to run 3 different functions. MenuA &MenuB to manually run the system in manual mode and a third menu item (MenuC) to run the 2nd sketch in auto mode.

You need to make that happen by calling the appropriate functions in "the second sketch" when the appropriate menu button is pressed.
Merely putting the code into the same file doesn't accomplish this.
Exactly what you want to happen "in auto mode" isn't clear to me. You need to be clear in your own mind what that is. For example, taking a reading, adjusting the water valves, waiting a minute, and doing it again.
Once you are clear what you want to happen in that mode, you call the appropriate functions to achieve that.
You haven't answered the questions in the comments under your main question. Without those answers no-one can help you.

The second sketch starts where it says //START RUN RADIANT MAIN CODE. The menu sketch and the Radiant Main are 2 separate sketches written by 2 different developers. They do run as stand-alone sketches.  I modified the menu sketch to operate my relays (MenuA and MenuB) for the manual mode it works fine. I need to be able to use the menu sketch to run 3 different functions. MenuA &MenuB to manually run the system in manual mode and a third menu item (MenuC) to run the 2nd sketch in auto mode.

@HaroldVermillion What do you mean with "2 separate sketches"? One Arduino can only run exactly one sketch, not more. You showed us one code. This code needs to handle everything, that the Arduino should do. Or do you try to ask how to combine 2 sketches?

I need to combine the 2 sketches together into one code

I am using a D1 ROBOT LCD KEYPAD shield. A1 through A5 are connected to temp sensors. 4 relay shield controls 2 water valves and a pump, 4th relay is unused. the menu sketch controls the 2 water valves with MenuA and MenuB. I need MenuC to run the second sketch which reads sensors sets temps and controls 2 water valves and a pump.

@HaroldVermillion See amended answer.

@HaroldVermillion why are you placing important information into a comment? ... it does not belong there ... this site is not a forum ... please place all info into your question at top of this page ... people read the question and move on when they see lack of information


text:
Why a Arduino UNO R3 board can use in Windows 10 but can't be used in My Macbook Air(M1)?
In Windows 10, everything is well. But when I use it in my macbook, it even can't recognize the port.
This is official description about driver.

First check if you have installed the driver.

It may make a difference if you're talking about a clone or an original. They don't all use the same transceiver. If you've been testing with anything besides the computer connected to the UNO, remove it.

I use a clone board, but the components is consistent with the original, use a Atmel Mega16U2 as usb-to-UART driver. According to official Web resource, this board don't need a software driver.

What version of OS X are you using?

I use Ventura 13.1.

No driver necessary on MacOS which is essentially derived from UNIX/Linux.  It should be plug & play.
It looks like the Air is not recognizing the Uno.
Try opening a Terminal console and type ls /dev/tty.*
You should get a list of 'Serial Devices' connected, try the 'ls /dev/tty.* with the Uno plugged and unplugged, any difference should reveal the name of Uno port.  If no difference I would suspect the cable you are using to connect the Uno.  If you are able to identify the Uno port that same name should be selectable in the Arduino IDE when you open it.
Just realized Stack Exchange is not showning my answer correctly 'ls /dev/tty.' should have an asterisk after the 'dot'.

Before I asked, I have try check Terminal console output use the method which you say. Unfortunately there is no difference. Only have three COM port show in my description.  I don't think the cable is broken, because it's usable in Windows 10. I upload some code, and it performs well.

Okay, then the issue must lie with your macbook Air, I usually use a Windows 7/10 or Linux laptop with Arduino, but when I saw your post I pulled out my ancient Macbook pro, plugged in my Uno which works fine on Win7/10 & Ubuntu and voila, the serial device appears with ls /dev/tty.*  I looked up the specs on the Air M1, it has 2 Thunderbolt / USB-C 4 ports, my next step would be to look at the way they are configured if I was in your shoes.  If you have another device headset, camera etc try plugging that into the port and see what it does with ls /dev/tty.*

When i plug a STM32F411RE nucleo board, in terminal us ls /dev/tty.* I will see new port have the name of tty.usbmodem23103. I think it's time to buy a new one to test whether is My mac's problems.


text:
Will an Arduino Nano work instead of Teensy 3.2?
I hope this is ok to post here and I appreciate any suggestions or help and opinions/facts to make this work.
First off I’ve Never programmed an Arduino device!
I was looking at this project:
https://learn.adafruit.com/pinball-controll-ipad/duo-pinball-teardown
I would like to use the cheaper Arduino nano type board, and use the provided code to program it.
I have the same device (pinball Duo controller as in the project) just wanted to know if I attempt this will the atmega328P Nano achieve the same results?
Thank you,
Shlade

No, Nano doesn't have native USB so it can't emulate the keyboard like teensy does. You can use Arduino Micro/Leonardo/Pro Micro or similar.

@KIIV ;-) I'd love to see answers written as answers... Isn't this site supposed to be helpful right on the front page?

No, you can't use Adruino Nano, because in this project the Teensy board has been used as an USB Keayboard and Nano has separate communication chip (FTDI or CH430) that can't emulate USB keyboard.
However you don't have to use Teensy boards, you can use any board that has native USB support. For example Arduino Micro, Arduino Pro Micro, Arduino Leonardo. All are using Atmega32u4.
You can probably find many more boards with different MCUs (usually they don't have any dedicated communication chip). I think for example RPi Pico, Seeed studio xiao BLE (on this one you might be able to pull even bluetooth mouse emulation), ...
If you want further infos here is the pinmap for you :


text:
How to connect to AWS iot?
I am trying to connect esp8266-12f to aws iot core following this tutorial. Below is my code.
main.cpp
#include <Arduino.h>
#include <ESP8266WiFi.h>
#include "config.h"
#include <WiFiClientSecure.h>
#include <PubSubClient.h>
#include <ArduinoJson.h>

#define wifi_status_led_pin 14
#define server_status_led_pin 12

using string = std::string;

#define AWS_IOT_MQTT_PORT 8883

WiFiClientSecure net;
BearSSL::X509List cert(AWS_CERT_CA);
BearSSL::X509List client_crt(AWS_CERT_CRT);
BearSSL::PrivateKey key(AWS_CERT_PRIVATE);
PubSubClient client(net);

void configAWS()
{
  // net.setInsecure();
  net.setTrustAnchors(&cert);
  net.setClientRSACert(&client_crt, &key);
  client.setServer(AWS_IOT_ENDPOINT, AWS_IOT_MQTT_PORT);

  while (!client.connected(THINGNAME))
  {
    Serial.println("Connecting to AWS");
    digitalWrite(server_status_led_pin, HIGH);
    delay(500);
    digitalWrite(server_status_led_pin, LOW);
    delay(500);
  }

  if (client.connected() && client.connect(THINGNAME))
  {
    client.subscribe(AWS_IOT_SUBSCRIBE_TOPIC);
    client.setCallback(messageHandler);
    Serial.println("AWS IoT connected!");
    digitalWrite(server_status_led_pin, HIGH);
  }
}

void setup() {
  Serial.println("setup");
  pinMode(wifi_status_led_pin, OUTPUT);
  pinMode(server_status_led_pin, OUTPUT);
  Serial.begin(9600);
  WiFi.mode(WIFI_STA);
  WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
  while (WiFi.status() != WL_CONNECTED)
  {
    Serial.println("wifi connecting");
    digitalWrite(wifi_status_led_pin, HIGH);
    delay(300);
    digitalWrite(wifi_status_led_pin, LOW);
    delay(300);
  }
  digitalWrite(wifi_status_led_pin, HIGH);
  Serial.println("connected network");
  configAWS();
  pinMode(door1_open_pin, OUTPUT);
  pinMode(door1_status_pin, INPUT);
  door1_previous_state = digitalRead(door1_status_pin);
}

void loop() {
}

config.h
#include <pgmspace.h>

#define SECRET
#define THINGNAME "THINGNAME " // change this

const char WIFI_SSID[] = "mywifi";     // change this
const char WIFI_PASSWORD[] = "password"; // change this
const char AWS_IOT_ENDPOINT[] = "XXXXXXXXX-ats.iot.us-east-2.amazonaws.com";

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

// Device Certificate
static const char AWS_CERT_CRT[] PROGMEM = R"KEY(
-----BEGIN CERTIFICATE-----
my cert
-----END CERTIFICATE-----
)KEY";

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

The cert should have no problem since I also tried esp32 with same cert and thing and it success. But in esp8266, I cannot connect to aws and keep logging "Connecting to AWS".
I am not sure it matters, but I am using platformio and only board esp12e instead of 12f is avaliable.
my ini file below,
[env:esp12e]
platform = espressif8266
board = esp12e
framework = arduino
lib_deps =
    bblanchon/ArduinoJson@^6.20.1
    knolleary/PubSubClient@^2.8
    ESP8266WiFi @ ^1.0


text:
Timer 1 "Set on Compare Match" in Normal Mode - Not working
I'm using the hardware timers on the 328 for phase angle control of a triac with zero-crossing detection. I am encountering some strange behavior with the "Set on Compare Match" feature not working as expected on Timer1. I am attempting to replicate the red "gate" trace here: https://playground.arduino.cc/Main/ACPhaseControl/, but with my own implementation in code.
Before building the triac and zero-cross detection circuit, I am using another timer (Timer0) to simulate a 120Hz AC square wave (2x the 60Hz frequency because the double crossing pulse will arrive twice a cycle).
The output of the synthesized AC square wave is fed into an external interrupt pin (INT0) with a jumper. The correct functionality of the program is a short pulse to fire the triac at some phase delay relative to the zero crossing interrupt event (another example: https://www.homemade-circuits.com/wp-content/uploads/2020/07/half-phase-control.jpg)
I configure Timer 1 in normal mode, and define compare levels for both OCR1A and OCR1B. OCR1A is the "phase delay" from zero crossing at which to fire the triac, and OCR1B sets the duration of the pulse used to fire the triac. In my code, Method 1 is working and producing the intended output, while Method 2 is not working (output is always ON). For brevity, I am highlighting the differences between the two methods below, and the rest of the code is the same.
Method 1:

Set OC1A to do nothing on compare (normal port operation) TCCR1A=0;
"Manually" turn on the pin inside of the interrupt handler for output compare A. It will later be turned off in the interrupt handler for output compare B: PORTB=(1<<PORTB1);

This produces the following (correct) output. In the oscilloscope screenshot, the yellow trace is the simulated AC square wave, and the green trace is to be the gate voltage on the triac.
https://i.stack.imgur.com/tpSAw.png
Method 2:

Enable the OC1A "Set at compare match" bit in the TCCR1A register:
TCCR1A |= (1 << COM1A1) | (1 << COM1A0);
In theory, this means that I don't have to manually turn on the pin inside the interrupt handler for compare A, because it's already been turned on for us by the Compare Match Output Unit.

https://i.stack.imgur.com/45tFA.png
Note that in both methods, I still need to "manually" turn off the pin inside the output compare B interrupt handler because OC1A and OC1B are not the same physical pin: PORTB=0;
In Method 2, the pin is held ON, with no indication that the interrupt handler for output compare B is doing anything. My mental model of the port is that as long as the bit in the data direction register is set for that port, both the output compare unit and CPU can write to the pin. It appears that the pin is always being held ON, even after it is turned OFF by the CPU. Does the compare unit lock/latch the pin until the next clock cycle, or am I missing something else? Some tips here would be much appreciated.
I can prove that the output is indeed connected to OC1A because OC1A is PB1 which is connected to the oscilloscope and is being toggled in Method 1. I have vertically scaled OC1A (green) for readability against OC0A.
I have been referencing Section 13 of https://www.sparkfun.com/datasheets/Components/SMD/ATMega328.pdf for most of this task.
My code below for Method 1 is presented. To get Method 2, toggle the comments on the indicated lines.

#define F_CPU 16000000L

#include <avr/io.h>
#include <avr/interrupt.h>

/*
For reference:
OCR1A = turn_on_timer_level
OCR1B = turn_on_timer_level + pulse_width

*/

int timer0_ac_sim_val = 64;    // Measured in clock ticks with prescale=1024
int turn_on_timer_level = 500;    // Measured in clock ticks with prescale=64
int pulse_width = 200;    // Measured in clock ticks with prescale=64

ISR(INT0_vect){
    // ISR at output compare A of timer 0 turns on timer 1 - simulates what happens when a zero crossing rising edge is detected on a 120Hz AC sine wave
    TCCR1B |= (1<<CS11) | (1<<CS10);
    TCNT1 = 0;
}

ISR(TIMER1_COMPA_vect){
    // ISR at output compare A of timer 1 turns on the pin
    PORTB = (1<<PORTB1);   // Turn on the pin COMMENT FOR METHOD 2
}

ISR(TIMER1_COMPB_vect){
    TCCR1B = 0; // Turn off the timer
    PORTB = 0;  // Turn off the pin
}

int main(){

    // Timer 0 setup for a 120Hz square wave on OC0A
    DDRD |= (1<<PD6);

    TCCR0A = 0x0;
    TCCR0A |= (1<<COM0A0) | (1<<WGM01);  // Set the output to toggle on compare

    TCCR0B = 0x0;
    TCCR0B |= (1<<CS02) | (1<<CS00);     // Configure with a prescale of 1024 and start clock

    OCR0A = timer0_ac_sim_val;  // Calculate this value for a 120Hz square wave, doesn't change.

    // Enable external interrupt 0 to trigger on a rising edge - set the External Interrupt Control Register
    EICRA |= (1<<ISC01) | (1<<ISC00);
    EIMSK |= (1<<INT0);

    // Global interrupt enable
    sei();

    // Timer 1 setup
    DDRB |= (1<<PORTB1);

    TCCR1A = 0x0;   // No pin action on output compare
    // TCCR1A |= (1 << COM1A1) | (1 << COM1A0);    // Set OC1A on compare match UNCOMMENT FOR METHOD 2

    TCCR1B = 0x0;   // Disable clock

    OCR1A = turn_on_timer_level;  // Delay between OC0A rise and OCR1A trigger
    OCR1B = turn_on_timer_level + pulse_width;   // Delay between OC0A rise and OCR1B trigger

    // Enable timer 1 interrupts
    TIMSK1 |= (1<<OCIE1A) | (1<<OCIE1B);

    while(1){
    };
}

My mental model of the port is that as long as the bit in the data direction register is set for that port, both the output compare unit and CPU can write to the pin.

Your assumption is incorrect. See section 13.11.1 of the datasheet you linked.

If one or both of the COM1A1:0 bits are written to one, the OC1A output
overrides the normal port functionality of the I/O pin it is connected to.

Thus, the "normal" functionality being overridden precludes your changing the pin yourself. You would need to set those bits to zero in the ISR to reclaim the use of the port, and set them back to one when required.

Perfect! I missed that in the datasheet when I was reading. Thanks so much.

For those who might be interested, after fixing the problem I decided to implement the same functionality using Fast PWM mode instead of CTC mode. In trying to debug my original issue, I came across a similar post, to which one of the answers was:
https://arduino.stackexchange.com/a/30529/89096

The PWM modes manage pin at both ends of the cycle.
The point of the CTC modes is that they manage the pin only at one end of the >count, but allow you to manage the other end explicitly.
To manage both ends explicitly, you use normal mode.

I didn't fully realize what that meant until now, but it clicked. In PWM mode, the hardware timer takes care of the pin toggling for us, on both sides of the waveform. We would use Normal or CTC modes if we wanted to do manage one or both sides of the waveform differently. But my application fits perfectly in the Fast PWM category, so I decided to implement that as well. This saves an ISR by not making the CPU "manually" toggle the pin on and off each time. The only difference is that the output is on OC1B (PORTB2) now instead of OC1A (PORTB1).
#define F_CPU 16000000L

#include <avr/io.h>
#include <avr/interrupt.h>

int timer0_ac_sim_val = 64;    // Measured in clock ticks with prescale=1024
int turn_on_timer_level = 400;    // Measured in clock ticks with prescale=64
int pulse_width = 100;    // Measured in clock ticks with prescale=64

ISR(INT0_vect){
    // ISR at output compare A of timer 0 turns on timer 1 - simulates what happens when a pulse is received from the zero crossing detector
    TCCR1B |= (1<<CS11) | (1<<CS10) | (1<<WGM13) | (1<<WGM12);
    TCNT1 = 0;
}

ISR(TIMER1_COMPA_vect){
    // ISR at output compare A of timer 1 turns on the pin
    TCCR1B = 0; // Turn off the timer
}

int main(){
    // Timer 0 setup for a 120Hz square wave on OC0A
    DDRD |= (1<<PD6);

    TCCR0A = 0x0;
    TCCR0A |= (1<<COM0A0) | (1<<WGM01);  // Toggle mode - non-PWM

    TCCR0B = 0x0;
    TCCR0B |= (1<<CS02) | (1<<CS00);     // Configure with a prescale of 1024, start clock

    OCR0A = timer0_ac_sim_val;

    // Enable external interrupt 0 to trigger on a rising edge - set the External Interrupt Control Register
    EICRA |= (1<<ISC01) | (1<<ISC00);
    EIMSK |= (1<<INT0);

    // Enable interrupts
    sei();

    // Timer 1 setup - 16 bit resolution with a prescale of 8 gives a max period of 1/(16e6/8/65536) = 32.78ms
    DDRB |= (1<<PORTB2);

    // Set WGM12 (CTC) to 1 and start the timer with a prescaler of 1024   -> This starts the timer in CTC mode
    TCCR1A = (1<<COM1B1) | (1<<COM1B0) | (1<<WGM11) | (1<<WGM10);  // Set COM1B1 and COM1B0 to 1 for inverting mode. For fast PWM set WGM11 and WGM10
    TCCR1B = 0x0;   // Start with clock disabled

    OCR1A = turn_on_timer_level + pulse_width;
    OCR1B = turn_on_timer_level;

    // Enable timer 1 interrupts
    TIMSK1 |= (1<<OCIE1A);

    while(1){

    }


text:
Using internal voltage reference for sensor
i am using 3.7~4.2V lithium battery. I am using internal voltage reference to read constant battery voltage as we know that the battery voltage level depletes overtime. The problem is that my sensor (mini solar panel) reads max value under little light and does not go beyond that level no matter how much light falls onto it in the later stage.

Comments have been moved to chat; please do not continue the discussion here. Before posting a comment below this one, please review the purposes of comments. Comments that do not request clarification or suggest improvements usually belong as an answer, on [meta], or in [chat]. Comments continuing discussion may be removed.

The problem is that my sensor (mini solar panel) reads max value under little light and does not go beyond that level no matter how much light falls onto it in the later stage.

Open voltage is not a good way to read the light level hitting a solar panel in this situation. Much better is to measure the current generated by the solar cell by adding a resistor across it here...

The value of the resistor can be found using...
V=IR
... where ...
V=1.1 volts
I=the maximum current the solar cell can generate in full light
If you do this, then you can read the A1 pin using the 1.1V ref and you will be able to measure the full range of light conditions using the solar cell with simple Arduino code like this..
analogReference(INTERNAL);  // a built-in reference, equal to 1.1 volts
int v=analogRead(A1);       // Returns value 0-1023 representing light level

PS: Note if you measure the battery voltage with a divider as shown, you will be drawing current (about 0.8 milliamps when the battery reaches its minimum voltage) ALL THE TIME - even when the circuit is off. You do not want to do this with a lithium battery since under-voltaging it can potentially cause permanent damage to it. You really should heed my answer to your other question here.
PPS: It is usually best to ask your real question directly rather than asking a bunch of questions that are synthetic and reflect problems you think you have rather than the problems you actually do have. Your supplied code and drawings should match the thing you are asking and the thing you are actually working on (and each other!). It is often the case that the problem is not where you think it is, and so showing code and drawings that do not reflect what is really going on just wastes people's effort and does not ultimately help you solve your real problem. :)

"Then how do i reduce my battery voltage to Vref?" The best way to measure the voltage of your power source is by measuring the 1.1V ref against Vcc as suggested in my answer to your other question and the article linked there.

" If i connect resistor on the solar end, the current drawn would increase and it would result into slow battery charging which again is not a suitable option for the specific project. " You question is about using a solar cell as a sensor to measure the light level. This answer tells you a good way to do that. If you are using the solar cell to charge the battery, then this is not represented in the question, in the code, or in the drawing so it is hard for us to help you with that! :) And note that charging a battery is a very different thing than using it as a light sensor.

These are all very different things that what is asked in this question and your others. Do note that charging a lithium battery is non-trivial and is not as easy as just connecting a solar cell to it. Check out https://batteryuniversity.com/article/bu-409-charging-lithium-ion for some info.

Your code above has many problems and does not compile. Best way to solve this problem (or any problem) is to find the minimum code and circuit that reproduces the problem and post that, along with (1) what you want to have happen, (2) what actually happens with the supplied code and circuit. For me, very often just systematically following these steps will actually end up with me solving the problem myself - but if not then at least you make it easy for other people to help you when you post it.

For example, in printVolts(), you use the variable val even though it does not exist here.   My guess is that in your code you are unintentionally switching between the 5V and 1.1V references because you are sometimes using the Arduino functions sometimes changing the registers directly. Also note  that with your current resistor values that you can not measure the battery voltage with the 1.1V ref because the output voltage can be higher than 1.1V even at the lowest possible battery voltage.


text:
1MHZ Attiny85 RF with MANCHESTER library
I'm trying to set up a transmitter made by the following components :

Attiny85 (I need 1MHZ speed)
Cheap 433mhz transmitter (FS1000A)

The library I am using is the Manchester library GitHub.
The attiny85 and the transmitter are powered with regulated 5V.
I set up 1MHZ when burning the bootloader for the tiny.
I am successful at transmitting with 8 AND 16MHZ with my Attiny85, however, 1MHZ seems to malfunction.
For 1MHZ on the tiny, this line need to be added in order to adjust timings :
man.workAround1MhzTinyCore();

Here is the complete code :
#include <Manchester.h>
/*
  Manchester Transmitter example
  In this example transmitter will send one 16 bit number
  per transmission.
  Try different speeds using these constants, your maximum
  possible speed will depend on various factors like transmitter
  type, distance, microcontroller speed, ...
  MAN_300 0
  MAN_600 1
  MAN_1200 2
  MAN_2400 3
  MAN_4800 4
  MAN_9600 5
  MAN_19200 6
  MAN_38400 7
*/
#define TX 2 //pin where your transmitter is connected

uint8_t transmit_data = 11;
void setup() {
  man.workAround1MhzTinyCore();
  //pinMode(RX, OUTPUT);
  man.setupTransmit(TX, MAN_300);
  pinMode(1, OUTPUT);
}
void loop() {
  digitalWrite(1, HIGH);
  man.transmit(transmit_data);
  delay(100);
  digitalWrite(1, LOW);

  delay(200);
}

Someone else has/had this issue Can't transmit on @1MHZ attiny85, and i don't know if it has been fixed or not. I am unsure if the library is still updated, and if this issue isn't with the library itself.
Does anyone have any leads or fix for that issue ?
That would greatly help, Thanks

The comments in the library code suggest, that this is a problem with the core. You can search in the issues of the core on github or open your own issue for it to find out if it is fixed. Though - as you report it not working without the workaround - I don't think it is fixed.  Does the workaround not work for you?

Hi, thanks for answering quickly, no, the workaround does not work for me. Do you mean the core of the tiny library or the core of the Manchester library ?

A core in the Arduino world is the support package for specific groups of boards/microcontroller (as installed from the board manager). So it is the Tiny core and the Manchester library, not vice versa. So yes, with core I mean the Tiny core (or whatever core you have installed for the Attiny)

The linked issue of the Manchester library also states, that calls to delay() does not work correctly (a value of 5000ms giving only 1s delay). Does this also happen for you? Please also test delayMicroseconds() since that is the function used in the Manchester library

Ok thanks for the tip, I managed to test it and it would seem to be working correctly, I get approximately 5 seconds every time, with delay() and delayMicroseconds()

Ok funny story, I think I found a solution, not sure why, but :
My setup (the same) :

Attiny85 (1MHZ (set on bootloader))
Cheap 433mhz transmitter (FS1000A)
Attiny microcontrollers library

When burning the bootloader with 1MHZ, and uploading sketch, it would seem that removing the line man.workAround1MhzTinyCore(); makes it work.
Without the line it's working, and with the work around it is NOT
Voila !