message:
How to connect Arduino Nano to Thermal Printer via serial connection

I have a generic Arduino Nano board that uses the old bootloader. I have the printer and the Arduino connected like so:

[![enter image description here][1]][1]

This is my code:

    #include "Adafruit_Thermal.h"

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

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

    SoftwareSerial mySerial(RX_PIN, TX_PIN); // Declare SoftwareSerial obj first
    Adafruit_Thermal printer(&mySerial);     // Pass addr to printer constructor
    // Then see setup() function regarding serial & printer begin() calls.

    // Here's the syntax for hardware serial (e.g. Arduino Due) --------------
    // Un-comment the following line if using hardware serial:

    //Adafruit_Thermal printer(&Serial1);      // Or Serial2, Serial3, etc.

    // -----------------------------------------------------------------------

    void setup() {

      // This line is for compatibility with the Adafruit IotP project pack,
      // which uses pin 7 as a spare grounding point.  You only need this if
      // wired up the same way (w/3-pin header into pins 5/6/7):
      // pinMode(BUILTIN, OUTPUT); digitalWrite(7, LOW);

      // NOTE: SOME PRINTERS NEED 9600 BAUD instead of 19200, check test page.
      mySerial.begin(9600);  // Initialize SoftwareSerial
      //Serial1.begin(19200); // Use this instead if using hardware serial
      printer.begin();        // Init printer (same regardless of serial type)

      // The following calls are in setup(), but don't *need* to be.  Use them
      // anywhere!  They're just here so they run one time and are not printed
      // over and over (which would happen if they were in loop() instead).
      // Some functions will feed a line when called, this is normal.

      // Font options
      printer.setFont('B');
      printer.println("FontB");
      printer.println("ABCDEFGHIJKLMNOPQRSTUVWXYZ");
      printer.setFont('A');
      printer.println("FontA (default)");
      printer.println("ABCDEFGHIJKLMNOPQRSTUVWXYZ");

      printer.sleep();      // Tell printer to sleep
      delay(3000L);         // Sleep for 3 seconds
      printer.wake();       // MUST wake() before printing again, even if reset
      printer.setDefault(); // Restore printer to defaults
    }

    void loop() {
    }

When I run my code or reset no prints get sent to the print.

Here's what I've tried.

 - Ensure power is on on both devices
 - Try baud rate 19200
 - Swop Tx and Rx cables around
 - Tried D5 and D6 for Tx and Rx

Any help would me much appreciated.

  [1]: https://i.stack.imgur.com/ZJgdT.png

body:
Your additional info about your printer tells me that it has a Bluetooth and a USB interface - but I can not see any other serial connection port.

So there is no way connecting this printer as-is to the arduino nano by some digital port pins.

You may decide to either buy the Thermal printer offered by Adafruit our search for a Thermal printer that clearly states that is has a "Serial Interface" or "Serial RS232 Interface" - no matter if that comes with "TTL" or not like the Adafruit printer.

The printer is intended to be connected to a USB host port (of an PC or RPi or so) or via Bluetooth (to an PC or Android phone).

It may offers a virtual serial interface over both USB and Bluetooth, but that is a speculation.

*It may be possible to hack your printer. I think the Adafruit printer was modded by Adafruit. They may have bought a stock-printer and added the connector for the TTL interface. This may also be possible with the printer you have, but that is not in the scope of your question and highly speculative.*


sender: user

message:
How to configure watchdog for the arduino Nano 33 BLE Sense board?

For the arduino Nano 33 BLE Sense board, the standard `avr/wdt.h` is not available. And it seems that no standard library provides it. How to use the watchdog system for this board ? I found no full information about it.

I've found the page [https://www.mysensors.org/apidocs/group__avr__watchdog.html][1] which allow to configure the reboot mode. And it works. But no way to configure the interruption mode with `ISR()` function. Moreover, there's no explanation about the manipulation of used register/variables for any fine configuration.

  [1]: https://www.mysensors.org/apidocs/group__avr__watchdog.html

Simple code example with regular asynchronous stuff using the watchdog ISR() mechanism. It which works well with ATmega328 (e.g.UNO). But I do not find equivalent configuration for the Nano 33 BLE using the nRF52840.

```C
# include <avr/wdt.h>

volatile byte led;
int k;

ISR(WDT_vect) {
  Serial.println("Asynchronous stuff in ISR() function");
  digitalWrite(LED_BUILTIN,led);
  led=!led;
}

void setup() {
  pinMode(LED_BUILTIN,OUTPUT);
  led=0;

  Serial.begin(9600);
  while(!Serial) {}
  Serial.println("== R E B O O T ==");

  WDTCSR = ( 1 << WDE ) | ( 1 << WDCE );
  WDTCSR = ( 1 << WDP2 ) | ( 1 << WDP0 ) | ( 1 << WDIE ) ; // Interruption and timeout  1/2 s
}

void loop() {
  Serial.print("Loop #");
  Serial.println(k);
  if (k++%2) {
    Serial.println("Some stuff (even branch)");
    delay(1200);
  }
  else {
    Serial.println("Some stuff (odd branch)");
    delay(4800);
  }
}
```
Thks.

sender: assistant

body:
In fact, for the RF52940, I'm not sure that the watchdog can provide the needed interruption mechanism despite it exists the INTENSET bit for interruption according to the chipset doc https://content.arduino.cc/assets/Nano_BLE_MCU-nRF52840_PS_v1.1.pdf). But the good way is for sure the use of timers (and one can use more than just one, quite good).

For a similar behaviour as the code given for the UNO before, here is the code one can write for the Nano BLE using a timer interrupt (see https://github.com/khoih-prog/NRF52_MBED_TimerInterrupt for full and usefull doc).

```C
#include "NRF52_MBED_TimerInterrupt.h"

volatile byte led;
volatile uint32_t count=0;
NRF52_MBED_Timer myTimer(NRF_TIMER_1);
unsigned k=0;

void myHandler() {
  digitalWrite(LED_BUILTIN,led);
  led=!led;
  count++;
}

void setup() {
  pinMode(LED_BUILTIN,OUTPUT);
  led=0;

  Serial.begin(9600);
  while(!Serial) {}
  Serial.println("== R E B O O T ==");

  if (myTimer.attachInterruptInterval(500*1000, myHandler)) // each 1/2 second
    Serial.println("myTimer launched");
  else
    Serial.println("Can not set the timer");
}

void loop() {
  Serial.print("Loop #");
  Serial.print(k);
  Serial.print(" and nb times in Handler : ");
  Serial.println(count);
  if (k++%2) {
    Serial.println("Some stuff (even branch)");
    delay(1200);
  }
  else {
    Serial.println("Some stuff (odd branch)");
    delay(4800);
  }
}
```


message:
an lcd with I2C is not recognized by esp32

I have a NodeMCU esp32-s board and I'm trying to connect My 16x2 lcd with PCF8574T I2C bus to the esp32 , the problem is that the lcd doesn't show anything and the WireScan sketch can't recognize the lcd too,but when I use arduion uno ,it's recognized and work perfectly ,I hope somebody can help me,the schematic for the connection is :
[![enter image description here][1]][1]

the schematic for the connection of the lcd with the bus is below with the bus module part number [![enter image description here][2]][2]:

  [1]: https://i.stack.imgur.com/FjBC1.png
  [2]: https://i.stack.imgur.com/0NXcS.png

body: You can run the PCF8574 on 5V and the EXP on 3V3 just be sure the I2C is pulled up to the 3V3 and NOT the 5V. I do this a lot and have never had a problem. The reason it works is the bus is driven by open collector/drain drivers which do not source any voltage.


message:
delayMIcroseconds and micros execution time not explainable

i just experimented with the timing accuracy of my Arduino Uno R3 using this code:

    unsigned long beginTime;
    unsigned long endTime;

    void setup() {
      Serial.begin(9600); // open a serial port
    }

    void loop() {
      beginTime = micros();
      delayMicroseconds(200);
      endTime = micros();
      delay(500);
      Serial.println(endTime-beginTime);
      delay(500);
    }

The results I got are (just an excerpt):
```
200
204
200
200
204
204
204
200
212
208
212
204
204
```
I tried to understand this behavior, read this link [Can I make delayMicroseconds more accurate?][1].

Due to the timing of `micros` (4 µs) I would understand values between 200 and 208. **But why do I get occasional values of 212 microseconds?** I'm kinda curious, since I bought the Arduino because of bare-metal programming and bounded execution times.

  [1]: https://arduino.stackexchange.com/questions/37387/can-i-make-delaymicroseconds-more-accurate

body:
The Arduino core uses hardware Timer0 with its ISR (Interrupt Service Routine) for timekeeping. While `delayMicroseconds()` directly uses the value of the hardware timer, `delay()` and `millis()` are handled by the ISR. It will be called regularly.

If the ISR is getting executed during your measurement, then the execution time of the ISR will add to the execution time of your measured code. Thus you get a higher count occasionally.

To prevent this you can either deactivate all interrupts (via `noInterrupts()`) or deactivate this specific interrupt, either by stopping Timer0:

    TCCR0B &= ~( (1 << CS02) | (1 << CS01) | (1 << CS00) );

or by letting the timer run, but deactivating its interrupts:

    TIMSK0 = 0;

For details about this have a look at the [datasheet of the Atmega328p][1], which is the microcontroller on the Arduino Uno.

  [1]: https://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-7810-Automotive-Microcontrollers-ATmega328P_Datasheet.pdf


message:
Why is the watchdog biting to quickly?

currently trying to implement a watchdog into my project. I am using the WDTZero library for controlling the watchdog on my MKR NB 1500. The program is trying to measure data, send it to a server, go to sleep, wake up, and repeat the process. Sometimes the code can hang if it can't connect to the NTP server or the server on which the data is being stored, I want the watchdog to reset the program in cases in which this happens.

A sketch of the program is below. The reason why the NB network is often after different connections is that the NB 1500 is not able to connect to another server if the GPRS connection is already open, so I always reset it before trying another connection.

```
void setup()
{
    setup_watchdog(); //Sets up the watchdog timer
    delay(1000);
    connect_GPRS_NB(); //Connects to the NB network and opens a GPRS connection
    request_NTP(); //Requests epoch1970 from the NTP server and then closes the connection
    timezone_adjustment(); //Adjusts the epoch time to my timezone (in Norway)
    set_RTC(); //Activates the SAMD21 RTC with this timezone adjusted time
    disconnect_NB(); //Disconnects from the NB network
    delay(2000);
    MyWatchDoggy.clear(); //Resets the watchdog timer
    }

void loop()
{
    connect_GPRS_NB(); //Connects to the NB network and opens a GPRS connection
    get_ENV_data(); //Takes measurements using the MKR NB ENV shield
    connect_to_server(); //Connects to the server in which the data will be stored
    write_to_server(); //Writes the data on the server
    disconnect_from_server(); //Disconnects from the server
    disconnect_NB(); //Disconnects from the NB network

    LowPower.deepSleep(300000); //Goes to deep sleep for 5 minutes
    delay(3000);
    MyWatchDoggy.clear(); //Resets the watchdog timer
}

```
All the functions above are written in other .cpp files and imported thru header files into the main file. Here is the code for activating and configuring the watchdog:
```
#include "watchdog.hpp"
#include "GPRS_NB_connection.hpp"

WDTZero MyWatchDoggy;

void setup_watchdog()
{
    MyWatchDoggy.attachShutdown(NVIC_SystemReset); //calls reset function
    MyWatchDoggy.setup(WDT_SOFTCYCLE8M); //8 minute watchdog timer
}
```
The program works fine in the way described at the top of the post when the watchdog is not included. But when including the watchdog, it bites after 30 seconds when the dog only should have bit after 8 minutes. I see this because data is being sent about every 25-30 seconds to the server.
At first, I thought I had not activated the watchdog in the right way, so I wrote another program to test it:
```
#include <Arduino.h>
#include <WDTZero.h>
#include <RTCZero.h>

WDTZero MyWatchDoggy;
RTCZero rtc;

void set_RTC()
{
    rtc.begin();
    rtc.setYear(0);
    rtc.setMonth(0);
    rtc.setDay(0);
    rtc.setHours(0);
    rtc.setMinutes(0);
    rtc.setSeconds(0);
}

void shutdown()
{
    Serial.println("Shutting down");

}

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

    }
    Serial.println("Starting up Arduino");
    MyWatchDoggy.attachShutdown(shutdown);
    MyWatchDoggy.setup(WDT_SOFTCYCLE8M);
    set_RTC();

}

void loop()
{
    Serial.print(rtc.getMinutes());
    Serial.print("/");
    Serial.print(rtc.getSeconds());
    Serial.println("");
    delay(1000);
}
```
But in this program the watchdog bites after about 8 minutes as it should.

I have not included the code for the functions described in the first code since I know they work without the watchdog and the code itself is very long. But if you think the problem could be caused by these functions for some reason, I will edit the post and include all the function codes.

body:
In the WDTZero library the long watchdog times are achieved by restarting the watchdog timer in watchdog interrupt until the required time is reached.

This doesn't work if the MCU sleeps.


message:
TFT display shows black stripes

I'm new to the field: I'm trying to drive a TFT ST7735S display (this is the model I'm currently using: https://www.amazon.it/dp/B078JBBPXK/ref=pe_24968671_487022601_TE_SCE_dp_1) with an Arduino Mega following this video (https://www.youtube.com/watch?v=iPeukOK6stk&ab_channel=Artigiano2.0-AlessioRomanelli). Once the hardware is set up and the code is written, when I run the example script "graphictest" of the Adafruit library for st7735 and st7789, the display shows stripes on the background as shown in the picture below:

[![enter image description here][1]][1]
(Note that the strange effect is not camera's fault)

Reading online I thought that the problem could be the fact that the display is powered with 5V instead of 3.3V, but I've also tried powering it with 3.3V (Arduino Mega 3.3V) with little to no changes. I've changed the `tft.initR(INITR_BLACKTAB);` to `tft.initR(INITR_GREENTAB);` too, as suggested by a user i this thread (https://forum.arduino.cc/t/bugged-1-8-inch-tft-diplay/1012166/5) and i've also tried powering the display with 5V but using 4.7k resistors in series to reduce the voltage as suggested in the same post, but it still doesn't work.

Moreover the strange effect that the image shows does only appear, if I use a 5V supply, just when the program executes the `void setup()` function, then becomes sharp (this does not happen if I power the display using the Arduino Mega 3.3V output supply: in fact in this case the stripes are still present even when entering the `void loop()` function)

As I said before, the program and the hardware setup arethe same as the video I was talking about.
One thing I noticed is that, when I press the reset button on the Arduino Mega, an instant before the program is reloaded, the stripes disappear leaving the image as sharp as it should have been, without any strange background effect. Does anyone have any idea on how to solve this issue?

Thank you in advance for any eventual answer!

**EDIT**:

This is the picture of the modified verison of the connections, running the graphictest program with the suggested code:

    #else
      // For the breakout board, you can use any 2 or 3 pins.
      // These pins will also work for the 1.8" TFT shield.
      #define TFT_CS        10
      //#define TFT_RST        9 // Or set to -1 and connect to Arduino RESET pin
      #define TFT_RST        8 // Or set to -1 and connect to Arduino RESET pin
      #define TFT_DC         9
    #endif

// OPTION 2 lets you interface the display using ANY TWO or THREE PINS,
// tradeoff being that performance is not as fast as hardware SPI above.

    #define TFT_MOSI 11  // Data out
    #define TFT_SCLK 13  // Clock out

    // For ST7735-based displays, we will use this call
    Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_MOSI, TFT_SCLK, TFT_RST);

[![enter image description here][2]][2]

Hopefully every connection is visible

  [1]: https://i.stack.imgur.com/KZFIm.jpg
  [2]: https://i.stack.imgur.com/ESFzz.jpg

body:
Adafruit made that graphictest program for screens that they sell. The screen that you have is not sold by Adafruit and there is no reason why they should support that screen.

Still, you can get it to work, if it is not bricked. After you see enough variants, you get an idea about what you need to get them to work. So, I suggest the following.....

Go here https://www.arthurwiz.com/software-development/177-inch-tft-lcd-display-with-st7735s-on-arduino-mega-2560 and hook up the screen to your mega just exactly as in their table. You will make 8 connections. Download and execute their 'Hello World' program from the tutorial. If that runs ok, then you know that the connections are correct. Note that the constructor is:

Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_MOSI, TFT_SCLK, TFT_RST);

Also, don't worry if the screen is not rotated correctly - you can add one line in setup() to fix that:

      tft.initR(INITR_BLACKTAB);
      tft.setRotation(1); // <---added
      tft.fillScreen(ST7735_BLACK);

Now on to graphictest. Find these lines and change them to how I have them. I left one line commented out to illustrate. You do this to identify which GPIO go with which function. Yes, I could have started here, but going through the first tutorial successfully means you have not bricked the screen and you have the connections correct.

    #else
      // For the breakout board, you can use any 2 or 3 pins.
      // These pins will also work for the 1.8" TFT shield.
      #define TFT_CS        10
      //#define TFT_RST        9 // Or set to -1 and connect to Arduino RESET pin
      #define TFT_RST        8 // Or set to -1 and connect to Arduino RESET pin
      #define TFT_DC         9
    #endif

You will use Option 2 and the constructor as stated previously - so

    // OPTION 2 lets you interface the display using ANY TWO or THREE PINS,
    // tradeoff being that performance is not as fast as hardware SPI above.
    #define TFT_MOSI 11  // Data out
    #define TFT_SCLK 13  // Clock out

    // For ST7735-based displays, we will use this call
    Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_MOSI, TFT_SCLK, TFT_RST);

    // Use this initializer if using a 1.8" TFT screen:
      tft.initR(INITR_BLACKTAB);      // Init ST7735S chip, black tab

Note that even though my screen still has a green tab, if I use the green tab initializer, I will have offset problems.

Make sure you haven't left any other configuration lines uncommented. I have the same screen and just hooked it up and tested all of this and everything works fine.

[![enter image description here][1]][1]

Let us know how it goes.

Edited to add:

You do not need to add ANY external resistors. Your Mega has connections for both 3V and 5V and you need to use both voltages.

Your initial pic (see below) shows that both pin 2 and pin 8 are connected to the same +V on the rail of the breadboard. This is incorrect. As shown in the table I linked, Pin 2 on the LCD goes to 5V on the Mega and pin 8 on the LCD goes to 3.3V on the Mega.

[![enter image description here][2]][2]

  [1]: https://i.stack.imgur.com/Lgkr5.jpg
  [2]: https://i.stack.imgur.com/IQcP1.jpg


body:
I had the exact same issue, and tested the things here but it did not help.
Then I pressed the reset button on my UNO with the same result as Luke__ had (the screen looked nice as long as I pressed the reset). After doing that a few times the display started to work as it should.

Strange, but resolved my issue.


message:
How can i separate values from the full string, incoming string always changes its positions?

```json
String str = {"timestamp": "2023-02-08 16-37-31" ,"cpcb_device": [{"Station" : "832","Para": [{"tag_name": "COD","tag_value": "35.5","tag_unit": "mg/l"},{"tag_name": "BOD","tag_value": "13.7","tag_unit": "mg/l"},{"tag_name": "TSS","tag_value": "24.8","tag_unit": "mg/l"},{"tag_name": "pH","tag_value": "6.5","tag_unit": "pH"}]}]}
```

body:
You can use substring() and indexOf() to get parts of the string at certain positions. for example:
```
String test = "timestamp: 123 value: test";

int val = test.indexOf("timestamp:"); //gives you the index for the beginning of "timestamp:"
int start = test.indexOf(" ", val)+1; //get index of the space starting at our 'val' index
int end = test.indexOf(" ", start); //get index of the next space, we added 1 to the previous value so it doesn't pick up the first space
timestamp = test.substring(start, end); //get the characters between these two index values
```
Try it out and see how it works for you, obviously getting the index of separating characters that make more sense, such as a comma or colon rather than a space.\
Also you could do it like this:
```
String search = "timestamp:";
int start = test.indexOf(search)+search.length();
//etc...
```


message:
How can I connect 2 Arduinos using ESP8266 transiver: ESP01

I have: 2 arduinos UNO, 2 ESP01 transivers. But if that's not enough, I'm ready to buy something else
I need to use one of Arduinos as a wifi hot spot, and the second as a modem. They should just be connected to each other :)
P.S. This is for my school project! Subsequently, I will put some obstacles between the Arduinos to see how much the signal strength degrades.

body:
Here is the ESP8266 WiFi library:\
https://github.com/esp8266/Arduino/tree/master/libraries/ESP8266WiFi

In there You'll find an example for a WiFi access point:\
https://github.com/esp8266/Arduino/blob/master/libraries/ESP8266WiFi/examples/WiFiAccessPoint/WiFiAccessPoint.ino

And an example for WiFi client:\
https://github.com/esp8266/Arduino/blob/master/libraries/ESP8266WiFi/examples/WiFiClient/WiFiClient.ino

That should provide enough information for you to build your project.

To get the signal strength without connecting, you can use WiFiScan:\
https://github.com/esp8266/Arduino/blob/master/libraries/ESP8266WiFi/examples/WiFiScan/WiFiScan.ino


message:
Arduino IDE for ESP32: Compilation Error: Exist status 255

**Problem:**

I have a ESP32 and I've been trying to flash it with the Arduino IDE, however it's been giving me Python error messages :/ when I'm trying C/C++ code to flash the Arduino.

**Question:**

How can I setup the board below so I can flashi it with C/C++ from the Arduino IDE?

**Error Message:**

      [6909] Error loading Python lib '/var/folders/wm/_tds7_0s6_j9587rbm54nfv00000gn/T/_MEIli4AzL/libpython3.8.dylib': dlopen: dlopen(/var/folders/wm/_tds7_0s6_j9587rbm54nfv00000gn/T/_MEIli4AzL/libpython3.8.dylib, 10): Symbol not found: ____chkstk_darwin
      Referenced from: /var/folders/wm/_tds7_0s6_j9587rbm54nfv00000gn/T/_MEIli4AzL/libintl.8.dylib (which was built for Mac OS X 11.0)
      Expected in: /usr/lib/libSystem.B.dylib
      in /var/folders/wm/_tds7_0s6_j9587rbm54nfv00000gn/T/_MEIli4AzL/libintl.8.dylib

      exit status 255

      Compilation error: exit status 255

**ESP32:**

[![enter image description here][1]][1]

**References Used/Due Diligence:**

 - [Installing the ESP32 Board in Arduino IDE (Windows, Mac OS X, Linux)][2]
 - [Getting Started with the ESP32 Development Board][3]
 - [ESP32 Bluetooth Classic with Arduino IDE – Getting Started][4]

**Version Numbers:**

 - MAC OS Version: macOS High Sierra Version 10.13.6

 - Arduino Version: Version 2.0.4-nightly-20230119 CLI Version: 0.29.0

  [1]: https://i.stack.imgur.com/ds0Di.jpg
  [2]: https://randomnerdtutorials.com/installing-the-esp32-board-in-arduino-ide-windows-instructions/
  [3]: https://randomnerdtutorials.com/getting-started-with-esp32/
  [4]: https://randomnerdtutorials.com/esp32-bluetooth-classic-arduino-ide/

body: I don't have Mac but I am working on Linux and I also had issues with Arduino IDE v2 (in the past). Because of this I'm still using IDE v1 with no issues and that's my suggestion: try older version of the IDE on your mac, you can still download it. If it won't work you can turn to PlatformIO or VSCode IDEs.


message:
adc arduino using reference voltage to read stable/constant lithium battery voltage

[![enter image description here][1]][1]

I want to read my lithium battery voltage.

1) I WANT TO CREATE A FUNCTION TO READ MY 3.7~4.2V,1200mAH BATTERY VOLTAGE THROUGH A MICROCONTROLLER (ARDUINO OR ATTINY44).

2) THEN I WANT TO CALL THE CREATED BATTERY FUNCTION IN THE FORMULA TO READ PRECISE SENSOR VALUE

        int voltage = ((CALLING BATTERY FUNCTION) * (READ SENSOR VALUE)) / 1023;

3) I AM USING INTERNAL REFERENCE VOLTAGE 1.1V.
NOTE: I want the whole system to run on lithium battery ( I am just creating a prototype on Arduino, if it works, ill be editing the code for my attiny44 using 8mhz external crystal).

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

        void loop() {
          //REFS1 AND REFS0 to 1 1 -> internal 1.1V refference
          ADMUX |= B11000000;
          //We read A1 (MUX0)
          ADMUX |= B00000001;
          // Start AD conversion
          ADCSRA |= B11000000;
          // Detect end-of-conversion
          while (bit_is_set(ADCSRA,ADSC));
          float val = ADCL | (ADCH << 8);
          val = val * 5.7; //Multiply by the inverse of the divider
          Serial.println(val);
        }

**This code is working but it is reading from analog Pin. Is there any possibility to do it without using AnalogPin because I dont have any spare pin on my attiny.**

  [1]: https://i.stack.imgur.com/bu89s.png

body:
> I want the whole system to run on lithium battery

If you power the Arduino from the battery, then you can indirectly read the battery voltage by reading the internal voltage reference. This requires no pins - just connect the battery across the Arduino ground and the 5V pin. Here is more explanation on why this works...

https://wp.josh.com/2014/11/06/battery-fuel-guage-with-zero-parts-and-zero-pins-on-avr/

Note: Do not connect more than 5 volts or less than 0 volts to the `5V` Arduino pin. This pin is connected directly to the AVR without any overvoltage or reverse polarity protection. Your  3.7~4.2V battery should be fine.


message:
How to use reset pin as I/O pin with ATtiny44

I am using the Arduino IDE as an ISP programmer to program my ATtiny44 IC. Unfortunately, I ran out of pins, so I want to use the reset pin as I/O. I read several articles online that says it is possible and even the datasheet says so.

[![enter image description here][1]][1]

I have a high voltage programmer as well. I wrote the code in the Arduino IDE and then used its hex file to program it using the high voltage programmer (TNM PROGRAMMER).

[![enter image description here][2]][2]

After I program, the IC stops working.

////////////////////////////////////EDIT/////////////////////////////////////

```c++
const int led = 0;
const int reset_led = 11; //physical pin 4 on attiny

// 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(reset_led, OUTPUT);
}

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

New fuse bit setup:

[![enter image description here][3]][3]

////////////////////////EDIT 2 /////////////////////////////////////////

[![enter image description here][4]][4]

Now, the led on reset has turned off completely while the another still blinks.
Powering my attiny44 with 5v.Code is same as before

////////////////////////////////EDIT 3////////////////////////////////////

    #include <avr/io.h>
    const int led = 0;
    #define ledd PB3
    // 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);

    DDRB |= (uint8_t)(1<<PB3);
    pinMode (ledd, OUTPUT);

    }

    // the loop function runs over and over again forever
    void loop() {

    PORTB |= (uint8_t)(1<< PB3);

     digitalWrite (led, HIGH);
      digitalWrite (ledd, HIGH);

     delay(1000);                       // wait for a second

    PORTB &= ~((uint8_t)(1 << PB3)); // set PB3 to "low"

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

This code worked miraculously for me, Thanks to @thebusybee.

/////////////////////////////EDIT 3/////////////////////////////////////////

The PB3 pin is pin11 in arduino.

[![enter image description here][5]][5]

  [1]: https://i.stack.imgur.com/J00bm.png
  [2]: https://i.stack.imgur.com/Pmwkt.png
  [3]: https://i.stack.imgur.com/Ha3YN.png
  [4]: https://i.stack.imgur.com/wIycI.png
  [5]: https://i.stack.imgur.com/jIsVa.png

body:
The [data sheet][1] gives insights:

Chapter 1.1.4 states:

> The reset pin can also be used as a (weak) I/O pin.

"_Weak_" means here, that the output function cannot deliver as much current as the other outputs, according to figures 21-24 to 21-27 beginning at page 198 roughly 2 to 3 mA. This is commonly not enough for LEDs, except you use a high-efficiency LED.

And on page 66 is this relevant table (I cut the irrelevant column for PB2):

> **Table 10-8.** Overriding Signals for Alternate Functions in PB[3:2]
>
> | Signal Name | PB3/RESET/dW/PCINT11 |
> | - | - |
> | PUOE | RSTDISBL(1) + DEBUGWIRE_ENABLE(2) |
> | PUOV | 1 |
> | DDOE | RSTDISBL(1) + DEBUGWIRE_ENABLE(2) |
> | DDOV | DEBUGWIRE_ENABLE(2) • debugWire Transmit |
> | PVOE | RSTDISBL(1) + DEBUGWIRE_ENABLE(2) |
> | PVOV | 0 |
> | PTOE | 0 |
> | DIEOE | RSTDISBL(1) + DEBUGWIRE_ENABLE(2) + PCINT11 • PCIE1 |
> | DIEOV | DEBUGWIRE_ENABLE(2) + (RSTDISBL(1) • PCINT11 • PCIE1) |
> | DI | dW/PCINT11 Input |
> | AIO | |
>
> Note:
> 1. RSTDISBL is 1 when the Fuse is “0” (Programmed).
> 2. DebugWIRE is enabled when DWEN Fuse is programmed and Lock bits are unprogrammed.

Since you have `DebugWIRE` enabled, this seems to be the cause. The alternate function `RESET` is still active.

Please be aware that according to note 1 below table 19-4 on page 160:

> After programming the RSTDISBL fuse, high-voltage serial programming must be used to change fuses and allow further programming.

This means that your circuit at PB3 needs to withstand the high voltage, and that the voltage source needs to provide enough current, which the circuit additionally draws at the high voltage.

---

Now to your code.

You use the pin number "0" and hope to have PB3. Well, according to this shamelessly linked pinout this is not correct:

[![Arduino pinout ATtiny44][2]][2]

Pin "0" is PA0.

PB3 has no number assigned.

Your next step could be to look up the sources of the Arduino library and check, if PB3 has a number assigned at all. I'm afraid this is not the case. If you're lucky and it has, use it. You will want to tell us about your finding then.

You can directly access the data direction control register and the port register. Grab your data sheet and other documentation, read, and implement.

This is untested:

```c
// 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"
```

  [1]: https://ww1.microchip.com/downloads/en/DeviceDoc/doc8006.pdf
  [2]: https://i.stack.imgur.com/VCjwB.jpg


message:
Button Matrix / Wiring Schematics

I am just beginning my journey into the Arduino world - plenty of development experience, but basically nothing with electronics outside of building computers.

The question I have involves wiring schematics - specifically for a button matrix, but it does apply more broadly. Using this diagram and Fritzing mapping, I see numerous buttons connected to each other - presumably via soldering:

[![Diagram][1]][1]

[![Fritzing][2]][2]

My question is, can you use wire nuts (or, more specifically multi-slot lever connectors) such as these to simplify the connection process?

[![Levers][3]][3]

I apologize in advance if this seems obvious, but I get lost trying to understand how to connect this stuff because I'm so new to it all.

Thanks in advance!

  [1]: https://i.stack.imgur.com/9cwHV.png
  [2]: https://i.stack.imgur.com/V25m3.png
  [3]: https://i.stack.imgur.com/eJXYU.jpg

body:
Assuming that "multi-slot lever connectors" is shorting the inserted wires together I see no reason why you could not use them.

If you are adverse to soldering consider using switches and cables commonly found in arcade machines instead.

Previously crimped cables ...

[![enter image description here][1]][1]

And arcade style micro switches ...

[![enter image description here][2]][2]

Can be combined / connected to form the switch matrix your designed above.

  [1]: https://i.stack.imgur.com/t8M6d.jpg
  [2]: https://i.stack.imgur.com/PydB4.jpg


message:
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 cant 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 dont work.
Heres 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 in help as I cant seem to find any explanations about this two functions:
```
if (!mfrc522.PICC_IsNewCardPresent())
  {
    return;
  }
  //Select one of the cards
  if (!mfrc522.PICC_ReadCardSerial())
  {
    return;
  }
```

Thanks in advance,
*Barzy.*

body:
    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.


message:
How to declare PB3 reset pin of ATtiny44 in program (using arduino IDE platform)

As follow-up of my [former question][1]:

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.

[![enter image description here][2]][2]

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.

```c++
// 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`.

[![PB3 of ATtiny][3]][3]

---

**EDIT**

```lang-cpp
#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.

[![Fusebits config][4]][4]

  [1]: https://arduino.stackexchange.com/questions/92279/how-to-use-reset-pin-as-i-o-pin-with-attiny44/92290?noredirect=1#comment212771_92290
  [2]: https://i.stack.imgur.com/awKYr.jpg
  [3]: https://i.stack.imgur.com/e9Tpb.png
  [4]: https://i.stack.imgur.com/qaEN3.png

body: 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).


message:
Arduino Nano 33 BLE getting the current time using RTC

I have a an [arduino NANO 33 BLE][1] 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][2] It is listed in the [nordic documentation][3] as well. However, I'm not sure exactly how to use it to get the current time; Based on the [MbedOS documentation for Time][4] 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

  [1]: https://docs.arduino.cc/hardware/nano-33-ble
  [2]: https://nsscprodmedia.blob.core.windows.net/prod/software-and-other-downloads/product-briefs/nrf52840-soc-v3.0.pdf
  [3]: https://infocenter.nordicsemi.com/index.jsp?topic=/struct_nrf52/struct/nrf52840.html
  [4]: https://os.mbed.com/docs/mbed-os/v6.15/apis/time.html

body:
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.


message:
6-pin BME280 not giving I2C signal

[![Updated picture][1]][1]

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.

  [1]: https://i.stack.imgur.com/fiNcj.jpg

body:
@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.
[![enter image description here][1]][1]

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.
[![enter image description here][2]][2]

- 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.

  [1]: https://i.stack.imgur.com/qHNVX.jpg
  [2]: https://i.stack.imgur.com/evzQW.jpg


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

I have this circuit
[![enter image description here][1]][1]

[![enter image description here][2]][2]

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 .

[![enter image description here][3]][3]

[![enter image description here][4]][4]

This is my code

```lang-cpp
#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?

  [1]:https://i.stack.imgur.com/KdLGO.png
[2]:https://i.stack.imgur.com/Ubypz.png
[3]:https://i.stack.imgur.com/WB6fI.png
[4]:https://i.stack.imgur.com/GGbPV.png

body:
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][1] 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.

  [1]: https://www.powerstream.com/AA-tests.htm


message:
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.

body:
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


message:
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.

body:
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.


message:
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.

```lang-cpp

//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

body:
Your code for RadiantMain is:

<!-- language: lang-C++ -->

    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.


message:
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 the only three port, but these all not correct][1]][1]

This is official description about driver.

[![enter image description here][2]][2]

  [1]: https://i.stack.imgur.com/DRVGx.png
  [2]: https://i.stack.imgur.com/UShax.png

body:
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'.


message:
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

body:
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 :
[![arduino nano pinout][1]][1]
[![teesny 3.2 pinmap][2]][2]

  [1]: https://i.stack.imgur.com/Flw0p.png
  [2]: https://i.stack.imgur.com/GtLJm.png


message:
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){
    };
}
```

body:
> 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.


body:
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){

    }
```


message:
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.

body:
>  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...

[![enter image description here][1]][1]

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][2]) 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][3] to it. You really should heed my answer to your other question [here][4].

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. :)

  [1]: https://i.stack.imgur.com/jAJuL.png
  [2]: https://www.google.com/search?q=(3.7 volts)/(4.7 kiloohms) in milliamps
  [3]: https://www.mpoweruk.com/lithium_failures.htm#:~:text=under-voltage / over-discharge
  [4]: https://arduino.stackexchange.com/a/92269/7859


message:
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][1].
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][2], 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

  [1]: https://github.com/mchr3k/arduino-libs-manchester
  [2]: https://github.com/mchr3k/arduino-libs-manchester/issues/53

body:
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 !


message:
Change Interrupts on the ATTiny 88

I am working on a project that requires a number of I/O pins for various purposes.  I chose the ATTiny88 because it has plenty of GPIO pins, and is relatively inexpensive.

Here is the updated code per timemage, with many thanks!

```
#include <Arduino.h>
#include <TM1637Display.h>
#include "PinChangeInterrupt.h"

int counter = 0;
bool Update = false;
int currentStatePhase_B;
int lastStatePhase_B;

// Shutdown Output
#define SW 11

// Rotary Encoder Inputs
#define Phase_A 13
#define Phase_B 12
#define DIO 3
#define CLK 4

TM1637Display display(CLK, DIO);

void setup() {

  // Set encoder pins as inputs
  pinMode(Phase_A,INPUT);
  pinMode(Phase_B,INPUT);
  pinMode(SW, OUTPUT);

 // Read the initial state of Phase_B
 lastStatePhase_B = digitalRead(Phase_B);

 // Call updateEncoder() when any high/low changed seen
 // on interrupt 0 (pin 2), or interrupt 1 (pin 3)
 attachPCINT(digitalPinToPCINT(Phase_A), updateEncoder, CHANGE);
 attachPCINT(digitalPinToPCINT(Phase_B), updateEncoder, CHANGE);

  display.setBrightness(0x0f);
  display.clear();
}

void loop() {
  delay(100);
 if (Update){
  // Show decimal numbers with/without leading zeros
    display.showNumberDec(counter, false);
    // Expect: ___0
  Update = false;
 }
}

void updateEncoder(){
  delay (4);
 // Read the current state of Phase_B
 currentStatePhase_B = digitalRead(Phase_B);

 // If last and current state of Phase_B are different, then pulse occurred
 // React to only 1 state change to avoid double count
 if (currentStatePhase_B != lastStatePhase_B  && currentStatePhase_B == 1){

  // If the Phase_A state is different than the Phase_B state then
  // the encoder is rotating CCW so decrement
  if (digitalRead(Phase_A) != currentStatePhase_B) {
   counter --;
  } else {
   // Encoder is rotating CW so increment
   counter ++;
  }

    if (counter > 1023){
      counter = 1023;
    }
    if (counter < 0){
      counter = 0;
    }
    delay(15);
 }

 // Remember last CLK state
 lastStatePhase_B = currentStatePhase_B;
 Update = true;
}
```
It is now capturing most, but not by any means all, interrupts, but the direction is highly unreliable.  More often than not, it counts up regardless of which way the encoder is turned,and often counts down when the encoder is turned clockwise.

Here is what seems to be a good reference:
[ATtiny88 8-bit Microcontroller][1]

  [1]: https://components101.com/microcontrollers/attiny88-pinout-specs-datasheet

body:
### Interrupt types

> One source says there are only two interrupt pins, ...

There are  two "*external* interrupt" pins; that is the term you'll find in the chip's datasheet. This is the term that refers to the kind of pins that `attachInterupt` uses. These are the ones in the pinout labeled INT0,INT1,INTn. The "external" term may be confusing for a couple of reasons. Lots of external things cause interrupts, but this name is applied to when you're not talking about events tied to particular peripherals, like USART (serial peripheral) receiving a character. The special function of "external interrupt" is *dedicated* to dispatching interrupts based on signals on these INT0/INT1/INT# pins. There's one interrupt vector for each of these signals (two in your case). As you've probably seen in the documentation they can be configured to trigger on rising or falling edges, both edges, and low levels.
So, they're right about that to the extent that they're talking about the "external interrupt" pins.

The "external" name is also confusing because of what else you've found:

> Another source says there are quite a few Change Interrupt pins

This is also true. These are the "PCINT#" signal names listed in the chip pinout.  These "*pin change* interrupts" are newer; not new, but new*er*. There exist(ed) AVR that had/have "external interrupts" but no "pin change interrupts". I'd like  to think that if they were created at the same time they wouldn't have simply called the former ones "external", because these are no less external although they're less dedicated. There's only a single ISR/interrupt for each group of 8 PCINT pins. And unlike the others they only naturally detect that a pin has changed and nothing about the nature of that change (rising vs falling). But a lot of AVR support them and those that do have a significant number of them. In the case of your ATTiny88, all of the GPIO (Arduino "digital") pins are capable of dispatching a pin change interrupt.  However, the Arduino AVR core doesn't provide a function for using them.

### Modifying NicoHood's PinChangeInterrupt library

One of the people that used to be in my circle was NicoHood, who created [this PinChangeInterrupt library][1]. I have a foggy memory of helping with bits of it.

What he did was model it after the normal `attachInterrupt` function. So, you can use it almost as though you have the `RISING`/`FALLING`/`CHANGE` "external interrupt" capability on all of your PCINT# pins; in your case all of your pins. Underneath it is tracking the state of each port pin to determine what has changed and in what direction. In other words, using an interrupt that fires given a change on any of 8 pins together with variables to synthesize per-pin callbacks for not just change but also specifically rising and falling if you want. This is not perfect it is possible to lose short lived events and it takes longer to dispatch your handler function. But it's probably fine for what you're doing.

It does not support your chip out of the box. However you can modify to support the ATTiny88; partially if you're not picky. You should find it in the library manager as "PinChangeInterrupt" by NicoHood, currently at version 1.2.9. If you install that it should show up under your sketchbook/libraries directory. You will need to edit the file at path:

\<sketchbook-directory\>`/libraries/PinChangeInterrupt/src/PinChangeInterruptBoards.h`

That's your local copy of [this file][2].

Your ATTiny88's handling of PCINT is going to be nearly the same as the ATMega328P that's in the UNO. Or rather nearly a superset of it. The chips are closely related in a way.
However, you have extra PCINT capable pins on the ATTiny88 that aren't available on the ATMega328P. So you can crudely hack in a line into [this section][2] to read:

```c++
#if defined(__AVR_ATmega328__) || defined(__AVR_ATmega328A__) || defined(__AVR_ATmega328PA__) || defined(__AVR_ATmega328P__) || defined(__AVR_ATmega328PB__) \
   || defined(__AVR_ATmega168__) || defined(__AVR_ATmega168A__) || defined(__AVR_ATmega168PA__) || defined(__AVR_ATmega168P__) || defined(__AVR_ATmega168PB__) \
   || defined(__AVR_ATmega88__) || defined(__AVR_ATmega88A__) || defined(__AVR_ATmega88PA__) || defined(__AVR_ATmega88P__) || defined(__AVR_ATmega88PB__) \
   || defined(__AVR_ATtiny88__) \
   || defined(__AVR_ATmega48__) || defined(__AVR_ATmega48A__) || defined(__AVR_ATmega48PA__) || defined(__AVR_ATmega48P__) || defined(__AVR_ATmega48PB__)
```

The addition of that second to last line above should make the library treat the ATTiny88 you have as though it were an ATMega328P. This compiles under ATTinyCore. I am not set up to test it on a real ATTiny88. But, I expect it will work if you try some examples.

Having done that, the library should be work on any of the pins that carry a PCINT0 through PCINT23 label.  If you want it to work with PCINT24-PCINT27, that can be done, but requires more work. But given what you've said you probably don't need one of those four and they're not available on the DIP package which I'm guessing you have anyway.

### Updating your code

You would to `#include "PinChangeInterrupt.h"` at the top of your code, and then your current code:

```c++
    attachInterrupt(digitalPinToInterrupt(Phase_A), updateEncoder, CHANGE);
    attachInterrupt(digitalPinToInterrupt(Phase_B), updateEncoder, CHANGE);
```

then becomes:

```c++
    attachPCINT(digitalPinToPCINT(Phase_A), updateEncoder, CHANGE);
    attachPCINT(digitalPinToPCINT(Phase_B), updateEncoder, CHANGE);
```

With luck, that should do it provided `Phase_A` and `Phase_B` under your core (e.g. ATTinyCore) map to GPIO/Arduino "digital" pins that carry a PCINT# signal where the number less than 24.

As I said, I have no way of testing it on real hardware right now. But I expect it will work. If not, it is the sort of direction you need to go in.

### Doing PCINT yourself

You can also take a more direct approach with reading the datasheet and sorting out how to do what the library does for you, only manually. [One of the examples][3] NicoHood provided with the library is not really an example of using the library but rather an explanation as to what the library does in the form of code. Notice it doesn't actually include the library; it would operate stand alone. So if you want to understand the guts yourself by following the ATtiny88 datasheet, that's a place to start.

One reason you might want to do it yourself anyway is if your encoders are being operated quickly, to the point where you can't afford some of the extra effective dispatch time imposed by what the PinChangeInterrupt library is doing in sorting out which pin changed and how. If you handle PCINT yourself, you can make a point of putting your two encoder pins in completely different groups of 8 such that there is only one source of pin change interrupt for each ISR and so there is no need to check which pin caused the interrupt and to route that to another function.

  [1]: https://github.com/NicoHood/PinChangeInterrupt/
  [2]: https://github.com/NicoHood/PinChangeInterrupt/blob/1.2.9/src/PinChangeInterruptBoards.h
  [3]: https://github.com/NicoHood/PinChangeInterrupt/blob/1.2.9/examples/PinChangeInterrupt_HowItWorks/PinChangeInterrupt_HowItWorks.ino