text:
Real Time clock module error-DS3231
This is not a code error I have been using DS3231 RTC module with battery. When I bought this module It worked perfectly now when I get it to use, The time is running perfectly. when I set the current time of my location, it has been running along with that time but the problem is when I unplug the power of my Arduino Nano and again when I give the power I can see the time is running from its start, I could not see any current time value my location but I have attached CR2032 battery along with DS3231 module? what is the problem with this? I changed another battery too but It shows same problem my DS32321 haven't kept the time when I unplug and re-plug the power
This is the code I'm using for set the time
#include <DS3231.h>

// Init the DS3231 using the hardware interface
DS3231  rtc(SDA, SCL);

void setup()
{
  // Setup Serial connection
  Serial.begin(115200);
  // Uncomment the next line if you are using an Arduino Leonardo
  //while (!Serial) {}

  // Initialize the rtc object
  rtc.begin();

  // The following lines can be uncommented to set the date and time
  rtc.setDOW(WEDNESDAY);     // Set Day-of-Week to SUNDAY
  rtc.setTime(12, 0, 0);     // Set the time to 12:00:00 (24hr format)
  rtc.setDate(1, 1, 2014);   // Set the date to January 1st, 2014
}

void loop()
{
  // Send Day-of-Week
  Serial.print(rtc.getDOWStr());
  Serial.print(" ");

  // Send date
  Serial.print(rtc.getDateStr());
  Serial.print(" -- ");

  // Send time
  Serial.println(rtc.getTimeStr());

  // Wait one second before repeating :)
  delay (1000);
}

This is the code I'm using to make Interrupt
 #include <DS3231.h>

int Relay = 4;

DS3231  rtc(SDA, SCL);
Time t;

const int OnHour = 21;
const int OnMin = 46;
const int OffHour = 21;
const int OffMin = 48;

const int On2Hour = 14;
const int On2Min = 54;
const int Off2Hour = 21;
const int Off2Min = 48;

void setup() {
  Serial.begin(115200);
  rtc.begin();
  pinMode(Relay, OUTPUT);
  digitalWrite(Relay, LOW);
}

void loop() {
  Serial.println("Time:  ");
  Serial.print(rtc.getTimeStr());
  Serial.print('\n');

  Serial.println("Date: ");
  Serial.print(rtc.getDateStr());
  Serial.print('\n');

  t = rtc.getTime();
  Serial.print(t.hour);
  Serial.print(" hour(s), ");
  Serial.print(t.min);
  Serial.print(" minute(s)");
  Serial.println(" ");
  delay (1000);
  //can be set lcd display alspo
  if(t.hour == OnHour && t.min == OnMin){
    digitalWrite(Relay,HIGH);
    Serial.println("LIGHT ON");
    }

    else if(t.hour == OffHour && t.min == OffMin){
      digitalWrite(Relay,LOW);
      Serial.println("LIGHT OFF");
    }
  if(t.hour == On2Hour && t.min == On2Min){
    digitalWrite(Relay,HIGH);
    Serial.println("LIGHT ON");
    }

    else if(t.hour == Off2Hour && t.min == Off2Min){
      digitalWrite(Relay,LOW);
      Serial.println("LIGHT OFF");
    }
}

Can you please share your code and which library are you using

I'm using Ds3231 library

yeah now I have uploaded the code

I am posting a code please try it may be it can help you
    #include "RTClib.h"

RTC_DS3231 rtc;

char daysOfTheWeek[7][12] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};

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

#ifndef ESP8266
  while (!Serial); // wait for serial port to connect. Needed for native USB
#endif

  if (! rtc.begin()) {
    Serial.println("Couldn't find RTC");
    Serial.flush();
    abort();
  }

  if (rtc.lostPower()) {
    Serial.println("RTC lost power, let's set the time!");
    // When time needs to be set on a new device, or after a power loss, the
    // following line sets the RTC to the date & time this sketch was compiled
    rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
    // This line sets the RTC with an explicit date & time, for example to set
    // January 21, 2014 at 3am you would call:
     rtc.adjust(DateTime(2020, 10, 19, 10, 13, 0));
  }

  // When time needs to be re-set on a previously configured device, the
  // following line sets the RTC to the date & time this sketch was compiled
  // rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
  // This line sets the RTC with an explicit date & time, for example to set
  // January 21, 2014 at 3am you would call:
  // rtc.adjust(DateTime(2014, 1, 21, 3, 0, 0));
}

void loop () {
    DateTime now = rtc.now();

    Serial.print(now.year(), DEC);
    Serial.print('/');
    Serial.print(now.month(), DEC);
    Serial.print('/');
    Serial.print(now.day(), DEC);
    Serial.print(" (");
    Serial.print(daysOfTheWeek[now.dayOfTheWeek()]);
    Serial.print(") ");
    Serial.print(now.hour(), DEC);
    Serial.print(':');
    Serial.print(now.minute(), DEC);
    Serial.print(':');
    Serial.print(now.second(), DEC);
    Serial.println();

    Serial.print(" since midnight 1/1/1970 = ");
    Serial.print(now.unixtime());
    Serial.print("s = ");
    Serial.print(now.unixtime() / 86400L);
    Serial.println("d");

    // calculate a date which is 7 days and 30 seconds into the future
    DateTime future (now + TimeSpan(7,12,30,6));

    Serial.print(" now + 7d + 30s: ");
    Serial.print(future.year(), DEC);
    Serial.print('/');
    Serial.print(future.month(), DEC);
    Serial.print('/');
    Serial.print(future.day(), DEC);
    Serial.print(' ');
    Serial.print(future.hour(), DEC);
    Serial.print(':');
    Serial.print(future.minute(), DEC);
    Serial.print(':');
    Serial.print(future.second(), DEC);
    Serial.println();

    Serial.print("Temperature: ");
    Serial.print(rtc.getTemperature());
    Serial.println(" C");

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

Upload the above code and then upload the same code just comment the following part
if (rtc.lostPower()) {
        Serial.println("RTC lost power, let's set the time!");
        // When time needs to be set on a new device, or after a power loss, the
        // following line sets the RTC to the date & time this sketch was compiled
        rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
        // This line sets the RTC with an explicit date & time, for example to set
        // January 21, 2014 at 3am you would call:
         rtc.adjust(DateTime(2020, 10, 19, 10, 13, 0));
      }

This will work and even if you plug and unplug it from power the RTC time will not reset

is it ok with Arduino

No,  it's not working, It shows the same problem that I have been facing. I mean my RTC module ds3231 does not keep time when it loses it power. but  I have attached timekeeping battery along with that

The same above code was working for me have you checked the voltage of the battery and also have you uncommented the part of the code and uploaded it again?

yeah , your  code is working fine , I changed the new battery too, but the problems is when it loses it power it starts from 2000/0/1 and the time is starting with 00.00.01

Okay 2000/0/1 is the starting time of ds3231, have you checked the voltage using multimeter check the polarity of the battery also before inserting it in the module and can you please share the picture of your module and also how have you inserted the battery

yeah I have to check the voltage using multimeter but the battery is new one and I have attached the battery in a proper way. I could not send the image through this platform because it is a large file

If you send your email I cand send it through that

Attach it in your above post everyone can answer then even if I am unable to answer it

yeah I tried that but it contains a large file size

Upload it over here

Use any software to reduce the size (resolution / bit depth / compression).

ok here is my ds3231 image https://gofile.io/d/9IkuBr

Now I checked my rtc module it shows 3.3v across the ds3231 module but it doesn't keep the time

I don't have access to my hardware right now will get back once I have access to my hardware, have you commented the part of the code which I have mentioned in the above code and tried again just want to know all the possibilities

2020/10/19 (Monday) 10:14:5
since midnight 1/1/1970 = 1603102445s = 18554d
now + 7d + 30s: 2020/10/26 22:44:11
Temperature: 33.75 C
This was the output when I upload your code as per your instruction

⸮⸮:b⸮⸮⸮{⸮8k⸮⸮⸮⸮⸮⸮2000/1/1 (Saturday) 0:0:5
since midnight 1/1/1970 = 946684805s = 10957d
now + 7d + 30s: 2000/1/8 12:30:11
Temperature: 33.75 C
this is the output message when I unplug and re-plug the power of my Arduino

Posting a schematic not a frizzy picture, as how you have it wired showing all connections could eliminate a lot of the problems. Perfect software with the wrong hardware configuration will not work perfectly.

I will take a SWAG as I do not know what module you are having problems. Remove the battery, power it up and measure the voltage at the battery terminals. If you have about 3.2V the module is designed to charge the battery (thought you might like to know). Power down the module insert the battery, do not power it up, and measure the battery voltage at the chip. Be sure to also check the ground side. I believe you will find the same thing I did, the solder connection to the battery holder was open, just added some solder and that solved it. I also found the SCL line was  broken on the board so if I connected the other side it would not work. I added a jumper to fix it. I purchased several from azon but only the first one was bad.


text:
Can I use this camera switcher?
I am wondering can I use this bicks camera switcher with the arduino since it uses a PWM signal.
If i can do I just put it on one of the PWM outputs or do I need to wire I add something to make it work.
**You can find the user manual here under attachments.**https://store.bicks.us/multiview/20-bicks-s-multiview-duo-fpv-camera-switcher.html

what do you mean by use with arduino?

can I use one of the pwm outputs to control it.(https://oscarliang.com/bicks-multiview-duo-camera-switcher/) for further reading

No one will read the user manual for you. This is not how StackExchange work, you read the manual and write the code, if there is any problem or question, come back here and ask the question.

Ok Thank you for letting me know

why not use a digital pin?  the PWM is for control with a radio RC

good idea, Thanks

The pwm output of an RC receiver is the same signal used to control a servo. So if you used the servo library with Arduino to control the pwm of this device it should work fine.

source: Stack Exchange

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

sort: votes


text:
Bluetooth module(HC 05) issues
I am trying to make a Bluetooth controlled 4WD robot. i was following a tutorial i found online (https://howtomechatronics.com/tutorials/arduino/arduino-robot-car-wireless-control-using-hc-05-bluetooth-nrf24l01-and-hc-12-transceiver-modules/). After successfully connecting my 2 HC 05 Bluetooth module i used the script from the tutorial and modified it slightly so it would work for my set up.
The code for the robot:
//Code for Slave
#define enA 9
#define in1 8
#define in2 7
#define enB 10
#define in3 6
#define in4 5
int xAxis, yAxis;
unsigned int  x = 0;
unsigned int  y = 0;
int motorSpeedA = 0;
int motorSpeedB = 0;
void setup() {
  pinMode(enA, OUTPUT);
  pinMode(enB, OUTPUT);
  pinMode(in1, OUTPUT);
  pinMode(in2, OUTPUT);
  pinMode(in3, OUTPUT);
  pinMode(in4, OUTPUT);
  Serial.begin(9600); // Default communication rate of the Bluetooth module
}
void loop() {
  // Default value - no movement when the Joystick stays in the center
  x = 510 / 4;
  y = 510 / 4;
  // Read the incoming data from the Joystick, or the master Bluetooth device
  while (Serial.available() >= 2) {
    x = Serial.read();
    Serial.print("X: ");
    Serial.println(x);
    delay(10);
    y = Serial.read();
    Serial.print("Y: ");
    Serial.println(y);
  }
  delay(10);
  // Convert back the 0 - 255 range to 0 - 1023, suitable for motor control code below
  xAxis = x*4;
  yAxis = y*4;
  // Y-axis used for forward and backward control
  if (yAxis < 470) {
    backMov;
    // Convert the declining Y-axis readings for going backward from 470 to 0 into 0 to 255 value for the PWM signal for increasing the motor speed
    motorSpeedA = map(yAxis, 470, 0, 0, 255);
    motorSpeedB = map(yAxis, 470, 0, 0, 255);
  }
  else if (yAxis > 550) {
    fowardMov;
    // Convert the increasing Y-axis readings for going forward from 550 to 1023 into 0 to 255 value for the PWM signal for increasing the motor speed
    motorSpeedA = map(yAxis, 550, 1023, 0, 255);
    motorSpeedB = map(yAxis, 550, 1023, 0, 255);
  }
  // If joystick stays in middle the motors are not moving
  else {
    motorSpeedA = 0;
    motorSpeedB = 0;
  }
  // X-axis used for left and right control
  if (xAxis < 470) {
    // Convert the declining X-axis readings from 470 to 0 into increasing 0 to 255 value
    int xMapped = map(xAxis, 470, 0, 0, 255);
    // Move to left - decrease left motor speed, increase right motor speed
    motorSpeedA = motorSpeedA + xMapped;
    motorSpeedB = motorSpeedB - xMapped;
    // Confine the range from 0 to 255
    if (motorSpeedA > 255) {
      motorSpeedA = 255;
    }
    if (motorSpeedB < 0) {
      motorSpeedB = 0;
    }
  }
  if (xAxis > 550) {
    // Convert the increasing X-axis readings from 550 to 1023 into 0 to 255 value
    int xMapped = map(xAxis, 550, 1023, 0, 255);
    // Move right - decrease right motor speed, increase left motor speed
    motorSpeedA = motorSpeedA - xMapped;
    motorSpeedB = motorSpeedB + xMapped;
    // Confine the range from 0 to 255
    if (motorSpeedA < 0) {
      motorSpeedA = 0;
    }
    if (motorSpeedB > 255) {
      motorSpeedB = 255;
    }
  }
  // Prevent buzzing at low speeds (Adjust according to your motors. My motors couldn't start moving if PWM value was below value of 70)
  if (motorSpeedA < 70) {
    motorSpeedA = 0;
  }
  if (motorSpeedB < 70) {
    motorSpeedB = 0;
  }
  analogWrite(enA, motorSpeedA); // Send PWM signal to motor A
  analogWrite(enB, motorSpeedB); // Send PWM signal to motor B
}
void fowardMov(){
  digitalWrite(in2,HIGH);
  digitalWrite(in4,HIGH);
  digitalWrite(in1, LOW);
  digitalWrite(in3, LOW);
}

void backMov(){
  digitalWrite(in1,HIGH);
  digitalWrite(in3,HIGH);
  digitalWrite(in2, LOW);
  digitalWrite(in4, LOW);
}

The code for the Controller:
#define Xaxis A0
#define Yaxis A1

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
}

void loop() {
  // put your main code here, to run repeatedly:
 Serial.write(analogRead(Xaxis)/4);
 Serial.write(analogRead(Yaxis)/4);
 delay(20);
}

After uploading the code i tried to move it but it wasn't working so i put print statements to see the value of X and Y. initially it didn't work so i swapped the Bluetooth modules i had and reconnected them. i also changed this line.
 while (Serial.available() >= 2)

To this
 if (Serial.available() > 0)

i started to receive values from the master to the slave but  i noticed the values were the same for x and y so i searched for another tutorial on the internet and found this (https://create.arduino.cc/projecthub/andriy-baranov/arduino-4wd-rc-car-639953?ref=similar&ref_id=18369&offset=3) reading his code i wondered how did the slave work. According to the official Arduino documentation Serial.read() does not take in any arguments but i still tried it and it didn't work. I decided to retry the code from the first tutorial i checked this time it looked like it was working so i tried moving the joystick and the serial monitor printed correct values for both at first then it swaps their values then freezes. How can i stop it from freezing and swapping the values? Also why doesn't the while loop run forever isn't the amount of data in the serial buffer always higher than 2? Thank you.

There is an issue with the way in which the data is sent and received because it assumes the transmission will remain perfectly synchronised for the lifetime of the programme. Consider what would happen if one byte were to be dropped due to a communication error – the x and y data would be swapped for further transmissions.
Original Sender
void loop() {
  // put your main code here, to run repeatedly:
 Serial.write(analogRead(Xaxis)/4);
 Serial.write(analogRead(Yaxis)/4);
 delay(20);
}

Original Receiver
void loop() {
  // Default value - no movement when the Joystick stays in the center
  x = 510 / 4;
  y = 510 / 4;
  // Read the incoming data from the Joystick, or the master Bluetooth device
  while (Serial.available() >= 2) {
    x = Serial.read();
    Serial.print("X: ");
    Serial.println(x);
    delay(10);
    y = Serial.read();
    Serial.print("Y: ");
    Serial.println(y);
  }
  delay(10);
  . . .
}

Therefore, there needs to be a way to synchronise to the first byte of the message. This can be achieved by using message packets where the start and end of the message are delimited with unique characters, e.g. { and }, similar to the JSON format.
As another example, the NMEA GPS standard uses $ and \n to delimit messages, and , to delimit fields. It also has a checksum at the end.
Here is a non-blocking algorithm which builds upon Majenko's readline() example and the Blink Without Delay example to read a packet. ReadPacket() returns true when incoming data has been accumulated into a valid packet. The LED is flashed to indicate that the MCU hasn't frozen.
New Sender
void loop()
{
    Serial.print("{");                  // First character delimiter.
    Serial.print(analogRead(Xaxis));    // Full resolution. No need to divide by 4.
    Serial.print(",");                  // Field delimiter.
    Serial.print(analogRead(Yaxis));    // Full resolution. No need to divide by 4.
    Serial.print("}");                  // Last character delimiter.
    delay(20);
}

New Receiver
void loop()
{
    //
    // TASK 1: Blink without delay to indicate that MCU hasn't frozen.
    //
    const unsigned int INTERVAL = 250;
    unsigned long current_timestamp = millis();
    static unsigned long previous_timestamp = current_timestamp;
    static bool led_state = false;
    if (current_timestamp - previous_timestamp >= INTERVAL)
    {
        led_state = !led_state;
        digitalWrite(LED_BUILTIN, led_state);
        previous_timestamp += INTERVAL;
    }

    //
    // TASK 2: Read and parse data packet.
    //
    static char packet[100];
    const byte NUM_FIELDS = 2;
    unsigned int fields[NUM_FIELDS];
    static unsigned int x = 512;   // Full resolution. No need to divide by 4.
    static unsigned int y = 512;   // Full resolution. No need to divide by 4.
    bool new_x = false;
    bool new_y = false;
    if (ReadPacket(Serial, packet, sizeof(packet)))
    {
        Serial.print(F("Received packet >"));
        Serial.print(packet);
        Serial.println(F("<"));

        // Parse the packet for x and y values at full resolution.
        const char delimiters[] = "{,}";
        char* field;
        int i = 0;
        field = strtok(packet, delimiters);
        while (field != NULL && i < NUM_FIELDS)
        {
            Serial.print("field = ");
            Serial.println(field);
            fields[i] = atoi(field);
            Serial.print("fields[");
            Serial.print(i);
            Serial.print("] = ");
            Serial.println(fields[i]);
            field = strtok(NULL, delimiters);
            i++;
        }
        if (i == NUM_FIELDS)
        {
            if (x != fields[0])
            {
                new_x = true;
                x = fields[0];  // Full resolution. No need to multiply by 4.
                Serial.print("New x = ");
                Serial.println(x);
            }
            if (y != fields[1])
            {
                new_y = true;
                y = fields[1];  // Full resolution. No need to multiply by 4.
                Serial.print("New y = ");
                Serial.println(y);
            }
        }
    }

    Serial.print("x = ");
    Serial.println(x);
    Serial.print("y = ");
    Serial.println(y);

    //
    // TASK 3: Process x and y values.
    //
    if (new_x || new_y)
    {
        Serial.println("Processing new values.");

        . . .
    }
}

bool ReadPacket(Stream& stream, char *const packet, const unsigned int SIZE)
{
    const char FIRST = '{';
    const char LAST = '}';
    static bool read_until_last = false;
    static unsigned int i = 0;
    char ch;

    if (stream.available())
    {
        ch = stream.read();

        if (ch == FIRST)
        {
            Serial.println(F("Received FIRST."));
            i = 0;
            packet[0] = ch;
            read_until_last = true;
            return false;
        }
        if (read_until_last)
        {
            i++;
            if (i > SIZE - 2)
            {
                Serial.println(F("Buffer overrun. Resetting to look for next packet."));
                i = 0;
                read_until_last = false;
                return false;
            }
            if (ch == LAST)
            {
                Serial.println(F("Received LAST."));
                packet[i++] = ch;
                packet[i] = 0;
                read_until_last = false;
                return true;
            }
            else
            {
                Serial.print(F("Received char >"));
                Serial.print(ch);
                Serial.println("<");
                packet[i] = ch;
                return false;
            }
        }
    }
    return false;
}

Your setup is WAY too complex!  Simplify your setup to the point where it only deals with just the piece that is giving you problems; in your case serial port comms between master and slave.  Solve JUST THAT problem, and then move on

I have simplified my setup by removing everything  except the master and slave Bluetooth devices . i made a simple sketch to send data from the master to the slave. it still does the  same thing. it freezes then after a while it prints out all the data sent by the master device. i noticed when i increase the delay for the master to 1 second it works a lot better but won't a delay of 1 second cause a noticeable time lag when controlling the robot? Thank you

Glad to hear you simplified things, and are starting to get some encouraging results.  If increasing the Master's delay to 1sec works a lot better, then you may be on to something.  Try increasing the delay even further (2sec, 10 sec) and see if that allows the master/slave response to look more like 'real time'.  If so, you may find that the master/slave serial rate is too low, and the 1 second delay is required to get all the bytes through the channel

In any case, take your time, go very slowly, write everything down, and ONLY CHANGE ONE THING AT A TIME.  At some point you will look at your results and your notes and say "Of course, why didn't I think of that earlier" ;-).

I did what you said and noticed something. i started the masters delay from 2 secs and started gradually decreasing it by half. At 125 millisecond it was still receiving serial data normally but with a little noticeable lag sometimes. the lag doesn't last up to a second though. I'm going to modify the code for the robot slightly so it doesn't need to send as much data. in the first tutorial the baud rate he uses is 38400 but i use 9600 do you think that could be the solution to my problem? thank you

The old 9600 baud rate is ancient. Try 115200 or 230400

I tried changing the baud rate.but it didn't improve things

If you have a 'freeze' that isn't affected by baud rate, then maybe your code sets up and then dismantles the connection each time through the loop, instead of setting it up once and then keeping it open throughout the life of the program.  There HAS to be a reason, and careful experimentation and result recording WILL reveal it.

Do you think the problem i have is with hardware? because i made my code as easy as possible by sending numbers 1-255 from the master with a for loop and then receiving and printing out the received data in the Serial monitor yet it still freezes. using a baud rate of 23400 i only got what looked like random numbers. i noticed that if remove the delay entirely from the master it doesn't freeze although some data is lost.

in general, hardware is almost never the problem

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


text:
Using Flexinol Or Muscle Wire To Control Paper Flower Petal With Arduino
I am relatively new to Arduino and I am looking to use flexinol or muscle wire to control flower petals. I think I will need to control 4 sets of the wire. I have totally no idea of how to wire the components together, if I will need to get additional parts like a transistor or battery, and what type/thickness of wire I should get.

this question is not Arduino specific ... you would have the same question if you were using a Raspbery Pi or any other microcontroller

And you haven't given any information about your actual hardware. Please provide a link to the product, that you want to use (somewhere, where you can look at the datasheet of the product)

If you aren't willing to do some brain work to figure out the problem, why should we help you?


text:
Is it possible to upload and run code from EEPROM during boot time?
I am having problems while writing custom bootloader, so that it uploads code from EEPROM (for now internal, as I have no external memory in my hands) and writes into flash. After ~2 weeks of struggling I encountered these question and answers. After that, I realized that I made a mistake not checking the possibility of it. However, I am still confused about several things:

If Harvard Architecture limits what I want, how come optiboot can flash the memory from incoming UART data, which is not even a memory?

If UART reads and flashes memory accordingly, cant I do the same with EEPROM? Read bytes, erase flash, write bytes.

If it is not possible, given two answers in above link, then how does this work? I guess, it is the same logic as I want, using external memory and rewriting flash. Does it mean Harvard Architecture limits only internal memory exchange?

UPDATE: Here is what I have done for now:
In separate sketch, EEPROM is filled with binary code. Bootloader (edited optiboot v8):
  // Set up watchdog to trigger after desired timeout
  watchdogConfig(WDTPERIOD);
#if BIGBOOT

  if ((eeprom_read(0x000) == 0x0C) && (eeprom_read(0x001) == 0x94))
  {
    //while (EECR & (1 << EEPE)); //wait if previous data is still being written
    uint8_t i, j;

    for (i = 0; i < 8; ++i) // 8 pages total
    {
      uint8_t *code;
      code = buff.bptr;
      address.word = (i * 128);

      for (j = 0; j < 128; ++j)  // 128 words at a time
      {
        if (j % 64 == 0)
          LED_PORT ^= _BV(LED);

        *code++ = eeprom_read(address.word + j);
      }

#ifdef VIRTUAL_BOOT_PARTITION
      virtualBootPartition(buff, address);
#endif

      writebuffer(0x46, buff, address, 128);
    }

    while(1); // wait for WDT
  }
#endif

#if (LED_START_FLASHES > 0) || LED_DATA_FLASH || LED_START_ON
  /* Set LED pin as output */
  LED_DDR |= _BV(LED);
#endif

while my function looks like this:
#if BIGBOOT
static uint8_t eeprom_read(uint16_t addr)
{
  EEAR = addr; //read from that address
  EECR |= (1 << EERE); //enable reading

  return EEDR;
}
#endif

I use make atmega328 BIGBOOT=1 to generate hex file. It does not work + UART uploading also fails. If I set BIGBOOT to 0 and generate, UART uploading works fine.
P.S. virtualBootPartition is function which is called in STK_PROG_PAGE case. In order to not repeat the same piece of code, I collected that part into the function.
#ifdef VIRTUAL_BOOT_PARTITION
/*
 *              How the Virtual Boot Partition works:
 * At the beginning of a normal AVR program are a set of vectors that
 * implement the interrupt mechanism.  Each vector is usually a single
 * instruction that dispatches to the appropriate ISR.
 * The instruction is normally an rjmp (on AVRs with 8k or less of flash)
 * or jmp instruction, and the 0th vector is executed on reset and jumps
 * to the start of the user program:
 * vectors: jmp startup
 *          jmp ISR1
 *          jmp ISR2
 *             :      ;; etc
 *          jmp lastvector
 * To implement the "Virtual Boot Partition", Optiboot detects when the
 * flash page containing the vectors is being programmed, and replaces the
 * startup vector with a jump to te beginning of Optiboot.  Then it saves
 * the applications's startup vector in another (must be unused by the
 * application), and finally programs the page with the changed vectors.
 * Thereafter, on reset, the vector will dispatch to the beginning of
 * Optiboot.  When Optiboot decides that it will run the user application,
 * it fetches the saved start address from the unused vector, and jumps
 * there.
 * The logic is dependent on size of flash, and whether the reset vector is
 * on the same flash page as the saved start address.
 */

#if FLASHEND > 8192
/*
 * AVR with 4-byte ISR Vectors and "jmp"
 * WARNING: this works only up to 128KB flash!
 */
#if FLASHEND > (128*1024)
#error "Can't use VIRTUAL_BOOT_PARTITION with more than 128k of Flash"
#endif
  if (address.word == RSTVEC_ADDRESS) {
    // This is the reset vector page. We need to live-patch the
    // code so the bootloader runs first.
    //
    // Save jmp targets (for "Verify")
    rstVect0_sav = buff.bptr[rstVect0];
    rstVect1_sav = buff.bptr[rstVect1];

        // Add "jump to Optiboot" at RESET vector
        // WARNING: this works as long as 'main' is in first section
    buff.bptr[rstVect0] = ((uint16_t)pre_main) & 0xFF;
    buff.bptr[rstVect1] = ((uint16_t)pre_main) >> 8;

#if (SAVVEC_ADDRESS != RSTVEC_ADDRESS)
// the save_vector is not necessarilly on the same flash page as the reset
//  vector.  If it isn't, we've waiting to actually write it.
  }
  else if (address.word == SAVVEC_ADDRESS) {
      // Save old values for Verify
      saveVect0_sav = buff.bptr[saveVect0 - SAVVEC_ADDRESS];
      saveVect1_sav = buff.bptr[saveVect1 - SAVVEC_ADDRESS];

      // Move RESET jmp target to 'save' vector
      buff.bptr[saveVect0 - SAVVEC_ADDRESS] = rstVect0_sav;
      buff.bptr[saveVect1 - SAVVEC_ADDRESS] = rstVect1_sav;
  }
#else
        // Save old values for Verify
        saveVect0_sav = buff.bptr[saveVect0];
    saveVect1_sav = buff.bptr[saveVect1];

        // Move RESET jmp target to 'save' vector
        buff.bptr[saveVect0] = rstVect0_sav;
        buff.bptr[saveVect1] = rstVect1_sav;
}
#endif

#else
/*
 * AVR with 2-byte ISR Vectors and rjmp
 */
  if (address.word == rstVect0) {
    // This is the reset vector page. We need to live-patch
    // the code so the bootloader runs first.
    //
    // Move RESET vector to 'save' vector
      // Save jmp targets (for "Verify")
    rstVect0_sav = buff.bptr[rstVect0];
    rstVect1_sav = buff.bptr[rstVect1];
    addr16_t vect;
    vect.word = ((uint16_t)pre_main-1);
    // Instruction is a relative jump (rjmp), so recalculate.
    // an RJMP instruction is 0b1100xxxx xxxxxxxx, so we should be able to
    // do math on the offsets without masking it off first.
    // Note that rjmp is relative to the already incremented PC, so the
    //  offset is one less than you might expect.
    buff.bptr[0] = vect.bytes[0]; // rjmp to start of bootloader
    buff.bptr[1] = vect.bytes[1] | 0xC0;  // make an "rjmp"
#if (SAVVEC_ADDRESS != RSTVEC_ADDRESS)
  }
  else if (address.word == SAVVEC_ADDRESS) {
    addr16_t vect;
    vect.bytes[0] = rstVect0_sav;
    vect.bytes[1] = rstVect1_sav;
    // Save old values for Verify
    saveVect0_sav = buff.bptr[saveVect0 - SAVVEC_ADDRESS];
    saveVect1_sav = buff.bptr[saveVect1 - SAVVEC_ADDRESS];

    vect.word = (vect.word-save_vect_num); //substract 'save' interrupt position
  // Move RESET jmp target to 'save' vector
  buff.bptr[saveVect0 - SAVVEC_ADDRESS] = vect.bytes[0];
  buff.bptr[saveVect1 - SAVVEC_ADDRESS] = (vect.bytes[1] & 0x0F)| 0xC0;  // make an "rjmp"
  }
#else

  // Save old values for Verify
  saveVect0_sav = buff.bptr[saveVect0];
  saveVect1_sav = buff.bptr[saveVect1];

  vect.bytes[0] = rstVect0_sav;
  vect.bytes[1] = rstVect1_sav;
  vect.word = (vect.word-save_vect_num); //substract 'save' interrupt position
  // Move RESET jmp target to 'save' vector
  buff.bptr[saveVect0] = vect.bytes[0];
  buff.bptr[saveVect1] = (vect.bytes[1] & 0x0F)| 0xC0;  // make an "rjmp"
  // Add rjmp to bootloader at RESET vector
  vect.word = ((uint16_t)pre_main-1); // (main) is always <= 0x0FFF; no masking needed.
  buff.bptr[0] = vect.bytes[0]; // rjmp 0x1c00 instruction
}

#endif
#endif // FLASHEND
#endif // VBP

You can only run code from flash memory. Only the bootloader can write to flash memory. When the bootloader "exits", it will run the code on the "regular" section of flash memory. The bootloader can get the code from input it want, UART, IR, I2C, SPI. It just has to implement it, and probably some protocol on top of it, so it knows when program data start and stops. It could read from EEPROM, but that would mean your code can only be as large as the EEPROM, which is 1k, if I remember correctly, for the 328, while flash memory is 32k (minus the size of your bootloader).

I found this bootloaders: https://github.com/mysensors/DualOptiboot. It get it's program from SPI-EEPROM (where the main program downloads it from somewhere and puts it in EEPROM. Then, after a "reboot", the bootloader transfers it from EEPROM to Flash memory).

Thanks for the answer. I have thoroughly analyzed serial communication between PC and Arduino upon uploading. The code size for atmega328p (I dont know for other MCUs) is exactly 1K. I wrote EEPROM in another sketch for once, which is binary file. Then, I edited bootloader, so that, if EEPROM has anything, read and upload it, as it does when receiving UART sequence. But, unfortunately it was unsuccessful. I guess, external memory will solve this problem.

you can store that 1 kB in flash too. see the do_spm function in Optiboot 7 https://github.com/Optiboot/optiboot/blob/master/optiboot/examples/demo_dospm/demo_dospm.ino

I sound like your on the right track. Not sure why it was unsuccessful. Though your emphasis on 'serial communication' and 'upload' makes me a bit confused. I don't see how it would all of a sudden work with external EEPROM.

@Juraj I don't think that works if you want to rewrite the entire sketch itself. But maybe it can work for OP.

@Gerben, to rewrite the sketch there is my copy_flash_pages function in bootloader to bootload from upper half of the flash. https://github.com/jandrassy/ArduinoOTA/blob/master/src/InternalStorageAVR.cpp  https://github.com/Optiboot/optiboot/pull/269

Related: Is it possible to use extra AVR Flash memory as non-volatile EEPROM-like Flash memory storage?.

What you're trying to do may require editing the linker script (not even sure where that's located for Arduino at the moment).

Looks like the linker script files are located in, for example: arduino-1.8.13/hardware/tools/avr/avr/lib/ldscripts/avr1.x. I'm grasping at straws here though--not sure how to tell which one is for the ATmega328. Anyone know? Also, here's the optiboot code. It's worth studying I think to see exactly how it works, to try and see how it works, what its limitations are, and go from there: https://github.com/arduino/ArduinoCore-avr/blob/master/bootloaders/optiboot/optiboot.c. It will probably have clues to track down in datasheets and Atmel/Microchip white papers too.

I edited my post and include more explaination and pieces of code.

@GabrielStaples why would I need linker script?

to use BIGBOOT with 328p, you must change the fuses https://github.com/jandrassy/my_boards/blob/14f363387bbe70bfe66e1b6c2b7a398338d92533/avr/boards.txt#L89 while burning the bootloader

And I was thinking, why BIGBOOT without my code is not working). Thanks!

read my answer below for more know-how

If you have a sketch which can write its updated version into EEPROM of ATmega328p and then boootload from the EEPROM, then you can use the flash for the same purpose. The ATmega328p has 32kB of flash and only 1kB EEPROM.
For my ArduinoOTA library I developed a way to store the uploaded binary in upper half of the flash and then let the bootloader copy the binary to address 0 and reset the MCU.
The Optiboot 8 has do_spm() function. This function can be called from the sketch to write to flash memory.
To copy the binary stored in upper half of the flash to address 0, I wrote a new function for the Optiboot. It is called copy_flash_pages and has an extra boolean parameter to request a reset of MCU after copying the pages.
For network upload the sketch size is larger then half of the flash of 328p because of the networking library. So ArduinoOTA is only for ATmega with more then 64kB flash.
If you have a way how to get the binary of size less then half of the 328p flash, then you can write it to the upper half of the flash and then use my copy_flash_pages function to bootload it.
Resources:

header file to access the Optiboot functions from sketch
boards definition and bootloader for 328p with Optiboot with copy_flash_pages function in my_boards (note the changed fuses in boards.txt for Uno/Nano/Mini)
the InternalStorageAVR class in ArduinoOTA library as example how to store and apply the binary

Example of InternalStorage use:
  if (!InternalStorage.open(length)) {
    Serial.println("There is not enough space to store the update. Can't continue with update.");
    return;
  }
  byte b;
  while (length > 0) {
    if (!source.readBytes(&b, 1)) // reading a byte with timeout
      break;
    InternalStorage.write(b);
    length--;
  }
  InternalStorage.close();
  if (length > 0) {
    Serial.print("Timeout downloading update file at ");
    Serial.print(length);
    Serial.println(" bytes. Can't continue with update.");
    return;
  }
  Serial.println("Sketch update apply and reset.");
  InternalStorage.apply(); // this doesn't return

This almost solves my problem. However, I did not understand this: "If you have a way how to get the binary of size less then half of the 328p flash, then you can write it to the upper half of the flash and then use my copy_flash_pages function to bootload it.". ATmega328p has 32k flash and binary size is 1k.

@MiradilZeynalli, to make the next upload the uploaded code must support the upload. can you make this code so small?

Moreover, I mostly would like to solve this with bootloader as my question implies. Because, having binary in flash + program itself + bootloader can have limitations for bigger programs (without using your network library). In my case, I would like to use bootloader max of 1k (I am even planning to delete STK500 support, so I can reduce it to 0.5k).

then why do you want to go over EEPROM? the bootloader can write directly to flash. I don't understand the process you try to achieve. how is the binary transferred?

I just have to test it, to be honest :). But, I think, from your experience, you have failed to do so. Then, please correct me if I got you wrong. Even if I have already array of values (let's say I got it from bluetooth) of binary file, I can flash memory and upload code with your InternalStorageAVR class and its functions

yes. similar to this example https://github.com/jandrassy/ArduinoOTA/blob/master/examples/Advanced/OTASketchDownload/OTASketchDownload.ino

I am using internal EEPROM for now, as I don't have external one right now. What I want to achieve, is to read from eeprom and rewrite flash DURING bootloader. In application code, read binary - store binary to EEPROM - reset yourself.

I analyzed your code and as you said, it is good for small programs or larger flash MCUs. If I understand your code correctly, you are using upper half of flash as temporary storage for code and then copy it to actual program section, which is why, you need your code to be less than the size of the flash. Then my question is: is it possible to store binary not in flash but in EEPROM (or in other external memory device) and then copy it to flash using your functions?

the code to write to EEPROM is simple. then in bootloader you check if EEPROM contains a new binary and copy it to flash. and as I understand you have the code, but the new binary doesn't start?

the problem with external device is that you must code the communication over SPI or similar and it makes the code larger

Yes, I am trying to read from eeprom during bootloader and write to flash (as optiboot does). But, it seems to fail. I have included all the needed code pieces in the question.

Everything was working correctly, I was just testing it wrong. As you said, with your library I can store heavier code than EEPROM. I will still use external EEPROM, but still your answer is correct, so I marked it (despite the fact that it has been 6 months)


text:
Can you use Serial Port as a variable?
I am doing a project where, for troubleshooting reasons, I find myself often swapping components to different serial ports. Maybe one time it's in Serial, then in Serial1, maybe I need to try if software serial works.
But changing every line where Serial.print or Serial.write is written for the new port is a hassle and easy to screw up.
Would it be possible to either create a definition at the beginning of the code that lets me rename Serial to SensorSerial so just by changing that definition I am sure it will use the correct port?

Yes. The simplest way is with a preprocessor macro. Macros get replaced verbatim before compilation happens, so you can do something like:
#define MY_SERIAL Serial

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

void loop() {
    MY_SERIAL.println(millis());
    delay(1000);
}

Yes, thank you, this is exactly what I was looking for

Majenko's answer is the right answer for your question. But to answer the title of the question, if you ever need to use different Arduino outputs and inputs as variable, most of them have common type Stream or Print. So it would be:
Stream& SensorSerial = Serial;

or
Stream* SensorSerial;
SensorSerial = &Serial;

The Arduino Stream classes hierachy:

Gave the answer to the other person because it fit more precisely what I meant. But this is really helpful to know for another part of the same project

This is actually how libraries do it and I consider it superior to the preprocessor solution.

More importantly this can be leveraged at run time to switch between &Serial, &Serial2 etc.  Macros are OK for compile time.

this should be the accepted answer.


text:
RA-01 Lora Radio not turning off
am trying to completly turn off ra-01 radio and esp8266 and turn it on by external trigger but i have issues getting the lora radio to turn off
#include <LoRa.h>
#include <ESP8266WiFi.h>

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

  // disable wifi
  WiFi.mode( WIFI_OFF );
  WiFi.forceSleepBegin();

  // LoRa
  #define dio0 2
  #define ss 15
  #define rst 16
  //#define rst 32

  LoRa.setPins(ss, rst, dio0);
  LoRa.setSyncWord(0xF3);

  Serial.println("LoRa: OK");

  if (!LoRa.begin(433E6)) {
    Serial.println("LoRa: Fail!");
    while (1);
  }
  Serial.println("Sending packet: ");

  // send packet
  LoRa.beginPacket();
  LoRa.print("c");
  LoRa.endPacket();
  LoRa.end();

  // shutdown spi
  SPI.end();
  digitalWrite(dio0, HIGH);
  digitalWrite(ss, HIGH);
  digitalWrite(rst, HIGH);

  // deep sleep
  ESP.deepSleep(0);
}

void loop() {

}``

what is your question?

Turning off Lora Radio?

"but i have issues getting the lora radio to turn off" So how do you notice that you have a problem with it? Sleep current too high? Any more details available?


text:
Conversion from string to char array
I know this is Arduino Forum but I think this question is related to programming, I am using ESP8266 for the project. I need to convert the  string incoming on the serial through UART lines and receiving those using the below code. Also I am converting the received string to char array as i need to insert some more characters in between hence I need the conversion.
I have used 3 different commands to convert the above string into char array as you can see below

#include <SoftwareSerial.h>
#include <Arduino.h>

#include <stdio.h>

#include <string.h>

SoftwareSerial s; //RX TX
using namespace std;
String str= "";
String str_tx;

const char* c;
double buff[24];
unsigned long int str_len = 0;
double val;
char* token;
//char* rest = char_array;
int i=0;
void setup() {
  // put your setup code here, to run once:
  Serial.begin(115200);
  s.begin(115200, SWSERIAL_8N1, 13, 15, false, 256); //115200, SWSERIAL_8N1, 13, 15, false, 512
  pinMode(13, INPUT);
  pinMode(15, OUTPUT);

  Serial.println("in setup 1");
  Serial.println("in setup 2");
  Serial.println("in setup 3");

}

void loop() {
  // put your main code here, to run repeatedly:2
 while(s.available() >0)
 {

  char ch=s.read();
  str.concat(ch);
  if( ch =='\n' )
  { str.trim();
    Serial.println(str);
    str_tx = str;
    Serial.println(str_tx);

    str_len = str_tx.length()+1;
    Serial.println(str_len);
    //char char_array[sizeof(str_tx)];
    char char_array[str_len];
    //strcpy(char_array, str_tx.c_str());
    //str_tx.toCharArray(char_array, str_len);
    std:copy(str_tx.begin(),str_tx.end(),char_array);
    Serial.println(char_array);
    char_array[sizeof(str_tx)] = '\0';
    //char_array[65] = 0;
    str="";
    str_tx = "";
    Serial.println("------------------------------------");
  }
  /*
  str = "";
  str = s.readStringUntil('\n');
  str.trim();
  Serial.println(str);
  str_tx = str;
  Serial.println(str_tx);

  str_tx = str;
  str_tx.replace("\n","");

  str_len = str_tx.length();
  Serial.println(str_len);
  Serial.println(str_tx.c_str());*/

}

}

The output of the above code comes as below, you can see the first time conversion occurs but the next time only empty string shows up, in all the 3 cases its showing the same hence I need to find out what exactly this issue is caused by, would appreciate if anyone could thro some light on it.
Thankyou

this is not a forum ... it is a Q&A site

insert more Serial.print() statements in your code for debugging purposes ... find out if variables have the value that you expect

use readBytesUntil

It's not clear what you are trying to achieve. Avoid String objects if you can: see Reading Serial on the Arduino. If you really need a String object, see String::toCharArray() or, if you know what you are doing, String::c_str().

What are these lines for ? These seem to be syntax errors or just don't do anything.
//char char_array[sizeof(str_tx)];
char char_array[str_len];

@jsotola Noted. Thanks for the suggestion.

@Edgar Bonet Yes thats why I tried using both, thanks for the link I will go through it and let you know!


text:
Hc-05 bluetooth module pairing issue
Module light is blinking/working but it's not showing for pairing in my smart phone.I have supplied it 3.3 volts and have tried different phones.

what is your question? ... I do not see anything related to the Arduino in your post

It won't pair directly you will need other apps for pairing the modules. Try using this app. It will solve your issue for sure

You can't use that app until you connect to the device through the android OS

I put together a complete tutorial on using the HC-05 in the Arduino environment for remote programming.  You can see it here

Your tutorial doesn't explain how to troubleshoot pairing problems.


text:
Why is my transistor switched output so low?
Help needed! I am using an Arduino Nano and a general purpose npn (2n2222a) transistor to provide a 12v signal to a low current 12vdc load in an automobile. The Arudino code is set to pulse D2 at bootup/startup for .5 second. The PWM output setting was 255 (since switched to digitalWrite). However, the switched output measures only 4.5v (expected close to 12v). What am i doing wrong?
Applying 12v+ directly to the black box works. The purpose is to simulate a temporary button push in the car so an auto function is enabled.

the black box is raising the voltage on the emitter ... that in turn raises the base voltage necessary for transistor to turn on ... the nano is not able to supply that voltage .... connect the emitter to GND ... place black box at the collector .... this has been beat to death here and many places ... do research about driving a motor or solenoid or lamp with an arduinp

I did do research, and found this circuit (4th circuit, emitter-follower) which looked close to my desired application: https://www.electronics-tutorials.ws/blog/relay-switch-circuit.html#:~:text=PNP%20Relay%20Switch%20Circuit.%20The%20PNP%20transistor%20circuit,is%20more%20negative%20than%20that%20at%20the%20Emitter.

the problem with your circuit is that D2 does not rise to 12 V

How much current is needed for your black box with 12 V supply?

not much current - it's supplying a signal to an auto control unit simulating a short button press - a few milliamps at a guess.

Your schematic shows a common collector amplifier: it amplifies current, not voltage.

The problem is that you are using an NPN transistor as a high side switch.
The voltage at the emitter of the transistor will always be about 0.7V below the voltage at the base.  The "high" output from the Arduino is 5V.  The emitter will be at about 4.3V.
Have a look at the Wikipedia "emitter follower" page.  The emitter follower is also called a common collector circuit. That explains the "problem" in more detail.  It is only a problem in so far as it is not the correct solution for your task.
You need to use a "common emitter" circuit.
This usage is commonly called a "low side switch."
That would look like this:

simulate this circuit – Schematic created using CircuitLab
If your black box really needs its input pulled up to 12V, then you would do something like this:

simulate this circuit
The resistor values and transistor part numbers are place holders.  The values of resistors you will need depends on the transistors you use.  The transistor selection will depend on how much current you need to deliver to the black box.
I see in a comment that your black box only needs a few milliamperes.  In that case, the shown transistors should work just fine.  The resistor values may be a little too high, but I think they'll be OK.

A couple of additional points:

The Arduino has PWM outputs, not PCM.
The output voltage for your black box will be pulsing if you use any PWM value lower than 255.  Your black box probably won't like that, and your voltmeter won't read a correct voltage.

You should use D2 as a digital output rather than PWM.  Just turn it on or off rather than fiddling with the PWM duty cycle.  Use "digitalWrite" instead of "analogWrite" on pin D2.

Thanks, i switched to digitalWrite in the code.

The 2N2222 is an NPN device. Skipping all of the physics involved, that means that (in your application) it will sink current as a low-side switch, but not source current as a high-side switch.
If you want a high-side switch, you should find a PNP transistor. In this case your Nano pin will sink current from the transistor's base terminal.
I would recommend you stick with the 2N2222, but make two changes:

Connect your "black box" between the positive terminal (+) of your 12V supply, and the collector terminal of the 2N2222.

Reduce the size of your base resistor from 10Kohms to 1Kohms

The ground side of the black box is not available. The black box (control unit) circuit has to supply +12v to simulate the switch press.

thanks, I only had npn transistors on hand, so that's what I tried.

checked the parts bin, I also have a p-ch mosfet and nte184/185's.

@Seamus: An NPN transistor will quite happily source current as a high side switch.  Tha'ts what it does - it is an emitter follower.  What it can't do is to provide a voltage at the emitter that is higher than the base voltage.

No, Seamus, I'm not looking for a "chat room."  I spend most of my time on the electrical engineering stack exchange.  The statement "but not source current as a high-side switch" is incorrect.  As the original question shows it, the 2N2222 would try to deliver all the current available from the 12V source to the black box.  If the black box were a short circuit to ground, the 2N2222 would quickly burn out from trying to pass many amperes of current from the car battery.  So much for "not sourcing current."

As used, the black box won't consume much current (there's a comment that says it only needs a few milliamperes.)  That doesn't change the fact that an NPN transistor used as a high side switch can quite happily source current from its emitter.

Already posted an answer.

And an NPN transistor will deliver current as shown in the question.  Or haven't you tried it?

I did try my original circuit in car, but it would not provide enough voltage? to signal the control unit to switch states. A straight +12vdc line to the control unit does switch the state.

@handyguy: Right - the circuit you drew in your question won't work. The collector needs to go to the neg/gnd/- terminal of your black box, and the emitter needs to go to the GND point on your Arduino. Does this mean it's working for you now?

I do not have access to the ground on the black box. I only have access to the signal wire to the control unit, which required a +12vdc signal.

@handyguy: OK - that's easy enough to fix. I'll be glad to revise my answer if you'll consider it - let me know if you don't mind.

i don't mind, thanks

@handyguy: I wasn't clear; my apologies, but I wanted to know if you were still interested in a revised answer. If you've moved on with a solution already, there may be no point in revising this answer. OTOH, if you're still undecided as to how to proceed, I'll be glad to make the changes.

thanks, but no longer needed.

What I have thought about is using an opto-coupler

Connect the Arduino pin output to pin 1 through 330 ohms resistor, pin 2 to ground of Arduino, connect pin 4 to Vcc of 12 V and finally connect pin 3 to the black box load.
Try this configuration
Since black box only needs few milliamps as you said
May be the transistor is not saturated since base current has to go through the black box load opto-coupler s have no base current instead they use photons
Here is the circuit diagram

5 V supply looks like the Arduino pin D2 and lamp is the black box load.
This is 4N35 example

The opto coupler looks like a good idea. The part is cheap and small. If it can switch 12vdc at a few ma, it looks like the simplest solution.

ok, so i chose the 2 transistor high side circuit as i had the needed pnp transistor laying around. Works great, thanks everyone for your help. The trace (5v/div) shows the Arduino signal at 5v and the circuit output at 12v - perfect!


text:
Receiving half the value of Reference Voltage in AD7705?
I have a doubt in the AD7705 library AD7705 Library Link when I am declaring a reference voltage of 5 V and giving a reference voltage of 5 V to IN1+. On the serial monitor, I can see ADC conversion from 2.5V to 5 V when I vary the potentiometer.
whatever reference voltage I am giving it is divided by 2.
What parameter should I change to get full-scale voltage reading?
Thanks in Advance!

it is more than divided by two ... please include the schematic diagram of your circuit

If you saying you have a potentiometer, it is likely you had a voltage divider in your circuitry, and you need to convert your ADC reading to get the actual value.


text:
Set control register to low in ds3231 rtc
I have been using ds3231 rtc module for keep tracking and make alarm along with backup battery. when I used it for first time it worked fine. but now it doesn't keep track my time when the power lose it from main power but I have checked that my battrey is in safe. So I search in lot of forums they said EOSC bit was set high that would be stoped the clock as it stops the internal oscillator. also want to set it into low then only rtc keep track of the time
but in another some forums they instructed that put this following code for set it to low
DS3231 RTC;

  Wire.beginTransmission(0x68);
  Wire.write(0xF);                            // Address the Status register
  Wire.write(0x00);                           //  Zero the Status register
  Wire.endTransmission();
  Wire.beginTransmission(0x68);
  Wire.write(0xE);                            // Address the Status register
  Wire.write(0x00);                           //  Zero the Status register
  Wire.endTransmission();

  RTC.setA2Time( ADay, AHour, AMin, 0x00, true, false, false);
  delay(100);
  RTC.turnOnAlarm( 2 );

in another place showed the following code
// clear /EOSC bit to ensure that the clock runs on battery power
  Wire.beginTransmission(0x68); // address DS3231
  Wire.write(0x0E); // select register
  Wire.write(0b00011100); // write register bitmap, bit 7 is /EOSC
  Wire.endTransmission();

but now problem is that where should I want to place this code and how  to past it in proper manner for keep tracking the time when ds3231 loses power too? please any know about this problem because I finded so many people are strugling with this issue when they come forward to use this ds3231 rtc module. if any body know about how to solve this issue plese consider to share your idea this will definately help full for evryone because there is no one properly answer for this issue

I would recommend you to go with this (RTClib) library to test your module. If it works fine than you can look in related function to check how things are working there and by that way you can fix your code.

To understand the DS3231 register structure you have to look here on page 11 https://www.analog.com/media/en/technical-documentation/data-sheets/ds3231.pdf. The example code fragment you gave Wire.write(0xE); . . . Wire.write(0x00); sets the control  register (0Eh) to zero which enables the oscillator by unsetting bit /EOSC. However, I guess your problem is somewhere else because nothing should normally disable the oscillator once it is enabled.

Which library are you using for the DS3231 and to set the alarms? It is so that the same DS3231 register which controls the oscillator (0x11) also controls the alarm interrupts. If the library is carelessly written, it could, as a side effect, disable the oscillator when changing the alarm configuration. Adding code to enable the oscillator may not help much unless you can guarantee to run it the moment the oscillator is disabled and would, anyway, only be a work around..

From the DS3231 data sheet:
Control Register (0Eh)
Bit 7: Enable Oscillator (EOSC). When set to logic 0, the oscillator is started. When set to logic 1, the oscillator is stopped when the DS3231 switches to VBAT. This bit is clear (logic 0) when power is first applied. When the DS3231 is powered by VCC, the oscillator is always on regardless of the status of the EOSC bit. When EOSC is disabled, all register data is static.
Status Register (0Fh)
Bit 7: Oscillator Stop Flag (OSF). A logic 1 in this bit indicates that the oscillator either is stopped or was stopped for some period and may be used to judge the validity of the timekeeping data. This bit is set to logic 1 any time that the oscillator stops. The following are examples of conditions that can cause the OSF bit to be set:

The first time power is applied.
The voltages present on both VCC and VBAT are insufficient to support oscillation.
The EOSC bit is turned off in battery-backed mode.
External influences on the crystal (i.e., noise, leakage,etc.).
This bit remains at logic 1 until written to logic 0.

I dug out an old D3231 board. It had a battery in it but was last set ~3 years ago and I am not sure how old the battery was when I first put it in the board. The battery cannot keep the clock running. When I attached it to an Arduino UNO and booted up, the clock’s registers read as follows (just pay attention to the time and the EOSC bit and the OSF flag):
CLOCK: 00:01:15 (24h clock) Sunday, 01/01/2000  Temperature=21C  Aging offset=0
Alarm #1: 00:00:00 (24h clock) DY/DT=18[DoM mode]   Alarm selection: when date, hours, minutes and seconds match
Alarm #2: 00:00 (24h clock) DY/DT=20[DoM mode]  Alarm selection: when date, hours, minutes match
CONTROL byte=00011100 /EOSC is ON /BBSQW is Disabled /CONV is clear /INTCN mode is Match /Alarm 1 is Disabled /Alarm 2 is Disabled
STATUS byte=10000000 /OSF is ON /EN32KHZ Disabled /BSY is OFF /A1F is OFF /A2F is OFF
The clock is now running because with VCC supplied by the Arduino, the oscillator will always run. When I read the clock, I can see the time advancing, but it started from 00:00:00
Now, I remove power and after a minute or so, power up the UNO and the clock, and read the clock. It is again running, but the time had not advanced – it simply restarted from 00:00:00. EOSC is ON. OSF is ON.
With no VBAT, the time was not preserved.
A fresh battery is inserted and I power up. The clock is again running, again, restarted at 00:00:00. EOSC is ON. OSF is ON.
After a couple of minutes, I power down (with the fresh battery still in the clock). When I boot up and read the clock, it is running AND it kept running on battery power, so the current time is accurate. EOSC is ON. OSF is ON.
EOSC was always enabled (read as 0) – that is the POR value. Unless your program explicitly sets the bit to 1, EOSC will reliably be enabled. If you do disable EOSC (set to 1), the oscillator will NOT run off of the battery backup (VCC off and VBAT on). With EOSC disabled, and if there is enough juice in the battery, it will hold the time (and other registers) when VCC is switched off and VBAT is on. When VCC is on, the oscillator will always run.
But, what about the OSF flag?
Reading the data sheet, you can see that the OSF flag gets set when the oscillator stops, which can occur from a number of conditions.
It is designed so that the software can legitimately suspect that the time is not accurate, But, OSF is set as the POR value.
You need to enable EOSC AND CLEAR OSF, every time you do a clean power up and every time OSF got set because you unplugged (no VCC) and changed batteries. Also, remember, that with VCC, the oscillator will run regardless of the state of the EOSC bit.
Do not ignore OSF, it is an important flag and it should not be getting set regularly. In fact, once you insert a battery and clear OSF, it should not be set again until the battery drains. If it is getting set regularly, you have problems elsewhere.
Some software reads OSF and if it is set, the software will balk and tell you as much, as it should. Since OSF is set on POR, it will be set whenever you remove VCC and VBAT and then power up again.
You need to explicitly clear OSF AND know why it got set.
This code snippet, enables EOSC AND clears OSF.
 // enable EOSC and clear OSF flag
 // *** The other bits in these two registers are writtten
 // with POR Values or '0' if POR value=X.
  Wire.beginTransmission(0x68); // address DS3231
  Wire.write(0x0E); // select CONTROL register
  Wire.write(0b000011100); // write register (bit 7 is EOSC)
  Wire.endTransmission();
  Wire.beginTransmission(0x68);
  Wire.write(0x0F); // select STATUS register
  Wire.write(0b00001000); // write register (bit 7 is OSF)
  Wire.endTransmission();

Hope it helps.

I also have a DS3231 RTC in my robot project.  Here's my complete setup code.  This can be placed anywhere in setup():  I don't think you have to mess with individual registers to get what you want.
    if (rtc.begin()) //02/19/19 this now returns FALSE if RTC doesn't respond
    {
        Serial.println("Found RTC...");
        delay(100);
        bRTCLostPower = rtc.lostPower(); //added 10/17/18
        mySerial.printf("rtc.lostPower() reports %d\n", bRTCLostPower);

        if (rtc.lostPower())
        {
            Serial.println("RTC lost power.  Setting RTC to last compile time");
            rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));// sets RTC to last compile date/time
        }

#ifdef FORCE_RTC_TO_LAST_COMPILE_TIME
        Serial.println("Forcing RTC to last compile time");
        rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));// sets RTC to last compile date/time
#endif

        DateTime now = rtc.now();
        char buffer[100];
        memset(buffer, '\0', 100);
        mySerial.printf("Retrieving Date/Time from RTC with rtc.now() =  %ld\n", now.unixtime());
        GetDayDateTimeStringFromDateTime(now, buffer);
        Serial.print("Date/Time: "); Serial.println(buffer);
        RTC_Avail = true;
    }
    else
    {
        Serial.println("Couldn't find RTC. Real-time clock functions won't be available");
        RTC_Avail = false; //use this instead
    }

    if (RTC_Avail && rtc.lostPower())
    {
        DateTime Comp_dt = DateTime(F(__DATE__), F(__TIME__)); //__DATE__ & __TIME__ are environment variables)
        uint8_t mydayofweek = Comp_dt.dayOfTheWeek();  //returns 0 for Sunday, 6 for Saturday dayOfTheWeek
        int mymonth = Comp_dt.month();
        int myday = Comp_dt.day();
        int myyear = Comp_dt.year();
        int myhour = Comp_dt.hour();
        int mymin = Comp_dt.minute();
        int mysec = Comp_dt.second();
        long unixtime = Comp_dt.unixtime();
        char* dayofweek = (char*)daysOfTheWeek[mydayofweek];

        Serial.print("day of week value = "); Serial.println(mydayofweek);
        Serial.print("day of week value = "); Serial.println(Comp_dt.dayOfTheWeek());

        mySerial.printf("RTC lost power - setting to datetime of last compile %ld (%s %4d/%02d/%02d at %02d:%02d:%02d)\n",
            unixtime, dayofweek, myyear, mymonth, myday, myhour, mymin, mysec);

        rtc.adjust(Comp_dt);
    }

what do you mean by an individual register?


text:
L239D motor driver not able to drive motors
I am making a line follower robot. The issue is trying to make the motors run.
The L239D module has 4 input pins (to control two motors), 4 output pins (to drive motors), and 6 power pins (5V, 5V, GND, GND, 9/12V, and 9/12V).
I have used one 5V pin to connect it to an Arduino's 5V supply and one of the 9/12V pins to two 9V batteries in series.
The motors are barely running and when the robot is on the ground it is not able to move. I even tried three 9V batteries in series to get the voltage up to 27V but it doesn't help.

Is your motor being drived when you hold it in the means when it is not placed on the ground

yes , when it is in hand i do see it getting rotated but not on ground

9 V batteries, assuming you mean the little PP3-size ones, can't supply the current needed for driving robot motors; they are intended for low-current applications.
Putting them in series will give you a higher voltage, not more current, and the higher voltage could damage something else in the circuit.
Assuming you connected everything correctly, including ground: you need bigger batteries. Even 6 AAs in series would be much better than using a 9V battery for getting your robot to move.

If i can connect 3 9V batteries in parallel, is that going to help! , as the current is the requirement.

Have you tried batteries in parallel

It will help a little, but they will be empty very quickly. Make sure they are at about the same voltage before connecting them in parallel.

On your next try use a different H-Bridge, one with MOSFET outputs, you can have a voltage drop across the L239D of 2.4V. Measure the voltage at the motor and at your batteries you will see what I am getting at. You might want to try connecting the motors directly to the battery first to see if it will do what you want.

I guess using 9 Volt battery in parallel will do your work because if the motor is moving as you quoted above means it is getting the voltage but not enough current to drive it, please connect the 9 volt battery in parallel and it will work for you


text:
legality of streaming data on 868 or 915 Mhz in EU/US
From what I read about duty cycles in the EU there is a 10% limitation (even less in some sub bands).
The modules I found have a max. rate of 300 kbps. Even if you max out the duty cycle that would only be 30kbps.
How do consumer devices like a digital walkie talkie operate here legally in the EU?
What am I missing?
Is there a frequency where I can legally stream constantly at more than 70kbps (not Wifi) ?

Anything in the 2.4GHz band. There's more than just WiFi that works at that frequency.

868MHz and 915MHz are ISM (Industrial, Scientific and Medical) bands which has both power and throughput limitation. It is designed for short burst of data, not for streaming as it is a shared resource. For walkie talkie, it operates on other unlicensed band like sharing the band with WiFi on 2.4GHz. If you need the bandwidth, use 2.4GHz.


text:
I want to make two arduino to communicate over different wifi. Is that possible?
I want to make any 2 Arduino module from different places to communicate over wifi. I really need to know if it possible? If yes, advice me more about it. I want send data from sensor module from one Arduino to another and vice versa. That's the basic idea. Do I need a third party services such as cloud services to make it happen? Or simply can send ovee wifi with the help of Ip adress. Sorry, I have less knowledge on this. Help me out. Thank you in advance.

If they are on the same (wifi) network; then yes.
If you are on a different network, it would be more difficult. You would have to setup port forwarding on your router. Then you would have to somehow know the public IP address of the other router. These addresses can change from time to time with certain ISPs. I wouldn't advice doing this.
Instead I'd go with an third party service. For example Adafruits offers an MQTT server. I'd probably use this even if they are on the same network.


text:
I need help creating a code that moves a DC motor CW or CCW based off of 2 different buttons
I know I can make the motor move backwards and forwards with buttons but I don't want it to move at full speed. I want it to increment in very small amounts to where it can be adjusted very small amounts at a time. I should also be able to hold the button so it moves continuously. I also have a motor with an encoder on it. Maybe there is a way to use the numbers on the encoder to increment? so press the CW button and now the motor wants to move till the encoder reaches +10 from where it was at? I understand what I want to do, just need help getting there. Thanks
HERE IS THE CODE I FIGURED OUT THAT MAKES MY DC MOTOR INCREMENT CW AND CCW

#define MOTOR_DIRECTION_PIN   2
#define MOTOR_SPEED_PIN       3

#define MOTOR_DIRECTION_CW    LOW
#define MOTOR_DIRECTION_CCW   HIGH

void setup()
{
  //button inputs
  //pullup so we do not need to include a physical resistor
  pinMode(12, INPUT_PULLUP);
  pinMode(13, INPUT_PULLUP);

  pinMode(MOTOR_DIRECTION_PIN, OUTPUT);
  pinMode(MOTOR_SPEED_PIN, OUTPUT);

  Serial.begin(9600);

  Serial.println("test");
}

void loop()
{
  int pushedButtonOne = digitalRead(12);
  int pushedButtonTwo = digitalRead(13);

  if(pushedButtonOne == LOW)
  {
    Serial.println("Button number 1 has been pushed");
    digitalWrite(MOTOR_DIRECTION_PIN, MOTOR_DIRECTION_CCW);
    analogWrite(MOTOR_SPEED_PIN, 50);
    delay(7);
    analogWrite(MOTOR_SPEED_PIN, 0);
  }

  else if(pushedButtonTwo == LOW)
  {
    Serial.println("Button number 2 has been pushed");
    digitalWrite(MOTOR_DIRECTION_PIN, MOTOR_DIRECTION_CW);
    analogWrite(MOTOR_SPEED_PIN, 50);
    delay(7);
    analogWrite(MOTOR_SPEED_PIN, 0);
  }
  else
  {
    Serial.println("nothing has been pushed");
  }

  //delay(100);

}

Your first problem is selecting a type of motor. I would suggest a stepper motor for what you want to do. Those let you control the motor's position in very small increments.

@DuncanC Yeah I have used stepper motor. There is another application I want to extend off of this and it led me to a DC motor. I want it to work for both

What do you mean with "until it reaches +10"? 10 encoder clicks? That wont work with a DC motor, unless it is a geared one. DC motors are made to spin, not to step. Use a stepper motor, if you want to step. You can still let it rotate continously

@chrisl yeah so say the motor turns on and its at position 0 on the encoder. If a button is pushed I could make the motor move CW(or CCW, just depends on whatever button i push) until the encoder reads 10 and then it turns the motor off or stops it? Is this something that could work?

Most encoders have more than 10 tics per full rotation. That means, that 10 tics might be like a half rotation. DC motors are not meant for such precision positioning. You can try it, but instead of a half rotation you might as well get a 3/4 or a full rotation (that depends on your motor). Also you need to calculate the timing with regard to the acceleration and deceleration of the motor. If your lowest count is in the range of a few full rotations, then it might work with a DC motor. If you want full tic precision, use a stepper motor.

@chrisl Okay, I will try that thank you

Here is the code i eventually figured out. It increments my DC Motor basically by activating it for a small amount of time in the direction of whichever button was pushed.
#define MOTOR_DIRECTION_PIN   2
#define MOTOR_SPEED_PIN       3

#define MOTOR_DIRECTION_CW    LOW
#define MOTOR_DIRECTION_CCW   HIGH

void setup()
{
  //button inputs
  //pullup so we do not need to include a physical resistor
  pinMode(12, INPUT_PULLUP);
  pinMode(13, INPUT_PULLUP);

  pinMode(MOTOR_DIRECTION_PIN, OUTPUT);
  pinMode(MOTOR_SPEED_PIN, OUTPUT);

  Serial.begin(9600);

  Serial.println("test");
}

void loop()
{
  int pushedButtonOne = digitalRead(12);
  int pushedButtonTwo = digitalRead(13);

  if(pushedButtonOne == LOW)
  {
    Serial.println("Button number 1 has been pushed");
    digitalWrite(MOTOR_DIRECTION_PIN, MOTOR_DIRECTION_CCW);
    analogWrite(MOTOR_SPEED_PIN, 50);
    delay(7);
    analogWrite(MOTOR_SPEED_PIN, 0);
  }

  else if(pushedButtonTwo == LOW)
  {
    Serial.println("Button number 2 has been pushed");
    digitalWrite(MOTOR_DIRECTION_PIN, MOTOR_DIRECTION_CW);
    analogWrite(MOTOR_SPEED_PIN, 50);
    delay(7);
    analogWrite(MOTOR_SPEED_PIN, 0);
  }
  else
  {
    Serial.println("nothing has been pushed");
  }

}

To formulate the comments into an answer:
In principle it is of course possible to put an encoder onto a DC motor shaft and then drive the motor, until you reach the desired position. But you won't get good precision or accuracy with this. You wrote

till the encoder reaches +10 from where it was at

Since most encoders have more than 10 tics per full rotation (you didn't specifiy how much yours has), this can mean  rotating only a fraction of a full rotation. Let's assume, that the encoder has 40 tics per full rotation. With 10 tics you have a quarter rotation. It seems you want precision in the range of about 1 tic.
DC motors are made for spinning relatively fast. They don't give you control over the position with steps. They mostly have very few coil/magnet combinations (for example just 2 coils, which are switched internally). Thus you have just an inert motor shaft, which is driven by the motor. It will need time to accelerate and to decelerate. With most motors, you may even get a half or full rotation, when you wanted only a quarter rotation (the 10 tics). Calculating the correct timings to get it any better will be not easy for relatively small reward. DC motors are not made for rotations below a small number of full rotations.
You could tackle that problem by using a geared DC motor. The shaft after the gears will run slower and thus have the explained problem not so badly. Then you have to live with the smaller speed.
Or you could go a more proper way and just use a stepper motor, which is made for small steps in the range of sub-full-rotation. It is a bit more difficult to drive (also depending on the driver circuit), but it gives you the position control, that you want. And to rotate continuously: A continuous rotation on a stepper motor is nothing else but step after step taken in fast succession (much like running is a fast succession of steps with your feet).

Note: The stepper motor does not have a feedback like an encoder on it. The motor driver will just drive the coils to step the motor. If the motor is stalled or if it is overloaded, you might loose some steps (meaning that the coils are driven for the steps, but the motor doesn't actually move). You could sense that with an additional encoder on the motor shaft. But in most cases that is not necessary. If you just make sure, that the motor is not overloaded at any time, you will be fine. Or you might not worry about some steps being lost sometimes, if the overall precision is good enough. That is your decision.

I actually somewhat figured it out doing a simpler way of just shutting the motor off after a short delay. Ill throw the code the made into my original post.


text:
Measure audio frequency through pulse duration
Hello dear StackExchange users,
i want to develop an Infrared blaster which i can plug into the headphone jack of a phone or console of choice. In order to communicate what frequency to modulate the diode with and how long to send pulses, i simply generate tones for the Arduino to read and interpret.
My problem is that i can't reliably measure the frequency with it. In order to measure the frequency i use an Analog Comparator Interrupt and trigger at falling edge, thus getting always the interrupt after a full pulse occured. I called micros() at every interrupt in order to get the pulse duration, but it was too imprecise. Then i tried using Timer0 with a prescaler of 8 to measure the frequency, but it only counts to 255.
Now i switched over to Timer1 because of it's bigger TCNT register. However for some reason it already overflows at 255 even though i didn't set the OCR1 registers.
This is my current code. Please note that the actual frequency calculation happens in the main loop to not mess with the measurements gained in the ISR.
const int setFrequencySound = 1000;
const int receiveDataSound = 2000;
const int receiveDataEndSound = 3000;

const int readyMode = 0;
const int setFrequencyMode = 1;
const int receiveDataMode = 2;
const int sendDataMode = 3;

volatile unsigned long timeBefore;
volatile unsigned long timeNow;
volatile unsigned long delta;
volatile float audioFrequencyBefore;
volatile float audioFrequency;

volatile float irFrequency;
volatile int irData[100];
volatile int irDataIndex;

volatile int mode = 0;

ISR (ANALOG_COMP_vect)
{
timeNow = TCNT1;
Serial.print (timeNow);
Serial.println (" TCNT1");
//TCNT1 = 0; //reset timer register
}

void setup ()
{
Serial.begin (115200);
Serial.println ("Started.");
ADCSRB = 0;           // (Disable) ACME: Analog Comparator Multiplexer Enable
ACSR =  bit (ACI)     // (Clear) Analog Comparator Interrupt Flag
      | bit (ACIE)    // Analog Comparator Interrupt Enable
      | bit (ACIS1);  // ACIS1, ACIS0: Analog Comparator Interrupt Mode Select (trigger on falling edge)

TCCR1B |= (0 << CS12) | (1 << CS11) | (0 >> CS10); //Activate timer and set prescaler to 8
TCNT1 = 0; //Reset timer register
}  // end of setup

void loop ()
{
//Calculate frequency by using the period duration
//determined through the timestamps captured in
//ISR method.
//delta = timeNow - timeBefore;
audioFrequency = 1000000000.0 / (float(timeNow) * 2.0);

if (millis() % 1000 == 0)
{
  Serial.print (audioFrequency, 5);
  Serial.print (" Hz, ");
  Serial.print (timeNow);
  Serial.println (" TCNT0");
}

//Do not process the same frequency multiple times
if (audioFrequency != audioFrequencyBefore)
{
  switch (mode)
  {
    case readyMode:
      if (audioFrequency == setFrequencySound)
      {
        mode = 1;

        Serial.println ("Start setting IR frequency.");
      }
      else if (audioFrequency == receiveDataSound)
      {
        mode = 2;

        Serial.println ("Start receiving IR data.");
      }
      break;
    case setFrequencyMode:
      irFrequency = audioFrequency + 25000;

      Serial.print ("IR frequency set to ");
      Serial.print (irFrequency, 10);
      Serial.println (" Hz.");

      mode = readyMode;
      break;
    case receiveDataMode:
      if (audioFrequency == receiveDataEndSound)
      {
        Serial.println ("Stop receiving IR data.");

        mode = readyMode;
        irDataIndex = 0;
      }
      else
      {
        irData[irDataIndex] = audioFrequency;

        irDataIndex++;

        Serial.print ("IR pulse received: ");
        Serial.print (irData[irDataIndex]);
        Serial.println (" microsecs.");
      }
      break;
    case sendDataMode:
      Serial.println ("Sending IR data...");
      break;
  }
}

audioFrequencyBefore = audioFrequency;

}  // end of loop

Please show a full compilable code (including the loop function). Serial printing in an ISR is not a good thing. You can very fast fill up the serial buffer that way. What frequency are you trying to measure? Since the signals on a standard headphone jack are often differential (for example in the range of +-1.2V) how are you processing the signal before feeding it into the Arduino?

Of course serial printing in the ISR isn't a good idea, but i gotta get my info somehow. When that issue is fixed, i'll remove this print command. The frequency i'm trying to measure is the audio frequency of a signal that i generate. No song, microphone input or anything, just a simple square tone i generate. Well, multiple tones.

Timer 1 overflows at 255 because that's how it has been configured by
the Arduino core, as it is intended to provide 8-bit PWM. If you want
to use the timer in normal mode, you should undo the Arduino's
initialization by setting TCCR1A to zero.
Two comments on the ISR:
ISR (ANALOG_COMP_vect)
  {
    timeNow = TCNT1;
    Serial.print (timeNow);
    Serial.println (" TCNT1");
    //TCNT1 = 0; //reset timer register
  }

First, as has been stated in a previous comment, you should not print
from within an ISR. Also, if you want consistent timing, you should
never reset the timer. Just keep it freely running and use time
differences to get the signal period. Do not worry about the timer
overflowing: if you do the computation with unsigned 16-bit integers
(uint16_t), you will be immune to the overflows. If you reset the
timer you will likely loose some ticks, as you can not read it and reset
it in the same clock cycle.
Lastly, I recommend you read about the “input capture” capability of
Timer 1. This is a feature of the timer designed for solving the exact
kind of problem you have here: the timer will automatically record a
timestamp on an external event. You can have this triggered by a rising
or falling edge on input pin 8, or by the analog comparator if you
prefer. This method gives you zero jitter, which cannot be achieved with
code, even running within an interrupt.

Edit: Answering an extra question in the comment.

Could i connect the audio wire [...] directly to pin 8 and use the
input capture functionality?

It depends on the shape of the signal that comes out of this wire.
First, you have to make sure the signal always stays between the
electric potentials of GND and Vcc (i.e. 0 – 5 V), otherwise you risk
damaging the Arduino.
Note that if the signal comes from a high impedance source, it can
safely go somewhat beyond this range, as the Arduino has all of its
inputs protected by diodes. You just have to limit the current in the
diodes to less than 1 mA. In other words, for each kΩ of output
impedance, you can extend the (unloaded) acceptable voltage range by 1 V
on each side. If the source is low impedance, you can make it high
impedance simply by adding a 10 kΩ resistor in series.
Second point is, you have to make sure the signal has a large enough
voltage span to make the digital input switch between LOW and HIGH.
According to the datasheet of the ATmega328P, when powered at 5 V the
input thresholds are typically around 2.1 V for switching LOW and 2.6 V
for switching HIGH. The difference between those thresholds provides
some hysteresis, which can help cancelling noise. Note that those are
typical values. If you want guaranteed switching, the signal should go
below 1.5 V to get a guaranteed LOW reading (this is VIL) and
above 3 V to get a guaranteed HIGH reading (VIH).
Note also that, if the input thresholds of the digital pin do not fit
your needs, you can use the analog comparator as a trigger for the input
capture.

Interesting, so the timer-1 tip would work on all 328p based Arduinos right? +1

@Tim_Stewart: Indeed. It's a feature of the ATmega328p (and many other ATmegas), not of the Arduino board that hosts it.

@EdgarBonet Could i connect the audio wire (i have a jumper cable hooked up to the left channel of a headphobne plug) directly to pin 8 and use the input capture functionality?

@MyFairJulie: See amended answer.

@EdgarBonet In fact i already use an analog comparator as seen here. Can just set up the input capture interrupt? Or do i still need the analog comparator interrupt?

@MyFairJulie: If you use the input capture feature of Timer 1, the the input capture interrupt is probably the best place to get the timestamps.


text:
Wemos D1 / Witty Cloud D8 doesn't behave as expected
When using D8 in the code doesn't work, nothing happens, but replacing D8 with 15 works like a charm. And to test this I created the code below. I know that D8 has worked earlier, but I don't remember which version I was using at that time, but it was a yer or more ago.
Environment:

Arduino IDE ver. 1.8.13
ESP8266 board ver. 2.7.4
Witty Cloud or my add on version to WeMos D1 (https://oshpark.com/shared_projects/r3NRvNjx)
WeMos D1 R1 chosen in Board manager

// "Witty Cloud" test program

// A0 - LDR resistor
// D2 - Button
// D6 - Green LED
// D7 - Blue LED
// D8 - Red LED

// Constants won't change. They're used here to set pin numbers:
const int LDR = A0;
const int BUTTON = D4;
const int GREEN = D6;
const int BLUE = D7;
const int RED = D8;

void setup()
{
  Serial.begin(115200);
  pinMode(LDR, INPUT);
  pinMode(RED, OUTPUT);
  pinMode(GREEN, OUTPUT);
  pinMode(BLUE, OUTPUT);
  pinMode(BUTTON, INPUT);
}

void loop()
{

  delay(1000);

  Serial.println("");

  Serial.print("LDR: ");
  Serial.println(analogRead(LDR));

  digitalWrite(RED, HIGH);
  digitalWrite(BLUE, LOW);
  Serial.println("--- Red ---");

  delay(1000);
  digitalWrite(RED, LOW);
  digitalWrite(GREEN, HIGH);
  Serial.println("--- Green ---");

  delay(1000);
  digitalWrite(GREEN, LOW);
  digitalWrite(BLUE, HIGH);
  Serial.println("--- Blue ---");
}

Have you looked at the core of your board? In wiring.c (i think) these makros should be defined. Are they defined with the pin number or the bit number in the port?

I actually found the error, check, https://github.com/esp8266/Arduino/blob/master/variants/d1/pins_arduino.h and found the row static const uint8_t D8   = 0; bummer

D1 R1 has different pin mapping then R2 and mini

Now I see my mistake, I chosed a "WeMos R1" and not "LOLIN(WEMOS) D1 Mini".... why has WeMos changed to LOLIN ?


text:
esp32 voltage divider readings off
Trying to read from a voltage divider circuit using two 240 Ohm resistors.  Getting a reading of 6.0, when it should be 1.65.  Circuit is powered by a bench 3.3V and both the Huzzah32 and circuit are grounded.  Using USB for the Huzzah32. Any thoughts?
  void setup()
{
  Serial.begin(9600);
}
void loop()
{
  int sensorValue = analogRead(A9);
  float voltage = sensorValue * (3.3 / 1023.0);
  Serial.println(voltage);
  delay(1000);
}

Please add the schema.

My multimeter reads the correct Vout...

this gets me closer, but still low... float voltage = (sensorValue * 3.3) / (4095);

ESP32 chips have a problem with ADC and WIFI at the same time.  Maybe disable WIFI ?

both the Huzzah32 and circuit are grounded ... are the grounds joined? ... your schematic does not show a common ground

Some clarification: I picked A9 because it is a none-wifi pin.  In regards to common ground, my circuit drawing sucks.  They have a common ground.  The final answer is to subract .12 from my input values after multiplying by 3.3 and dividing the esp 12 bit increments (4095).  Thanks for input!

First, ESP32 ADC is 12-bit, not 10-bit. therefore the formula should be:
float voltage = sensorValue * (3.3 / 4096.0);

Secondly, ESP32 ADC is not really linear, and tend to have lower reading than the actual value. You will need to do some calibration if you want to get a more accurate reading. You can take a look at my github on esp32-adc-calibrate.


text:
What is the most efficient voltage divider for Arduino?
I need to make voltage divider, so I could read a battery voltage up to 14.4 V. Could I use very high resistance resistors for that, so the current would be very low (to not to discharge battery)?
On the Internet there are examples with 500 - 2000 ohm resistors, but could I use hundreds of thousands to reduce the current to minimum? Would Arduino's analog input still read the value?

I think I've seen power management IO, that could measure current, voltage and provide its readings through I2C line. So it might be the correct way how to do it. INA3221?

This sounds like a project that isn't going to do what you think it is.  Are you trying to build a battery tester?  To tell you if your tool batteries are still good?

The most efficient is not to have a voltage divider at all. Or at least to only have a voltage divider when you actually need one.
My preferred schematic is this:

simulate this circuit – Schematic created using CircuitLab
With this M1 is normally kept turned off by R3. When you want to take a measurement you turn on M2 by setting D3 HIGH (or whatever pin you attached it to) which pulls down the gate of M1 turning it on. This then connects the batter to the voltage divider R1/R2 and allows you to read the voltage at A0.
The voltage divider of 20k / 10k allows you to read up to 15V on the battery, and gives you an output impedance of 6.67kΩ which is within the recommended maximum of 10kΩ for the ATMega's ADC.
During "idle" times when M1 and M2 are both off the only current flowing is the minuscule leakage current through M2 tempered by the large 100kΩ resistor R3 (which itself pales into insignificance compared to the "off" resistance of M2 anyway).
Selecting M1 so that the ON resistance is very small (<0.1Ω) allows you to essentially ignore it in your calculations since that will be swamped by the tolerance of R1 and R2 anyway.  M2 needs to be selected so that it is "logic level" (i.e, with a gate threshold V_GS well below 5V).
This double-FET arrangement should be used rather than just using an N-channel FET in the ground connection of the divider because when that simpler arrangement is turned off the Arduino will be seeing 12V directly connected to A0 which really is not good - you will kill the Arduino - so it is important that you switch the "high" side of the network not the "low" side, and to do that requires two FETs.

What are some jellybean FETs for this purpose?

@PeterMortensen I'd probably use the BSS138P (n channel) and the IRLML5203 (p channel) in a sot-23 footprint.

Yes, you can use very high value resistors for your voltage divider.  But the recommended maximum is 10 kohms for the ADC pins.  So the combined resistance of your two resistors should be maximum 10 kohms.

it is recommended that whatever you connect to the A/D have an output impedance of 10k or less for best accuracy. This is to allow the A/D input capacitor on the sample and hold to charge up in the time allotted to it between switching the input multiplexer over and starting the conversion.

From: Input Impedance of A0-A5

Note that calculating output impedance is not as simple as adding the resistors together. The resistors are actually calculated in parallel not series, so two 20k resistors would give 10k output impedance.

There are more details in another source.

I was able to implement it with 3 MΩ resistors.
The problem is that the readanalog() function executes 10 reads. So the first one is the right value and then you will not measure the right value anymore.
Solution: A voltage divider with 2.5 MΩ and 500 kΩ with a 470 nF capacitor on the 500 kΩ resistor. The solution with the MOSFET is better. This is easier, and it works (but only for 20 years ).

This is a variation on Majenko's design above. It was such a good idea, I couldn't resist submitting this - a reduced-component-count version:

simulate this circuit – Schematic created using CircuitLab
The TPS22810 is a load switch that enables or disables Vout (2.7V ≤ Vin ≤ 18V; Iout ≤ 3A). The output is determined by the EN/UVLO input that may be driven by a 1.8 V, 3.3 V or 5 V GPIO output. This component and the C1 bypass cap replaces 2 FETs and 2 Resistors. The TPS22810 cost is ≈ $0.50 ea. in small quantities.
The TPS22810 will likely find its most useful application as a high-side switch, but it seems to serve the purpose of the OP's need for driving a voltage divider also.

Everybody is missing the point here.  The lower limit on the series resistance of the voltage divider is the self-discharge rate of the battery.  For instance, a Li-ion battery loses about 10% of its charge per month.  For a 3000 mAH 18650 cell, that's about 300 mAH per month, meaning about 300/(30X24) = 0.42mA constant drain.  So, for a 8V stack made of 2 18650 cells in series, we get a total series resistance of 8V/0.42 of about 19K-ohms.  IOW, if I put a 19K resistor across an 8V stack, I would get about the same battery drain as the battery would see if I left it completely alone.  As long as the series resistance is much greater than that, it won't affect the battery life at all.  So, if I use 2ea 50K resistors for a total series resistance of 100K, it will have very little effect on battery life.  2ea 50K resistors will present an effective output impedance of about 25K to the ADC input port on a MCU, and that is low enough so there will be little or no distortion of the measured voltage, and any offset can be easily compensated out in software.  Moreover, if you want to go to a higher division ratio (say 4:1 instead of 2:1) the effective output resistance goes DOWN because it's a parallel circuit from the ADC's POV, but still a series circuit from the battery's POV.  If I use a 75/25K divider for a 4:1 ratio, the parallel output impedance is 18.75K.
So, no need for fancy switching circuits - just choose a series divider with a convenient ratio and with a total series resistance in the 100K range, and you are done.

I don't see any problem with reasonably high resistors (however see below). You are right that they would discharge the battery less.

Would Arduino's analog input still read the value?

Of course, if there was a voltage there to read. Why wouldn't it? A really high resistance might let the reading be affected by stray voltages.
A possible work-around would be to only take the reading occasionally, say, every 10 seconds. You could do this by making the reading be between a couple of Arduino pins, and leave one "floating" until you are ready to read it.
However that is not a good idea for reading a 12V battery. You need the voltage divider to be "active" so you don't have 12V on the Arduino input pin. Majenko's suggestion sounds better in that respect.
I have a lengthy discussion about the ADC on the Atmega328P. Reply #5 on that page discusses how it takes its measurements. This is done by charging a "sample and hold" capacitor. With too high an input impedance the capacitor would charge too slowly, and thus the subsequent sampling would give incorrect readings. A source signal impedance of 10k is recommended in the datasheet, so a voltage divider along those lines would be appropriate.
Majenko's suggestion of 20k + 10k would only involve a 0.4 mA constant current flow through the voltage divider, which for a 12V battery is probably not a huge deal (even without all that switching circuitry).

What is the actual (DC) input impedance?

The input impedance is 100 MΩ, but there are other considerations.

One reason it might not be able to read the voltage is that the Auduino's analog input will put a load on the voltage divider. Assuming the Auduino's input acts like a resister connected to ground (which is only an assumption for purposes of argument), then it will be connected in parallel with the 'bottom' resister of the voltage divider. This will alter the resistance and cause the Auduino to read a lower voltage than expected.

@David42 That's right. In fact I have a lengthy discussion about that (too lengthy to post here) on my page about the ADC in the Atmega328P. I'll edit that link into  my answer.

@NickGammon Reading at your answer and post about ADC, it seems to me that the simple solution proposed by Adriano should work great. That was to add a capacitor in parallel with the resistor connected to ground. What would be the problem of that?

I'm not sure why Adriano says that readanalog() executes 10 reads. The function on the Uno is analogRead() and it only executes one read. I think the best solution is to disable the voltage divider until it's required, as proposed by both Majenko and Seamus.