text:
Is there a maximum length of an array in ROM?
Consider the following code:
    #include <Arduino.h>

    unsigned char testimage [] = {
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    ... many more rows ...
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
    };

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

        Serial.println("start");

        for (int i = 0; i < 10; i++) {
            Serial.println((int)(testimage[i]));
        }

        Serial.println("stop");

    }
    void loop()
    {}

I found out that then the array gets a certain size, there is nothing being sent to the serial monitor. It looks like the entire program freezes. I do not even see the start message appear.
I haven't tried to find the exact size, but it is somewhere between 4500 and 8000. (When sized around 4500, it works, when around 8000 it doesn't).
When I do not address the array though, I do see the start and stop messages appear.
I am using an Arduino ATMega2560.

does not work is a vague description of a problem ... what happens exactly? ... what were you expecting to happen? ... please add the info to the question ... do not write a comment

Mega has 8000 bytes large SRAM

It isn't clear whether you meant to put your array in ROM as your question implies, but the code you presented assigns it to RAM. That would surely restrict to your array to less than the 8K of of RAM minus whatever is needed by (globals + your libraries' statics + your code's statics + the stack).
Update:

I assumed the data section of the code would end up in ROM.

In fact, an image of the initialized data section does become part of the ROM image. The initial values need to be saved somewhere so RAM can be initialized each time the program is(re-)started but it is not accessed from ROM during run-time. (Note we're not talking about PROGMEM data here, which is kept in ROM and accessed from there even at run-time.)

Thanks. I assumed the data section of the code would end up in ROM. I guess the example code seems to be completely wrong ;).

In this case the RAM size is the limit. And you'd need some space for stack/heap,..
If you use non-const array, it'll be copied from flash to RAM at the startup
On the mega2560 even using const it still be copied into the RAM as each FLASH/RAM/EEPROM has different address space
Only way would be using PROGMEM and it can't be used directly (again different address spaces for flash/ram)
You can guess the mega2560 has 8KB RAM and you should keep some RAM for runtime. If there isn't enough of space, the stack and heap will be smashing each other and it would behave completely unpredictably (overwritten return addresses, runaway code and so on)


text:
How to use a DF Mini Player Busy Pin to start an LED Sequence?
I'm using a DF Mini Player with my Arduino Uno project I keep getting stuck on the same point - how to trigger my LED sequence.  I discovered, through some google searching, that utilizing the BUSY pin on the DF Player Mini would return data that I was hoping I could use to trigger the sequence.
My code is as follows:
// Wed 17 Aug 2023; Modified BUSY_PIN INPUT_PULLUP to INPUT to accomodate for player keeping track of it's own state of HIGH or LOW, fixed BAUD rate mismatch

#include <DFRobotDFPlayerMini.h>
#include "SoftwareSerial.h"
#include "DFRobotDFPlayerMini.h"
#define BUTTON_PIN 4
#define BUSY_PIN 8

bool buttonState = 1; // Normally high, goes low when pressed
bool previousButtonState = 1; // Because we will test when CHANGED

///////////////Create the Player object/////////////////////////////
DFRobotDFPlayerMini player;

static const uint8_t PIN_MP3_TX = 2; // UNO Tx connects module's RX
static const uint8_t PIN_MP3_RX = 3; // UNO Rx connects module's TX
SoftwareSerial softwareSerial(PIN_MP3_RX, PIN_MP3_TX);

//////////////////////////////////////////////////////////////////

/////////////////Create Fairy Light Variables////////////////////

int led = 11;           // the PWM pin the LED is attached to
int brightness = 3;    // how bright the LED is
int fadeAmount = 2;    // how many points to fade the LED by

////////////////////////////////////////////////////////////////

int busyState = 0;
int prevBusyState = 0;

void setup()
{

  ///////////////////////Button Trigger//////////////////////////

  pinMode (BUTTON_PIN, INPUT_PULLUP); // Avoids need for resistor

  ///////////////////////////////////////////////////////////////

  pinMode(BUSY_PIN, INPUT); //check to see if song is still playing

  ///////////////////////Music Functions/////////////////////////

  // Init USB serial port for debugging
  Serial.begin(9600);
  Serial.println();
  // Init serial port for DFPlayer Mini
  softwareSerial.begin(9600);
  delay(1000);

  // Start communication with DFPlayer Mini
  if (!player.begin(softwareSerial, true, false)) {  //Use softwareSerial to communicate with mp3.
    Serial.println(F("Unable to begin:"));
    Serial.println(F("1.Please recheck the connection!"));
    Serial.println(F("2.Please insert the SD card!"));
    while (true) {
      delay(0);
    }
  }

  busyState = digitalRead(BUSY_PIN);
  prevBusyState = busyState;

  ///////////// End Music Functions/////////////////////////////

  ////////////////////Fairy Lights//////////////////////////////

  pinMode(led, OUTPUT); //declare pin 11 to be an output

  //////////////////End Fairy Light/////////////////////////////
}

void loop()
{

  buttonState = digitalRead(BUTTON_PIN);
  busyState = digitalRead(BUSY_PIN);

  if (busyState != prevBusyState) {
    if (busyState == LOW) {
      Serial.print ("song is playing. lights are go");
      Serial.print('\n');
      Serial.print('\r');

      /////////////////Fairy Light Fading Routine////////////////////////
      // set the brightness of pin 10:
      analogWrite(led, brightness);

      // change the brightness for next time through the loop:
      brightness = brightness + fadeAmount;

      // reverse the direction of the fading at the ends of the fade:
      if (brightness <= 1 || brightness >= 240) {
        fadeAmount = -fadeAmount;
      }
      // wait for 30 milliseconds to see the dimming effect
      delay(45);
      /////////////////////////////////////////////////////////////////
    }
    prevBusyState = busyState;
  }

  if (buttonState == LOW && previousButtonState == HIGH)
  {
    /////////////////////Play Song///////////////////////

    // The following NOT inside the previous if()
    // Set volume to maximum (0 to 30).
    player.volume(23);
    // Play the first MP3 file on the SD card
    player.play(1); // i.e. usually file 0001.mp3

    ////////////////////////////////////////////////////

  }
  previousButtonState = buttonState;
}

When I check my Serial Monitor, I am getting my print song is playing. lights are go. However the LED (which are Fairy Lights) do not follow the sequence. In fact, they just stay on the entire time. I even added a 10k resistor to Data input 11 - which only dampened the light intensity but otherwise did no other effect.
I'm not sure if I will need to control these lights with another board, code is not sufficient or if I'm missing something in the wiring. I would have thought the power source would be the issue, but if the LED's are getting power through data, I would think the resistor would take care of that issue?

your problem has nothing to do with the DF player, in fact it is just clutter in the question ..... forget about the DF player for now, that part works ... write simple code that turns the lights on for one second, turns lights off for one second and repeats

so the fade code that im using in my sketch is actually part of the arduino built in examples (01. basics > fade). Which works when its not nested inside the if statement - but the tradeoff is that it "works" at all times with no trigger.

then there is something wrong with the if statements ... add debugging code to your program

well thats actually the thing, I put in a Serial.print ("song is playing. lights are go"); to run if/when BUSY state is picked up by my code in the serial monitor. That does actually come through. But the Light sequence does not. Thats the thing that keeps confusing me. I thought for sure once I got my Serial Monitor to read that, I would have success, but that was not the case :(

like I said before ... write a new program that only turns the lights on and off ... no DF player code

source: Stack Exchange

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

sort: votes


text:
Code not Executing Reliably on Push Button Activation
I have put together the following code to activate a motor using an Arduino Uno via  push buttons.

Two push buttons should be pressed simultaneously to activate the motor for a specified number of steps,
then when both buttons are pressed again the motor will spin in reverse, returning the motor to its original position.

The code works, but not every time the button is pressed. I've gone through every line of the code and can't seem to find the issue. I know that the connections are correct since the code executes sometimes, but I don't know if there is an error in the code causing the unreliable response or if I have faulty/cheap push buttons with bad connections.
    #include <Bounce2.h> // Include the Bounce2 library

    // Define stepper motor connections:
    #define dirPin 3
    #define stepPin 2
    #define motorEnablePin 4 // Motor driver's enable pin
    #define buttonPin 8 // Push button connected to pin 8
    #define buttonPin2 9 // Push button connected to pin 8

    boolean motorRunning = false; // Flag to track motor rotation
    boolean oddRotation = true; // Flag to track odd/even rotations

    // Create a Bounce object for the button
    Bounce debouncer1 = Bounce();
    Bounce debouncer2 = Bounce();

    void setup() {
      // Declare pins as output or input:
      pinMode(stepPin, OUTPUT);
      pinMode(dirPin, OUTPUT);
      pinMode(motorEnablePin, OUTPUT); // Enable pin as output
      pinMode(buttonPin, INPUT_PULLUP); // Use internal pull-up resistor for the button
      pinMode(buttonPin2, INPUT_PULLUP); // Use internal pull-up resistor for the button
      digitalWrite(dirPin, LOW); // Set the spinning direction CW/CCW
      digitalWrite(motorEnablePin, HIGH); // Disable motor driver initially

      // Attach the debouncer to the button pin
      debouncer1.attach(buttonPin);
      debouncer2.attach(buttonPin2);
      debouncer1.interval(50); // Set debounce time
      debouncer2.interval(50);
    }

    void loop() {
      // Update the debouncer
      debouncer1.update();
      debouncer2.update();

      if (debouncer1.fell() && debouncer2.fell()) {
        // Button pressed and motor is not running, initiate motor rotation
        motorRunning = true;
        oddRotation = !oddRotation; // Toggle the rotation direction

        int stepsPerRevolution = 200; // Number of steps for one full revolution
        int desiredRevolutions = 10;  // Number of desired revolutions
        int totalSteps = stepsPerRevolution * desiredRevolutions;
        int stepCount = 0; // Counter for the steps taken

        // Set the motor rotation direction
        digitalWrite(dirPin, oddRotation ? LOW : HIGH);

        // Enable the motor driver
        digitalWrite(motorEnablePin, LOW);

        while (stepCount < totalSteps) {
          // Rotate the motor
          digitalWrite(stepPin, HIGH);
          delayMicroseconds(600);
          digitalWrite(stepPin, LOW);
          delayMicroseconds(600);

          stepCount++;

          // If the desired number of rotations is reached, stop the motor
          if (stepCount >= totalSteps) {
            // Disable the motor driver
            digitalWrite(stepPin, LOW);
            digitalWrite(motorEnablePin, HIGH);

            // Reset the flag to stop motor rotation
            motorRunning = false;
          }
        }

        // Disable the motor driver when idle
        digitalWrite(motorEnablePin, HIGH);
      }
    }

Bounce.fell() returns true only if the input fell since the last update(). So your code will only work if both buttons are pressed at exactly the same time.
I suggest that you record the time at which each button is pressed and execute your code if the press times are less than 100ms apart. That should give reliable operation.
You can test if this is the problem simply by removing the debouncer2.fell() call. The code should then work reliably when only button 1 is pressed.

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


text:
Understanding flow of current with pull-up and pull-down circuits
I am new to all of this and was trying to figure out what was happening with pull-up/pull-down circuits.  I think I understand what happens when the board handles the pull-up/pull-down but I wanted to try to build the circuits.  I got help from another forum.  Once I made the circuits, I found that I don't understand the path that the voltage is traveling.  I have 2 examples with multimeters attached.
Pull Up
I understand the press of the button connect circuit to ground.  But why does the voltage everywhere go down to zero when it is connected to ground?  Does it have something to do with the multimeter can't read the voltage because the current is taking the path of least resistance - which I have read is a myth?

Pull Down
When compared to the Pull Up, why does the voltage go to 5 before the yellow wire when the button is pushed?  Isn't it connected to the ground again which seems like it should cause the same scenario as the Pull Up where they all read zero.  Or does the resistor before ground have something to do with this.

I know nothing about electronics.  Some information and links where I could find more information would be great.  Thanks.
All the gifs are screen recordings from circuits I built with circuits.io.  I want to get into making somethings but wanted to practice first before I spent any money.

It goes down to 0V because ground is the voltage reference.

It's very hard to read your circuit, because there are wires everywhere. However this is effectively what a switch and a pull-up resistor looks like:

Due to the pull-up, pin 8 on the Arduino (which the switch is connected to) is normally pulled-up to 5V if the switch is open.
When you close the switch pin 8 becomes 0V, thus your meter reads 0V.

On the other hand, with a pull-down resistor, the circuit looks like this:

Now pin 8 is normally zero volts with the switch open, and when closed pin 8 is connected to 5V to pin 8 becomes 5V.

See my tutorial on switches for more details.

What happens with the flow of current and the resistor to make one example read high and the other low.

Imagine a door with a spring on it to close it. The spring is like a pull-up (or pull-down) resistor (depending on whether you are trying to keep the door closed or open).
The spring gently pulls the door shut. However if you barge out of it with a handful of pizzas in your hand your override the spring. In the absence of the spring the door would just flap in the breeze, sometimes opening and sometimes closing.
The point is, a person is strong enough to force the door open, despite the spring. Similarly if you close the switch you override the pull-up (or pull-down) resistor.

Where does the 5V go when the switch is closed.

It flows through the resistor to ground (or 5V depending on which one you are talking about).

When the switch is open in the pull up example - is voltage going through the resistor? From what I'm reading online, in the pull up case voltage isn't traveling through the resistor until the button is pressed.

Voltage doesn't "go through" a resistor, current does.

With the switch open, effectively a tiny amount of current goes through the resistor to pin 8. It is a "high impedance" input which means it puts a very small load on the input. Thus there is a very small voltage drop over the 10k resistor, and almost the full 5V is presented to the input pin for reading.
To work out the exact amount, we can look at the datasheet which says that the maximum leakage current through an I/O pin at 5V is 1 µA. Now using Ohm's Law we can find the voltage drop over the 10k resistor:
V = I * R
V = 0.000001 * 10000
V = 0.01 V

Thus with 5V at the 5V pin of the processor, and a (maximum of) 1 µA consumed at pin 8, it will therefore have 4.99 V at the pin, which therefore reads HIGH.

With the switch closed, then we use Ohm's Law to calculate the flow through the resistor:
I = V / R
I = 5 / 10000
I = 0.0005 A

Thus 0.5 mA flows through the resistor with the switch closed. This is not enough to damage the resistor, or make a significant load on the 5V line.

I think you are getting confused (as I did when I was young) that a big resistance (like 10k) must "resist" a lot of voltage. It is easy to think that after going through 10k resistance there can't be much "voltage" left.
The fact is, though, that the voltage on the other end of a resistor is proportional to not only the resistance (R) but also the current (I). This is Ohms's Law (V = I * R)
So, if the current is very small (as is the case with an input pin) then the voltage drop over a resistor - even a large one - is very small.
So, the idea of a pull-up resistor is, that with no external influences (like a switch) then after passing through 10k resistance, there is still 5V at the other side.
Let me issue you with a challenge. Find a voltage source (eg. a battery). Measure it with your multimeter. Let's say you have a 5V source which is the Arduino 5V pin. Now get a 10k resistor. Put it in series with the 5V source. Now measure it on the other side of the resistor. Depending on the quality of the meter (and thus how much current it takes to measure a voltage) you will get very close to the same voltage reading. In my case I had 5V on one side of the resistor, and 4.99V on the other side. This is exactly what my calculations above predicted.

Thanks for the diagrams.  Maybe this is very basic, but can you explain why the pin takes current from the path without the resistor?  Like for the pull up, once the switch closes the pin is still connected to the 5v pin, but why does it use the ground pin to get a voltage of zero.   And if I put a multimeter on the section between ground and the switch, why would it read zero instead of 5?

What pin? In both diagrams pin 8 is connected to a resistor. In one it pulls the pin high (a pull-up) and in the other it pulls it low (a pull-down).

Sorry, I should have been more descriptive.  Yes, pin 8.  When the switch is closed in both examples pin 8 is connected to both ground and 5V.  What happens with the flow of current and the resistor to make one example read high and the other low.  Like in the pull up, all three pins are connected so what property or law of electricity makes it switch from 5V to 0V when it is still connected to the 5V.  Where does the 5V go when the switch is closed.  Path of least resistance comes to mind but I have read that that statement is a myth.  Thanks.

See my amended answer.

Thanks for working me through this.  When the switch is open in the pull up example - is voltage going through the resistor?  From what I'm reading online, in the pull up case voltage isn't traveling through the resistor until the button is pressed.  If this is the case, why does the input pin read 5V when the button is up if the voltage has to travel through the resistor from the 5V pin.

First, think of voltage and current this way:  Voltage is water pressure, current is the water flowing through the pipes.  Next, digital inputs normally have high resistance to ground and/or power lines.  So, without the button pressed, a trickle of current is still flowing through the pull up or pull down resistor.  But that trickle of current is enough to change the voltage at the pin.

When the switch is open in the pull up example - is voltage going through the resistor? - yes, that is why it is called a pull-up.

See my amended reply.

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


text:
Why/when to use IoT publish/subscribe protocols rather then RESTful HTTP?
I am sending data (GPS coordinates) from Arduino once a minute with HTTP POST request to REST API (in OpenShift PaaS). Data is then stored to MySQL db.
Would so called "IoT" publish/subscribe protocols (XMPP, MQTT) be better? Why?
When exactly do you use those two protocols rather than Restful HTTP? Would I really save a significant baterry energy using them?
AFAIK in those protocols machine would "publish" a data to broker and my app would subscribe to it. If I would like to gather data every minute in my app I guess that I would got to have some CRON job that would subscribe to data every minute? Or how would data gathering be achieved?

Your arduino won't change, other that instead of a POST package to your webserver, it sends a MQTT packet to a MQTT server. You won't get any difference in battery usage. I'm still trying to figure out what's so special about MQTT, especially if you are already proficient in MySQL and something like PHP.

In my experience ReST is good for real-time data transfer and processing but has a lot of overhead for simple message passing. Plus, there's no queuing in it so store-forward configurations are troublesome.
MQTT is a message queue transport system where the message can be placed on the channel by the publisher and will stay there until the subscriber picks it up. So you can have some rudimentary store-forward capabilities with this. Also MQTT is more transparent and multicast so communicating to many nodes is no different than communicating to one.
With that, each have their place and use and ReST is great for sending large items (JSON blobs), sending data for calculation and getting it back, and for requesting a specific dataset. MQTT is more for "here's my sensor data every second, enjoy".

(shameless self-promotion)  I did a talk on iot stuff this year at our local code camp.  Notes are here: https://github.com/adbacker/bcc2016/blob/master/2016bcc-iotonthecheap.pdf
Super simplified per my limited experience:
(experts correct at will :-)  )
MQTT protocol:

requires a broker
maintains a connection to the broker (which allows for push notifications back to the device)
was specifically designed for "small footprint" applications (read: limited RAM and processing power)

MQTT is optimized for sending simple data.  GPS coordinates would be a good fit. I'm sure MQTT could be used to send complex data (ie: large json objects) but that doesn't seem to be what it's designed for.
You're not looking for push notifications back to the device, nor are you maintaining a connection to the REST server so (from a practical standpoint) I'm guessing your battery life improvement would be minuscule at the very best converting the solution to mqtt.
Adafruit has a pretty good mqtt tutorial and libraries, as well as a beta service that provides broker services: https://learn.adafruit.com/adafruit-io/mqtt-api
Also, for super-duper-easy IOT setups (that admittedly use a custom protocol), let me recommend blynk.  ( www.blynk.cc )  It's free and so easy I rewrote my entire presentation around it.  Additionally, there are (free) blynk ios and android apps that allow creation of custom dashboards that communicate (via the also-free blynk broker) with your device of choice.  If you host the broker server (also free) yourself, it has it's own REST api that allows data access to/from your device.

Basically, MQTT reduces latency where there's relatively high latency like Wi-Fi by keeping the TCP connection alive so that data can be published and received very quickly. It uses port 1883 and not 80.
As I understand it, the publishers and subscribers connect once to the broker and then ping the broker regularly to keep the connection alive; how often the broker is pinged depends on the pre-agreed keep-alive period. MQTT packets are also significantly smaller than HTTP requests. If the connection is somehow broken, the client repeatedly tries to re-establish the connection and when successful, the subscribers re-subscribe.
Subscribers define callbacks that are called after a topic has has been updated by some publisher. MQTT is best for time-critical jobs where HTTP requests would just take too long and where quick notification of changed topics is desired. I'm not sure but it will probably consume more battery power, since there's that matter of a constant TCP link to the broker.
Since you're only expecting data updates every minute, I think it makes more sense to connect and GET the feed data from the server every 60 seconds. You can use the feed's Last-updated time-stamp (if it doesn't exist, create one) to check if the feed has been updated by the Arduino yet. An MQTT technique would just spend most of the time connected to a broker for no reason since you already know that the update events occur every minute; that is a significant amount of time and power spent waiting for predictable data.
However, you could wait for about 55 seconds, subscribe to the topic and when you get the new data, you disconnect and then wait for 55 seconds again, though I dont know if this will be much of an improvement over REST. If you use this method, you can also set the keep-alive period to be just about 10 seconds, so that the Arduino has enough time to update the feed before your app is notified and there's no need for regular pings.
If you decide to go with MQTT, check out this Arduino library.

MQTT node does not poll broker except keeping connection alive on TCP level. If a message is available for the node, it is send by the broker to the node at that time.

In my applications, the biggest power drain is turning on the radio to transmit data. I often keep the radio off, collect data points, and then turn on the radio to send multiple pieces of data together as one request using a RESTful HTTP call. For my case, RESTful HTTP is way more efficient since I do not need an always on connection.

authors: محمد الكويكبي

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


text:
Arduino Wifi/Wemos Wifi D1 adding &t=0 to simple GET request
I'm attempting to make a simple get request to my website from my arduino, but I'm unable to do so.
I keep getting the following error:
<html>
  <head>
    <meta http-equiv="refresh" content="0;url=http://dnserrorassist.att.net/search/?q=http://www.example.com/&t=0"/>
  </head>
  <body>
    <script>
      window.location="http://dnserrorassist.att.net/search/?q="+escape(window.location)+"&r="+escape(document.referrer)+"&t=0";
    </script>
  </body>
</html>`

Edit: Here's the important code.
const char http_site[] = "www.example.com";
const int http_port = 80;

// Perform an HTTP GET request to a remote page
bool getPage() {

  // Attempt to make a connection to the remote server
  if ( !client.connect('http://' + http_site, http_port) ) {
    return false;
  } else
  {
    Serial.println("Connected!");
  }

  // Make an HTTP GET request
  client.print("GET /");
  Serial.print("GET /");

  client.println(" HTTP/1.1");
  Serial.println(" HTTP/1.1");

  client.println("Host: xxx.xxx.xxx.xxx:1995");
  Serial.println("Host: xxx.xxx.xxx.xxx:1995");

  client.println("Connection: close\r\n");
  Serial.println("Connection: close\r\n");

  return true;
}

void loop(void){

  if ( client.available() ) {
    char c = client.read();
    Serial.print(c);
  }
}

That doesn't look like an error to me. Can you give more detail? What is your code?

That's very true. It looks like a URL parameter is being added, but I'm not adding it anywhere.

It may not like the IP address in the "Host:" line. See 3.2.2 http URL

Hey, I figured it out. It didn't like two things: 1. the IP in the Host, and 2. http:// in the client.connect.

client.println("Host: xxx.xxx.xxx.xxx:1995") sounds wrong to me. It should be either client.println("Host: xxx.xxx.xxx.xxx") or better client.println("Host: www.example.com")

@Gerben, yes. You're right. I had to change that to the host I was calling. I've never worked with this stuff before, so it's been quite the learning experience :)

Did that fix your problem?

what ide do you use? is that in arduino ide?

Yes, I'm using the Arduino IDE.


text:
Are (how much are) interupts interfering I2C or SPI communication?
I am thinking over an autonomous rover.
One of the features/components of the rover will be ability to know how fast is the rover moving and what distance did it travel. I would like to use dedicated attiny85 chip for that. The chip will use rotary encoder and interrupts to detect motion. It will be connected throught I2C/SPI (do not know yet) with the main controller. Main controller will ask the attiny85 on speed and distance if needed.
The problem is, I guess, that rotary encoder will use interrupts and so the I2C or SPI may not work properly. I could disable interrupts while communicating but:

Motion sensing won't be precise, as I will loose some motion data.
When attiny85 will be on receiving side, it wont know soon enough that it should disable the interrupts.
There is a chance that SPI/I2C uses the interrupts as well, not sure, have to check.

Am I right? What would you advise?

If your interrupts are brief enough I can't see them being a problem. 90% of the SPI or I2C communication is done in hardware anyway and won't be affected by the interrupts - it's only between each byte that you will be doing anything, and that may be done in interrupts (depending on your implementation) anyway which will mean other interrupts are disabled at the time.

@Majenko Thanks a lot. So this concept is worth trying you say. I will try it and then post the experience.

Certainly worth trying.

@Divisadero how did it work? I'm thinking about using the software serial library with I2C, and I would like to know if interrupts cause problems for I2C communication.

@daweim0 I was/am too busy, didnt get to that. I played a bit with I2C and interrupts and it dependes on the I2C speed. If you do not need high bitrate, you will be fine. But be sure to use hardware I2C for sure.

authors: Сергей Эктов


text:
Need help with ATtiny85 code
I am looking for help with ATtiny85 coding. The project I am working on is using an Arduino Nano and I want to switch to an ATtiny85.
The code below works with the Nano but not with the ATtiny85. I am relatively new to Arduinos and have done a few projects with success but this is my first time using an ATtiny.
I will try to explain. When the code is running on a Nano

It is checking for a number between 1 and 32 in the EEPROM at address 0.
If the number is outside either value it will generate a random number between 18 and 32.
I then check to see if the value at address 0 in the EEPROM is less than or equal to 0, if not it will decrement that value and store the new value in address 0.
Once the value is at 0 or less a separate value is generated for a time delay.
Once that time delay has occurred pin 7 outputs power for 1 second and stops.
Once that has occurred a new random number is generated and stored in address 0.
To decrement the value the Nano is powered off and on again and the check is made.

I have tested this code with a Nano multiple times and with pin 7 connected to an led it turns on and off, resets and begins again. When I load this code onto an ATtiny85 and run the same test the led will not turn on, also I get an error with the Serial.begin(9600) and anything else starting with Serial, so I comment them out and it compiles and uploads just fine. I have the Spark Fun AVR programmer and was able to get the ATtiny to blink an led using a simple led blink sketch but that's as far as I got. I need some help.
    #include <EEPROM.h>  // Include the EEPROM library

    void setup() {
      Serial.begin(9600);          // Initialize the serial communication
      pinMode(7, OUTPUT);          // Use digital pin 7 as output
      randomSeed(analogRead(0));   // Seed the random number generator with a random value
      int value = EEPROM.read(0);  // Read the value stored in EEPROM address 0

      if (value <= -1 || value > 32) {  // If the value is not between 1 and 32
        int new_Value = random(18, 32);  // Generate a new random number between 18 and 32
        EEPROM.write(0, new_Value);    // Store the new value in EEPROM address 0
        Serial.println("Generated a new random number: " + String(new_Value));
      }

      else if (value <= 0) {     // Check if the random value is less than or equal to 0
        value--;                 // If no then decrement the value
        EEPROM.write(0, value);  // Write the new value to EEPROM address 0
        Serial.println("Random number from EEPROM: " + String(value));
      }

      else {
        int time_delay = random(1, 25);  // Generate random number for time delay
        Serial.println("Generated Time Delay: " + String(time_delay));

        delay(1000 * time_delay);

        digitalWrite(7, HIGH);
        delay(1000);
        digitalWrite(7, LOW);

        int new_Value = random(18, 32);  // Generate new random day value
        EEPROM.write(0, new_Value);    // Write new value to EEPROM address 0
        Serial.println("Generated a new random number: " + String(new_Value));
      }
    }
    void loop() {
    }

Sketch used for LED blink
    void setup() {
      pinMode(0, OUTPUT);
    }

    void loop() {
      digitalWrite(0, HIGH);
      delay(5000);
      digitalWrite(0, LOW);
      delay(5000);

does not work is not a useful description of a program behavior ... what exactly happens when you run the program?

was able to get the ATtiny to blink an led ...look at your blink LED code and compare to this code

Have a look at this answer: https://arduino.stackexchange.com/a/47616/37523

@VE7JRO, I will give that a try, thank you.

if the blink program works, then why did you not use the same pin for your program?

When you put this code on the nano you use pin 7.  When you put it on the ATtiny85 what pin number do you use?

if (value <= -1 || value > 32) - I don't see how a single byte, which will range between 0 and 255 could ever be less than 0.

@NickGammon value is of type (signed) int so it can be less than 0

@SBF EEPROM.read() returns uint8_t which is unsigned. I realise value can hold negative numbers, but since its value is put there by EEPROM.read() it won't, in this particular case, ever be negative.


text:
Micropython installation on Arduino nano
I am currently trying to use micropython on an arduino Nano 33 BLE using MacOS. Following the instructions from arduino website I was able to complete steps 1-3. At step 4, I can find the bossac file but when I try to run the provided command:
bossac -e -w —offset=0x16000 —port=usbmodem14201 -i -d -U -R file.bin
the terminal says no device found on usbmodem14201 which is a port appearing under the nano board in the IDE.
As a sanity check I ran serialportlist in matlab and the same port was returned when the Nano is plugged in.
I even ran ioreg -p IOUSB in terminal and found the nano:
‘’’ Arduino Nano 33 BLE@14200000 <class AppleUSBDevice, id 0x100008674, re$ ‘’’
That 142… number didn’t work either.
What am I doing wrong?

Welcome to Arduino StackExchange:

Firstly your computer translates double dashes into single long dashes. the dashes should be double dashes (--) for options such as --offset, --port, etc. The command should be:
bossac -e -w --offset=0x16000 --port=usbmodem14201 -i -d -U -R file.bin

but I can see that your computer translated these -- to those — ?

Before you try to upload code confirm that the board is recognized by the system using the ls command:
ls /dev/cu.*

This should list all serial devices and you should see something like /dev/cu.usbmodem14201 in the list if your board is connected.

Ensure that you have the necessary permissions to access the serial port. You can try running the bossac command with sudo to run it as the superuser:
sudo bossac -e -w --offset=0x16000 --port=usbmodem14201 -i -d -U -R file.bin

Instead of just the port name usbmodem14201, you might need to use the full path like /dev/cu.usbmodem14201:
bossac -e -w --offset=0x16000 --port=/dev/cu.usbmodem14201 -i -d -U -R file.bin

Check that the Arduino Nano 33 BLE is in the bootloader mode. Typically, this can be achieved by double pressing the reset button. When it's in bootloader mode, the board might appear on a different port. Check the ports again with ls /dev/cu.* after you double press the reset button.

If you try all those and still it doesn't work maybe you should try installing latest drivers or check compatibility. Anyways, good luck.


text:
Single #include pulls in all libraries
I am tracking down the memory usage of an Arduino-like project I am working on (not a real Arduino, but has same microcontroller and it uses the Arduino build environment, version 1.6.8). I have some modules that I am using and placed them in the Libraries directory in my sketch directory:
Encoder
LiquidCrystal
OneWire
TGPages
TGPro

Now, when I compile a minimal sketch...
#include <Arduino.h>

void setup()
{
}

void loop()
{
}

...the compiled size is 450 bytes Flash and 9 bytes RAM. So far, so good.
Now here's the weird part: when I include a single header file from anywhere in the Libaries folder, the compiled size increases dramatically.
#include <Arduino.h>
#include "pins.h"

void setup()
{
}

void loop()
{
}

"pins.h" is located in the TGPro directory and only contains #defines, not even code or other includes.
....
Using library TGPro in folder: C:\Users\User\Project\TG\libraries\TGPro (legacy)
Using library OneWire in folder: C:\Users\User\Project\TG\libraries\OneWire (legacy)
Using library Encoder in folder: C:\Users\User\Project\TG\libraries\Encoder (legacy)
Using library LiquidCrystal in folder: C:\Users\User\Project\TG\libraries\LiquidCrystal (legacy)
Using library EEPROM at version 2.0 in folder: C:\Users\User\Project\TG\hardware\arduino\avr\libraries\EEPROM
Using library Wire at version 1.0 in folder: C:\Users\User\Project\TG\hardware\arduino\avr\libraries\Wire

Sketch uses 2,266 bytes (7%) of program storage space. Maximum is 32,256 bytes.
Global variables use 230 bytes (11%) of dynamic memory, leaving 1,818 bytes for local variables. Maximum is 2,048 bytes.

And I'm like: WTF? I'm not even referencing any of the files, still they get pulled in, wasting space. There are a few global, static variables in there which explain the used space and referenced code.
So, my questions:

Is het normal for Arduino to pull in all files in the Sketch\Libraries directory, regardless if they are referenced or not? It doesn't seem to do this with the 'core' libraries.
How can you prevent this? Suppose I have a large collection of modules that I use in various projects, but not all modules are used all the time. It would be a waste to include code that is never actually used.
How can I find out more about the code that is compiled in; I know the linker will leave out unreferenced code, but I want to make sure this is due to the statically defined variables.

avr-nm -C the_compiled_program.elf should tell you what's in there (your question 3).

What you are experiencing is due to the fact that your use case does not match with the Arduino foreseen use cases of "importing a library".
Basically you want the use case "include a file" and you get "import a library". The use case "import file" is simply not foreseen in the Arduino IDE.
Because the Arduino IDE add the library to your code it also adds the source doe files to your code. When these source codes contain global variables (which is very common and not a bad practise in embedded world) these will be part of your final code. As such your sketch will increase size even if you do not use these global variables.
To answer questions
1) yes it is normal because the use case "include file" is translated into "include library" in .ino files in the Arduino IDE.
Why this does not happen for the core? The core is first linked into a archive and then linked to the sketch. This leaves the linker more options to remove stuff.
2) I think the easiest is to copy the pins.h file in your sketch work folder (and you probably will need to restart the Arduino IDE).
Another option is to go for a real IDE like the arduino eclipse plugin called sloeber (which I develop)
In sloeber you could link to the pins.h file instead of copying. You could also reference the pins.h with a (partial/full) path avoinding the library include.
3) All global variables, static and similar stuff in the source code of the "imported libraries"

I know that Arduine pulls in the source code. However, my understanding so far is that if I include, say "lcd.h", it would import "lcd.cpp" together with its includes, and so on. I do not expect (nor want) everything to be pulled in, just because the file is in a particular directory.  2a) pins.h is already in the sketch folder, under Libraries. 2b) Copying files is of course unaccaptable; that will create a versioning nightmare. The idea is to share files between projects (sketches), of course. 2c) What would sloeber accomplish? 3) yes, Edgar Bonet's comment already gave a few hints.

that would be the use case "import class". I have never seen this usecase anywhere in c/c++.
2a) yes but it is there in such a way that also the c/c++ files are there.
2b) you could consider making a library only containing pins.h
2c) added 2 options to the answer.


text:
Accelerometer Z Value off a significant amount, all other values reasonable
I'm using the MPU9255 Accelerometer to measure acceleration in the X,Y, and Z directions.  As per the datasheet, I've applied a scaling to the raw digital values based off of whether I specified +- 2G, +- 4G, +- 8G etc.  This scaling works fantastically, but there is consistent noise on the Z axis, far greater than that of gravity's 1G of force.  Here is a sample output
ACCELEROMETER-X
0.7226562500
ACCELEROMETER-Y
0.1523437500
ACCELEROMETER-Z
7.9707031250

ACCELEROMETER-X
0.7460937500
ACCELEROMETER-Y
0.1875000000
ACCELEROMETER-Z
8.0468750000

As you can see, there is about 7G of noise on the Z axis. I calculated the scaling with this code:
//Get accelerometer scaling based off of how many G's per of variation the system was tuned to handle
int16_t getAccScalar(int16_t system_scale){
  int16_t acc_scalar = 16384;
  short scalar = 1;
  if(system_scale == ACC_FULL_SCALE_4_G){
    scalar = 2;
  }
  else if(system_scale == ACC_FULL_SCALE_8_G){
    scalar = 4;
  }
  else{
    scalar = 8;
  }
  acc_scalar /= scalar;
  return acc_scalar;
}

And then in configuration I use a register writing function with this header:
void I2CwriteByte(uint8_t Address, uint8_t Register, uint8_t Data)

and call it with these values
I2CwriteByte(MPU9250_ADDRESS,28,ACC_FULL_SCALE_2_G);

Anyone know why this is happening? Thanks and have a squanchy day.

I suspect are just looking at the 1G from gravity and your scaling is off; What happens when you turn the accelerometer on its side?

When you turn the accelerometer on its side, all the force transfers to the other axis as expected.  But here's the thing, the scaling I'm using is perfect scaling for X and Y, so why is Z so far off? It's the same scaling for all 3 axes.

The accelerometer scaling value was off from the one that I set as the actual scaling, so scaling was indeed the problem. Thanks.

Accelerometer static errors are usually not anywhere near that large, so I suspect your scaling code is not behaving correctly. You could verify this by turning the accelerometer on its side and see if the Z axis retains a +7G value, or if the X/Y axis instead becomes too large.


text:
Drv 8871 shield: is VM for the motor power supply?
I bought a simple board on AliExpress with DRV8871 soldered on top, the ILIM resistors and 2 capacitors for filtering.
There is a screw terminal block 4 positions on one side, labelled OUT1 and OUT2 and POWER+ and POWER-. This is clearly for motor outputs, motor power supply, and ground.
On the other side there is IN1 and IN2 for logic control, another ground (short circuited with the other one) and VM. Is VM the same of power+? If yes why do they put the same pin twice with different names?

refer to the datasheet for the board for description of the connections

In the drv8871 datasheet there is no mention to power+ and power-, only to vm and power ground, this is why I was wondering about the reason to introduce 2pins with different name in the shield

Welcome to SE/Arduino! Please take the [tour] to learn how this site works, and read "[ask]" and other pages of the [help]. Then come back to [edit] your question to address all comments. Do not add a comment for that, this is not a forum.

Please re-engineer the board and follow the traces to get a schematic. For example, you will find that power+ and VM are connected, or not. But because we have no access to the board, this is your task.

why do they put the same pin twice with different names? ... because that is what they chose to do


text:
ESP8266 - Can't upload or use Serial Monitor - Ubuntu 22.04 LTS
When trying to use the ESP8266 Node MCU or Multiple Feather Huzzah's I get the following error. I can program Arduino Uno & Mega without issue.

warning: espcomm_sync failed
error: espcomm_open failed
error: espcomm_upload_mem failed
error: espcomm_upload_mem failed

I have tried all the many fixes on the web, the real issue is that all of these devices work fine with a windows machine. Also I use VMM and QEMU, I built a Windows 10 VM and Ubuntu 20.04 - When I share ttyS0 with either of these VM's I can program the 8266 just fine, but I can not directly from my host running 22.04. I can work with the VM's but I would rather not.
Any help would be appreciated.

I'm curious to know whether or not you can connect to an already programmed board and get serial data in and out of it.

all of these devices work fine with a windows ... then your problem is with linux serial port ... nothing to do with Arduino ... you are asking at the wrong place

is it this problem? https://arduino.stackexchange.com/questions/86211/fail-upload-sketches-to-esp8266-only-on-ubunto-20-04-3/86214#86214

@timemage - I had the same issue will 4 esp8266's all had code running on them. The issue ended up being a conflict or something with the CP210x driver. I found this solution in a separate post - it fixed my issue and I was able to replicate and validate this worked on a second 22.04 machine.

I found this solution in a separate post - it fixed my issue and I was able to replicate and validate this worked on a second 22.04 machine.
systemctl stop brltty-udev.service
sudo systemctl mask brltty-udev.service
systemctl stop brltty.service
systemctl disable brltty.service

this solution work also for me. thanks a lot. but what a stupid error.


text:
shift register 74HC595 enable specific pin
Its driving me crazy for some couple of days now and i don't get the answer.
I'm busy to setup a irrigation system with a shift register 74HC595 and a 8 channel relay board.
I see a lot of sketches where it looks like you can turn a specific relay on but i dont get the clue.
I like to turn on a specific relay based on a button press.
Is it possible to turn on a specific relay based on the representing button?
Im using the shiftOut option. The code im using now is :
//#define BLYNK_DEBUG
#define BLYNK_PRINT Serial

#include <ArduinoOTA.h>
#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>
#include <TimeLib.h>
#include <WidgetRTC.h>

#include <ESP_SSD1306.h>    // Modification of Adafruit_SSD1306 for ESP8266 compatibility -> https://github.com/somhi/ESP_SSD1306
#include <Adafruit_GFX.h>   // Needs a little change in original Adafruit library (See README.txt file) --> https://github.com/adafruit/Adafruit-GFX-Library
#include <SPI.h>            // For SPI comm (needed for not getting compile error)

#include "settings_base.h"
#include "globals.h"
//#include "functions.h"
//#include "blynk_writes.h"

//Pin connected to ST_CP of 74HC595
const int latchPin = 15; //D8
//Pin connected to SH_CP of 74HC595
const int clockPin = 14; //D5
//Pin connected to DS of 74HC595
const int dataPin = 13; // D7

int totalRelays = 2; // Number of relays
int relayState = 0; // default state = off
int relayArr[] = {12, 16}; // Pins on the Wemos
char vbutton1 = V1; char vbutton2 = V2;
char relayVButtons[] = {V1,V2};
int zone = 0;
int relayVButton = 0;
byte data;
byte dataArray[10];

/*
   SETUP
*/
  BLYNK_WRITE(V1)
  {
    // Get the state of the VButton
    relayVButton = param.asInt();
    relayControl(relayVButton, 12, 49); // Test led on Wemos pin
    //int bitToSet = 49;

    Serial.println("V1 pressed");
  }

  BLYNK_WRITE(V2)
  {
    // Get the state of the VButton
    relayVButton = param.asInt();
    relayControl(relayVButton, 16, 50); // Test led on Wemos pin
    Serial.println("V2 pressed");
  }

void setup() {

  pinMode(dataPin, OUTPUT);   // All 3 pins are output
  pinMode(clockPin, OUTPUT);
  pinMode(latchPin, OUTPUT);

  // Do some loop through all the relays and buttons for pinMode
  for (int i=0; i<=totalRelays; i++){
    pinMode(relayArr[i], OUTPUT);
    digitalWrite(relayArr[i], 0);
    pinMode(relayVButtons[i], INPUT);
  }

  // COMMUNICATIONS
  Serial.begin(115200);
  WiFi.mode(WIFI_STA);
  // CONNECT TO BLYNK
  Blynk.begin(AUTH, WIFI_SSID, WIFI_PASS);
  while (Blynk.connect() == false) {}
  // OVER THE AIR UPDATES
  ArduinoOTA.setHostname(OTA_HOSTNAME);
  ArduinoOTA.begin();

  Serial.println(F("Blynk v" BLYNK_VERSION ": Device started"));
}
/*
   LOOP
*/
void loop() {
  Blynk.run();
  ArduinoOTA.handle();
  timer.run();
}

void relayControl(int onoff, int relayNumber, int bitToSet){
if(onoff == 1) // Virtual button set to on
    {
      digitalWrite(relayNumber, HIGH); // set Wemos pin on HIGH (for test)
      registerWrite(bitToSet, HIGH);
      relayState = 1;
    }
    else
    {
      digitalWrite(relayNumber, LOW); // set Wemos pin on HIGH (for test)
      registerWrite(bitToSet, LOW);
      relayState = 0;
    }
}
void registerWrite(int whichPin, int whichState) {
// the bits you want to send
  byte bitsToSend = 0;

  // turn off the output so the pins don't light up
  // while you're shifting bits:
  digitalWrite(latchPin, LOW);

  // turn on the next highest bit in bitsToSend:
  bitWrite(bitsToSend, whichPin, whichState);

  // shift the bits out:
  shiftOut(dataPin, clockPin, MSBFIRST, bitsToSend);

    // turn on the output so the LEDs can light up:
  digitalWrite(latchPin, HIGH);

}

Sander

i've change the code. Now the result is the led is turning on but only one led. After pressing led 2 the other one is turning on..
Im not able to turn them off.
//#define BLYNK_DEBUG
#define BLYNK_PRINT Serial

#include <ArduinoOTA.h>
#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>
#include <TimeLib.h>
#include <WidgetRTC.h>

#include <ESP_SSD1306.h>    // Modification of Adafruit_SSD1306 for ESP8266 compatibility -> https://github.com/somhi/ESP_SSD1306
#include <Adafruit_GFX.h>   // Needs a little change in original Adafruit library (See README.txt file) --> https://github.com/adafruit/Adafruit-GFX-Library
#include <SPI.h>            // For SPI comm (needed for not getting compile error)

#include "settings_base.h"
#include "globals.h"
//#include "functions.h"
//#include "blynk_writes.h"

//Pin connected to ST_CP of 74HC595
const int latchPin = 15; //D8
//Pin connected to SH_CP of 74HC595
const int clockPin = 14; //D5
//Pin connected to DS of 74HC595
const int dataPin = 13; // D7

int totalRelays = 2; // Number of relays
int relayState = 0; // default state = off
int relayArr[] = {12, 16}; // Pins on the Wemos
char vbutton1 = V1; char vbutton2 = V2;
char relayVButtons[] = {V1,V2};
int zone = 0;
int relayVButton = 0;

/*
   SETUP
*/
  BLYNK_WRITE(V1)
  {
    // Get the state of the VButton
    relayVButton = param.asInt();
    relayControl(relayVButton, 12, 1); // Test led on Wemos pin
    //int bitToSet = 49;

    Serial.println("V1 pressed");
  }

  BLYNK_WRITE(V2)
  {
    // Get the state of the VButton
    relayVButton = param.asInt();
    relayControl(relayVButton, 16, 4); // Test led on Wemos pin
    Serial.println("V2 pressed");
  }

void setup() {

  pinMode(dataPin, OUTPUT);   // All 3 pins are output
  pinMode(clockPin, OUTPUT);
  pinMode(latchPin, OUTPUT);

  // Do some loop through all the relays and buttons for pinMode
  for (int i=0; i<=totalRelays; i++){
    pinMode(relayArr[i], OUTPUT);
    digitalWrite(relayArr[i], 0);
    pinMode(relayVButtons[i], INPUT);
  }

  // COMMUNICATIONS
  Serial.begin(115200);
  WiFi.mode(WIFI_STA);
  // CONNECT TO BLYNK
  Blynk.begin(AUTH, WIFI_SSID, WIFI_PASS);
  while (Blynk.connect() == false) {}
  // OVER THE AIR UPDATES
  ArduinoOTA.setHostname(OTA_HOSTNAME);
  ArduinoOTA.begin();

  Serial.println(F("Blynk v" BLYNK_VERSION ": Device started"));
}
/*
   LOOP
*/
void loop() {
  Blynk.run();
  ArduinoOTA.handle();
  timer.run();
}

void relayControl(int onoff, int relayNumber, int bitToSet){
if(onoff == 1) // Virtual button set to on
    {
      digitalWrite(relayNumber, HIGH); // set Wemos pin on HIGH (for test)
      registerWrite(bitToSet);
      Serial.println(bitToSet);
      relayState = 1;
    }
    else
    {
      digitalWrite(relayNumber, LOW); // set Wemos pin on HIGH (for test)
      registerWrite(bitToSet);
      relayState = 0;
    }
}
void registerWrite(int whichPin) {
// the bits you want to send
   uint8_t data = 1<<whichPin ;
  // turn off the output so the pins don't light up
  // while you're shifting bits:
  digitalWrite(latchPin, LOW);

  // shift the bits out:
  shiftOut(dataPin, clockPin, MSBFIRST, data);

    // turn on the output so the LEDs can light up:
  digitalWrite(latchPin, HIGH);

}

Im using the shiftOut option.
The code im using now is :
//#define BLYNK_DEBUG
#define BLYNK_PRINT Serial

#include <ArduinoOTA.h>
#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>
#include <TimeLib.h>
#include <WidgetRTC.h>

#include <ESP_SSD1306.h>    // Modification of Adafruit_SSD1306 for ESP8266 compatibility -> https://github.com/somhi/ESP_SSD1306
#include <Adafruit_GFX.h>   // Needs a little change in original Adafruit library (See README.txt file) --> https://github.com/adafruit/Adafruit-GFX-Library
#include <SPI.h>            // For SPI comm (needed for not getting compile error)

#include "settings_base.h"
#include "globals.h"
//#include "functions.h"
//#include "blynk_writes.h"

//Pin connected to ST_CP of 74HC595
const int latchPin = 15; //D8
//Pin connected to SH_CP of 74HC595
const int clockPin = 14; //D5
//Pin connected to DS of 74HC595
const int dataPin = 13; // D7

int totalRelays = 2; // Number of relays
int relayState = 0; // default state = off
int relayArr[] = {12, 16}; // Pins on the Wemos
char vbutton1 = V1; char vbutton2 = V2;
char relayVButtons[] = {V1,V2};
int zone = 0;
int relayVButton = 0;
byte data;
byte dataArray[10];

/*
   SETUP
*/
  BLYNK_WRITE(V1)
  {
    // Get the state of the VButton
    relayVButton = param.asInt();
    relayControl(relayVButton, 12, 49); // Test led on Wemos pin
    //int bitToSet = 49;

    Serial.println("V1 pressed");
  }

  BLYNK_WRITE(V2)
  {
    // Get the state of the VButton
    relayVButton = param.asInt();
    relayControl(relayVButton, 16, 50); // Test led on Wemos pin
    Serial.println("V2 pressed");
  }

void setup() {

  pinMode(dataPin, OUTPUT);   // All 3 pins are output
  pinMode(clockPin, OUTPUT);
  pinMode(latchPin, OUTPUT);

  // Do some loop through all the relays and buttons for pinMode
  for (int i=0; i<=totalRelays; i++){
    pinMode(relayArr[i], OUTPUT);
    digitalWrite(relayArr[i], 0);
    pinMode(relayVButtons[i], INPUT);
  }

  // COMMUNICATIONS
  Serial.begin(115200);
  WiFi.mode(WIFI_STA);
  // CONNECT TO BLYNK
  Blynk.begin(AUTH, WIFI_SSID, WIFI_PASS);
  while (Blynk.connect() == false) {}
  // OVER THE AIR UPDATES
  ArduinoOTA.setHostname(OTA_HOSTNAME);
  ArduinoOTA.begin();

  Serial.println(F("Blynk v" BLYNK_VERSION ": Device started"));
}
/*
   LOOP
*/
void loop() {
  Blynk.run();
  ArduinoOTA.handle();
  timer.run();
}

void relayControl(int onoff, int relayNumber, int bitToSet){
if(onoff == 1) // Virtual button set to on
    {
      digitalWrite(relayNumber, HIGH); // set Wemos pin on HIGH (for test)
      registerWrite(bitToSet, HIGH);
      relayState = 1;
    }
    else
    {
      digitalWrite(relayNumber, LOW); // set Wemos pin on HIGH (for test)
      registerWrite(bitToSet, LOW);
      relayState = 0;
    }
}
void registerWrite(int whichPin, int whichState) {
// the bits you want to send
  byte bitsToSend = 0;

  // turn off the output so the pins don't light up
  // while you're shifting bits:
  digitalWrite(latchPin, LOW);

  // turn on the next highest bit in bitsToSend:
  bitWrite(bitsToSend, whichPin, whichState);

  // shift the bits out:
  shiftOut(dataPin, clockPin, MSBFIRST, bitsToSend);

    // turn on the output so the LEDs can light up:
  digitalWrite(latchPin, HIGH);

}

What is your current code for writing data to the shift register? Do you use the shiftOut() function, or SPI, or something else?

yes im using the shiftOut function.
Will post the code im using now.

I have updated my earlier answer based on your new code sample. Instead of posting your code changes as answers to your own question, you can edit your question itself, so that your question remains in the question area.

Working from shiftOut() backwards:
Parameters for shiftOut():

Syntax
shiftOut(dataPin, clockPin, bitOrder, value)
Parameters
dataPin: the pin on which to output each bit (int)
clockPin: the pin to toggle once the dataPin has been set to the
  correct value (int)
bitOrder: which order to shift out the bits; either MSBFIRST or
  LSBFIRST. (Most Significant Bit First, or, Least Significant Bit
  First)
value: the data to shift out. (byte)

The important part to notice is the value parameter, which is one 8-bit value, and along with the dataPin and clockPin, sets the 8 registers of the shift register to the 8 bits shifted in. Then, as you have in your code, you pull the latchPin high to latch the register values to the output pins.
Binary values can be represented in C++ as b00001010, where the b prefix notes that the number following is in binary notation, and not "one-thousand ten". If the least-significant bit refers to relay-0 and the most-significant bit refers to relay-7, then to turn on relay-0, you would make sure the last digit (least-signficant) is a one: b00000001. To turn on relays 0 and 1, send 'b00000011', and so on.
In your registerWrite() function, you call shiftOut(dataPin, clockPin, MSBFIRST, bitsToSend);, thus bitsToSend should be an 8-bit value, with each bit representing the state of one of the 8 relays on your relay board.
within registerWrite(), bitsToSend is set by the bitWrite() function, which sets the bit number identified by whichPin to the value represented by whichState, which are both parameters passed in from the function call. It's worth noting that bitsToSend is initialized to b00000000 and bitWrite() is called only once, and so there can be at most one bit turned on in the value to write; and thus only one relay active at a time.
registerWrite() is called from within relayControl(), and the whichPin value in registerWrite() comes from the bitToSet value in relayControl(), which in turn is called by the BLYNK_WRITE(V1) or BLYNK_WRITE(V2) functions. In both of those functions, you pass 49 or 50 as the bitToSet parameter, but there are only 8 bits in a byte, so the value passed should be between 0 and 7. You cannot set bit 49 of an 8-bit value.
Probably relayControl() should be called with a value between 0 and 7 for the last parameter.

EDIT Based on New Code
Your latest code shows some changes to the registerWrite() function:
void registerWrite(int whichPin) {

You have removed the parameter which contains the value to write to the particular bit position. Now you have no way to tell the function whether to turn the pin on or off.
// the bits you want to send
   uint8_t data = 1<<whichPin ;

By shifting a 1 to a particular bit position, you have no way to clear a bit, which is probably why you now cannot get an LED to turn off except by turning on the alternate LED.
  // turn off the output so the pins don't light up
  // while you're shifting bits:
  digitalWrite(latchPin, LOW);

  // shift the bits out:
  shiftOut(dataPin, clockPin, MSBFIRST, data);

    // turn on the output so the LEDs can light up:
  digitalWrite(latchPin, HIGH);
}

If you wish to maintain the current state of bits, you will need to declare data as a static variable, which means that it's value is retained even when the function ends and is again available when the function is called again. Further, by using the assignment (=) operator, all you are able to do is overwrite the existing data with the new data, erasing the previous data.
You can use the bitSet() and bitClear() functions to set (make equal to 1) and clear (make equal to zero) individual bits in a byte.
A new registerWrite() function might look like:
void registerWrite(int whichPin, int pinValue) {
  // the bits you want to send
  static uint8_t data;

  if (pinValue==1) {
    bitSet(data, whichPin);    // Turn on the bit at whichPin
  } else {
    bitClear(data, whichPin);  // Turn off the bit at whichPin
  }

  // turn off the output so the pins don't light up
  // while you're shifting bits:
  digitalWrite(latchPin, LOW);

  // shift the bits out:
  shiftOut(dataPin, clockPin, MSBFIRST, data);

    // turn on the output so the LEDs can light up:
  digitalWrite(latchPin, HIGH);
}

You noted you have been frustrated for days working on this, and your code examples have mixed coding conventions, so perhaps you are finding many different code examples and trying various ones until you find something that works. I would encourage you, however, to take it slow and read through each line of code you have and make sure you understand exactly what it does, and be sure you can explain to yourself why each statement or command is there. This will help you to see the path of execution for your code and be able to diagnose bugs and come up with solutions that directly fix the problem, rather than swapping and and out a multitude of snippets from websites and forums.

Hello Jose,
Thank you for clearing out the matter. Yes i've tried a lot of things and didn't get the clue. Think i mixed up to much. Most of the time missing part is closer than you think. The code is clear to me for 90% and need to study the scripting lanquage but also the hardware behind the code.
The bitset with the static variable did the trick.

You already had SPI in use. You can connect SCK to SRCLK, MOSI to Serial data in, and pick a pin for RCLK. D10 needs to be an output for the device to be SPI master. If it's used already, use that.
Then simply clock in the needed data:
digitalWrite (rclk, LOW);
SPI.transfer (yourData);
digitalWrite (rclk, HIGH); // outputs update on this rising edge

MRCLR connects to +5, OE/ connects to Gnd.
SPI.begin();

in setup() turns on the defaults of 4 MHz clock rate, MSBFIRST, and SPI Mode 0, that's all you need.


text:
Whats common practice when using more components than there are pins?
I have a project where I want to use several motors (servo and stepper) which are activated with an RFID and show info on a display.
What’s common practice or a smart way to get past such limitations?

Either use IO expanders / shift registers, or split your project down into smaller parts each with its own controller.

switch from Uno to Mega

if you need to run things simultaneously, especially with a pwm controlled servo, go for more controllers or a controller with more hardware pwm ports.

Basically there are 4 ways to go if you run out of pins:

Change to a microcontroller board with more pins
Arrange the parts in a smart way to save pins (like if you have many buttons or LEDs you could arrange them as a matrix)
Use extra peripherals like shift registers, port expanders, PWM chips, ... which need less pins to be controlled
Use extra microcontrollers to offload some function to them and just communicate over a data bus of your choice (like I2C or Serial) with less pins.

Which of the above is best for you depends on your project and your requirements. Here are some notes about the options:

Choosing a bigger microcontroller is often the easiest solution, though you need to invest in buying it and rewrite and/or rewire your project. If you change to a different kind of microcontroller it might also involve searching for alternative libraries (since often libraries are not compatible across microcontroller types)
Arranging buttons or LEDs in a matrix will save you pins, but you also create extra complexity for the software driving them since they need to be actively scanned through all the time. That will take new considerations regarding your program flow (keeping the program responsive using millis() and a non-blocking coding style like in the BlinkWithoutDelay example)
With shift registers you need to buy the actual shift registers and with that commit to a data direction (since shift registers come as shift-in and shift-out registers) (as @Mat stated in the comments there are shift registers which support both ways, but they are more complex to use than the standard ones). If you drive something with them you also need to make sure to stay without the specific limitations of that shift register. You need 3 pins for them, but you can daisy chain them. So to drive 4 shift registers you just chain them and still use the 3 pins on your microcontroller. The Arduino Framework provides the shiftIn() and shiftOut() functions to control them.
Port expanders usually come with either I2C or SPI interface and are more flexible than shift registers (like different data directions for the pins), but also cost a bit more and are a bit more difficult to control. The Arduino Framework doesn't have direct functions to control them. You can either use the Wire or SPI library directly (after reading and understanding the communication protocol in the datasheet of the port expander) or you might find a fitting third party library for your specific port expander.
For driving extra motors or servos a PWM chip can be helpful. These are usually connected via I2C or SPI and can create PWM/servo signals on their outputs. For example the 16 Channel PWM Driver from Adafruit. There are lots of similar products out there, this is just the one, that comes to my mind.
Using an extra microcontroller might sound a bit wasteful. But it can make things easier, especially if you have multiple things to control which overload the computation capabilities of your microcontroller (with an Uno you can easily get in that terrain). If you pursue this hobby for a while you will often have some microcontrollers lying around. You can get Arduino Nano clones from China for about 1€ per piece. Other microcontrollers are also not expensive. The advantage over the other methods is that you can offload a part of the code to the other microcontroller. While for peripherals like port expanders the logic still happens on your main controller, here you could write more complex logic into the second microcontroller. I used this one time for creating a user interface on a TFT display so that the main microcontroller was free to do its actual job. An additional advantage with extra microcontrollers is (like @Majenko wrote in the comments), that your code gets more modular. For example lets imagine you write code for the extra microcontroller to control the speed of a fan. Then you decide to add more fans to the project. With the modular design you can just add more fans and always take the same code. Or you might wanna add a fan to another project. Just take the existing code and integrate the interface to the second microcontroller in that project.

I hope this helps as an orientation. More definitive answers can only be given here, when you describe your exact situation.

Another benefit of multiple microcontrollers is that of modularity: instead of writing one piece of code to control 5 motors you can write one piece of code to control one motor and replicate it 5 times along with the exact same hardware.

(There are shift registers that go both ways like the 74x299. A bit more complex than the 595 though.)

@Mat Ok, didn't know that. Great to learn something new. Thanks

Excellent, detailed answer. Well done!

you kind of skirt around this, but you really should mention switching periphreals to a common bus, like I2C to drive a pwm board, a 4 chan ADC, and an LCD from 2 pins. Or WS2812B to drive 5 LEDs instead of 5 pins.

There are several ways, but I recommend these:

MUXs/DEMUXs for I/O pins
Extra peripherals for special function like SPI, USART, ADC, and so on.

1: MUX and DEMUX can make you use more pins with little pins.
For example, you can control extra 2^n pins with n pins. The advantage of MUX and DEMUX is that it respond immediately. However you have to use more pins if you want to control lots of pins and it can only control one pin at a time.
2: You can use additional peripherals to use specific functions like PWM, SPI, ADC and so on. The advantage of this method is that you can use more functions and, in some cases, you control lots of peripherals with less pins. Because of these good features, the peripheral devices are relatively expensive.


text:
How to ignore garbage values in serial communication between arduino and python
I have arduino uno. I am trying to send and receive serial data from arduino to python. I have usb to uart converter. I have connected its tx to rx of Arduino and rx to tx of Arduino and gnd is connected to gnd. I have connected this usb to my laptop where I have written below python script:
import serial

ser = serial.Serial(port='COM6')

res = ser.read(10)
print(bytes.hex(res))
data = b"\x7E\x7E\xAA\x03\xAB\x77"
ser.write(data)

ser.close()

In above code, I am first reading the serial data, once the data is received, I sent out some hex packets. Below is the Arduino code:
void setup()
{
  Serial.begin(9600);
}

void loop()
{
  const byte message[] = {0xAA, 0xBB, 0x06, 0x00, 0x00, 0x00, 0x01, 0x01, 0x03, 0x03 };

  Serial.write(message, sizeof message);
  Serial.println("data sent");
  delay(1000);

  char buffer[6];
  if (Serial.available() > 0)
  {
    int size = Serial.readBytesUntil('\x77', buffer, 6);
    for (int i = 0 ; i < size ; i++)
    {
      Serial.println(buffer[i], HEX);
    }
  }
}

In above code, I am first sending out the hex packets (which is received fine on python side) and then it waits for serial data. Once serial data is available to read, it reads it unitll \x77 and prints out all data. This is received on serial console of Arduino:

You will notice that it has received the data but there are some extra FF being received. Why have we recived these FF. Also in the python code, we know we are sending data of length 6 so accordingly we have defined char buffer[6] in arduino but what if we have to receive data which we do not what length it will be. Please help. Thanks

How did you configure the serial port on the Python side? It is not done in the Python code itself.

@EdgarBonet Sorry I didn't get you by configuring the serial port. On the Python side, I have just mentioned the port number and thats it. About the hardware, its the same as mentioned in the question.

You cannot connect another USB-to-Serial converter on the same rx and tx pins. Serial ports cannot work in "parallel". Define a software serial using any other digital pins and connect your converter on those pins. The hardware rx and tx pins are already connected to the on-board "serial-to-USB" converter.

@Fahad I know and this is why when uploading the code, I need to remove the jumper wires rfom tx and rx pins. Once code is uploaded, I just press reset to start it again. Is that okay?

@SAndrew But you are still using the same pins for two serials! One is the onboard serial that you are watching on the Arduino IDE serial window (COM7) and one is in the python (COM6). That is a problem. Serials are not meant to be used as parallel buses.

@Fahad Thanks for your help. Using software serial is actually a good option.

The effect that you see is type promotion, in the C++ standard called "integral promotion", which happens implicitly. Values of type char are cast to int. Commonly, and in your case too, the char is by default signed.
The values 0xAA and 0xAB have a set most significant bit, which commonly designates a negative value in two's complement. This holds true for your case. And so these negative values are cast to the same negative values, but in full width of an int. In your case, an int has 32 bits.
Hex 0xAA as (by default signed) char is -86 decimal. And -86 decimal as (by definition signed) int is 0xFFFFFFAA hex.
Printed as hex, all bits are shown. So you see all these FF.
The solution is to mask only the interesting lower 8 bits:
    {
      Serial.println(buffer[i] & 0xFF, HEX);
    }

Good catch! Well, it's actually a bit more complicated: the char gets promoted to a 16-bit int by the overload resolution of Serial.println(), then explicitly casted to long by Print::print(int, int), then converted to unsigned long by the call to printNumber().

@EdgarBonet This issue happens a lot with beginners, and I had it many times already. :-D -- Thanks for going deep into the details! I feel the official Arduino documentation in the web as unsatisfactory, because I always miss the exact and complete prototypes. We should not have to look into the library source...

Thanks for your answer. Any idea why some of the garbage and random values are being received? Thansk

@SAndrew Which garbage and random values do you mean? I don't see any. Please post a new question if this is a separate issue, else edit your question.


text:
Bad readings from 12V pwm fan tachometer signal
I have the following circuit:

(The Arduino is powered via the USB)
The problem is that I the reading from the fan's tachometer signal are incorrect,
I tried to add the two resistors as voltage dividers but still the readings are wrong.
When I check the voltage of the tachometer signal with a multimeter, in the time the multimeter is connected the readings are somewhat correct (not 100%).
Here is a snippet from the fan's documentation:

(BTW: When I used a different 12v pwm fan and didn't use a voltage divider the readings were incorrect only in the time I switched the 12v power off until the fan stopped spinning (after it stopped spinning the tachometer stopped sending signals so the rpm was 0 which was correct).)
Working code (correct tacho signal value):
const byte tachpin = 2;

unsigned int tacho = 0;
long int startTime = 0;
long int elapsed = 0;

void setup() {
  Serial.begin(9600);
   // Configure Timer 1 for PWM @ 25 kHz.
    TCCR1A = 0;
    TCCR1B = 0;
    TCNT1  = 0;
    TCCR1A = _BV(COM1A1)
           | _BV(COM1B1)
           | _BV(WGM11);
    TCCR1B = _BV(WGM13)
           | _BV(CS10);
    ICR1   = 320;

    pinMode(tachpin, INPUT_PULLUP);
    attachInterrupt(digitalPinToInterrupt(tachpin), tachisr, RISING);
    startTime = millis();
}

void tachisr(){
  tacho++;
}

void loop() {
      elapsed = millis() - startTime;
      if(elapsed > 1000) {
        int tachcopy = 0;
        noInterrupts();
        tachcopy = tacho;
        tacho = 0;
        interrupts();
        rpm = (tachcopy / 2.0) * (60000 / elapsed);
        Serial.println(rpm,DEC);
      }
      startTime = millis();
}

Correct reading from working code

rpm = 0, tachcopy = 0
rpm = 1150, tachcopy = 39
rpm = 2360, tachcopy = 80
rpm = 2655, tachcopy = 90
rpm = 2773, tachcopy = 94
rpm = 2655, tachcopy = 90
rpm = 1268, tachcopy = 43

Not working code (incorrect tachometer signal):
const byte tachpin = 2;

unsigned int tacho = 0;
long int startTime = 0;
long int elapsed = 0;
long int rpm = 0;
unsigned int pwmValue = 0;
unsigned int outValue = 0;
unsigned int seconds_counter = 0;

void setup() {
  Serial.begin(9600);
   // Configure Timer 1 for PWM @ 25 kHz.
    TCCR1A = 0;
    TCCR1B = 0;
    TCNT1  = 0;
    TCCR1A = _BV(COM1A1)
           | _BV(COM1B1)
           | _BV(WGM11);
    TCCR1B = _BV(WGM13)
           | _BV(CS10);
    ICR1   = 320;

    // Set the PWM pins as output.
    pinMode( 9, OUTPUT); //!!!ADDED LINE!!!

    pinMode(tachpin, INPUT_PULLUP);
    attachInterrupt(digitalPinToInterrupt(tachpin), tachisr, RISING);
    startTime = millis();
}

void tachisr(){
  tacho++;
}

//!! ADDED FUNCTION !!!
void analogWrite25k(int value)
{

    OCR1A = value;

}

void loop() {

      elapsed = millis() - startTime;
      if(elapsed > 1000) {
        int tachcopy = 0;
        noInterrupts();
        tachcopy = tacho;
        tacho = 0;
        interrupts();
        startTime = millis();
        rpm = (tachcopy / 2.0) * (60000 / elapsed);
        Serial.print("rpm = ");
        Serial.print(rpm,DEC);
        Serial.print(", tachcopy = ");
        Serial.println(tachcopy,DEC);

        seconds_counter++;
      }

      analogWrite25k(100); //!!!ADDED LINE!!!

}

Not working code output:

rpm = 737854, tachcopy = 25012
rpm = 738591, tachcopy = 25037
rpm = 737824, tachcopy = 25011
rpm = 738591, tachcopy = 25037
rpm = 738562, tachcopy = 25036
rpm = 737854, tachcopy = 25012
rpm = 738562, tachcopy = 25036
rpm = 737854, tachcopy = 25012
rpm = 738562, tachcopy = 25036
rpm = 737824, tachcopy = 25011
rpm = 738591, tachcopy = 25037
rpm = 737854, tachcopy = 25012
rpm = 738562, tachcopy = 25036
rpm = 737854, tachcopy = 25012
rpm = 738562, tachcopy = 25036
rpm = 737854, tachcopy = 25012

Readings when using 10K ohm resistor as pull up (instead of the voltage divider (10K+4.7K))  and maxing out analogWrite25k - analogWrite25k(320);:

rpm = 6165
rpm = 6401
rpm = 6136
rpm = 6136
rpm = 6165
rpm = 6018
rpm = 6283
rpm = 5870
rpm = 6047
rpm = 6578
rpm = 6460
rpm = 6224
rpm = 5782
rpm = 6047
rpm = 6136
rpm = 6136
rpm = 6313
rpm = 5988
rpm = 6224
rpm = 6195
rpm = 6136
rpm = 5900

Which is interesting because the max speed of the fan is ~3000rpm (so rpm readings are about x2 max fan rpm when maxing out analogWrite25k)
Update:
Added debounce + 10K Ohm to Arduino 5V:
#define DEBOUNCE 10
//Interrupt handler. Stores the timestamps of the last 2 interrupts and handles debouncing
unsigned long volatile ts1=0,ts2=0;
//Calculates the RPM based on the timestamps of the last 2 interrupts. Can be called at any time.
unsigned int calcRPM(){
    unsigned long ts1_copy, ts2_copy;
    noInterrupts();
    ts1_copy = ts1;
    ts2_copy = ts2;
    interrupts();

    Serial.print(ts1_copy);
    Serial.print(" / ");
    Serial.print(ts2_copy);
    Serial.print(" / ");
    Serial.println(ts2_copy - ts1_copy);
    return (60000000.0 / (ts2_copy - ts1_copy ) / 2.0);
}

void tachisr2() {
    unsigned long m=micros();
    if((m-ts2)>DEBOUNCE){
        ts1=ts2;
        ts2=m;
    }
}

Output after adding debounce:

rpm = 2953.92
90923308 / 90923320 / 12
rpm = 2500000.00
91948328 / 91958496 / 10168
rpm = 2950.43
92994188 / 92994200 / 12
rpm = 2500000.00
94031032 / 94031040 / 8
rpm = 3750000.00
95047108 / 95057256 / 10148
rpm = 2956.25
96093308 / 96093320 / 12
rpm = 2500000.00
97119144 / 97129296 / 10152
rpm = 2955.08

When the value is ~2900 it is the correct value.
Update 2
Hope you can help me with another problem, The rpm value is scattering on a range of up to 120rpm+ even on low fan cycle of 800 rpm, of course when the elapsed time wait is bigger the scattering range is lower, the rpm reading might be not precise by about ~10%, I saw videos of live speed reading from BIOS of PC fan connected to PC motherboard and some of the fans are more precise (maybe because of BIOS code? (maybe there is a standard that specifies minimum time before reading the tacho counter?)), The question is are the tachometer sensors on 12V PC fans not supposed to be super precise by design or do I still have some problems with my circuit?, If I want a more precise rpm reading should I use an external tachometer sensor? which one is the best? optical/magnet based?
(btw my current circuit doesn't include the 4.7KOhm resistor from the schematic, only 10KOhm pull up to 5V)

Please show the code, that gave you wrong values and explain how exactly they are wrong and how you veryfied the correct values

@chrisl, added the code, I know the values are wrong because I get >10,000 as the rpm and sometimes negative numbers

@jsotola its the voltage divider, I also tried 10K pull-up connected to 3.3V without the voltage divider and also got incorrect readings

@jsotola, Check my update please, I figured that the problem occurs only when I enabled the pwm output pin.

1. Open Collector Output of a module.
The power for the open collector output should come from the MCU, not (indirectly) from the sensor's power supply. It is very similar to wiring a push button switch on the low side.
Usually, the internal pullup resistor of the Arduino pin which is connected to the module passes enough power to detect the status of this output (as you have done). This internal pullup resistor has a value of around 30k. It is also possible to add a lower value external pull up resistor, if required say because of electrical noise, between the Arduino's 5v power rail and the pin. Ensure, however, that the current is within the tolerance of the connected device.
Measuring PWM voltages with a multimeter will not be successful, as you have discovered. These tend to integrate and show an average voltage. Say 12 volts at a 50% duty cycle will be read as 6 volts. Use an oscilloscope to see the voltage across the wave form.
2. Electrical Interference.
Your figure here tachcopy = 25012 indicate that your 25KHz signal is leaking through and being detected as pulses from the sensor. Powering the open collector via the Nano's 5v power rail (as above) may eliminate this. Maybe also better decoupling on the 12 volt power supply (say adding a big capacitor).
3. Code Issues
Your code has an number of issues which should be cleaned up. Some may show up after only about 25 days. Some may show up after the next recompilation and some affect the accuracy of the results.

unsigned int tacho = 0; should be volatile.
int tachcopy = 0; should be unsigned int to match the data tape it is copying.
Variables which are derived from millis() should be unsigned long (uint32_t) as here: elapsed = millis() - startTime;.
This (60000 / elapsed) should be forced to a floating point division say (60000.0 / elapsed)
This could be in setup() instead of loop(): analogWrite25k(100); //!!!ADDED LINE!!!

4. "rpm readings is about x2 max fan rpm"
I can't explain that. It may be that the sensor output needs to be debounced.
5. Sample debounce routine (lockout principle)
// Simple debounce routine. Based on original code.
// After accepting a pulse locks out further pulses for 3 ms
// Should be OK for 100Hz (period 10ms)

void tachisr(){
  // ISR (external interrupt)
  static uint32_t lastAcceptedPulseAtMs = 0 ; // static initialised once only
  uint32_t ms = millis() ;
  if ( ms - lastAcceptedPulseAtMs >= 3 ) {  // 3 ms - tune if required
    lastAcceptedPulseAtMs = ms ;
    tacho++;
  }
}

Note: An ISR should be quick to execute and should not contain Serial.print() etc.

Yes, debouncing is a must. It sometimes also has positions that are "oscillating" even if it's not running (4-pin fans with 0% pwm)

@KIIV I did a quick search but could not discover what technology is used for the tachometer. Some are very prone to bouncing say a reed switch, however, I doubt if that would last very long in such an application. A hall effect sensor or something optical would be less of a risk. Maybe the OP can tell us what their model uses.

@6v6gt Thanks for your great answer, I will test it in a bit, However I don't understand why tacho need to be volatile? (i'm accessing it only when interrupts are off and one time in ISR). Regarding your question, I don't have access to the FAN controller but My fan is Noctua NF-F12.

@Takata tacho needs to be volatile, because the "source of truth" is in memory, not in the CPU registers. For "normal" variables, the compiler can switch the source of truth between memory and registers as it pleases. But in your case, without volatile, the register containing the tacho value while being in loop() is assigned and filled from memory at the start of loop(), which is before you call noInterrupts(). volatile basically adds machine instructions to LOAD the value from memory into a register in the moment you read the variable in your code (and STORE directly after writing)

@Takata If volatile is missing, the compiler may choose to optimize the register usage as it pleases -- and for that, it assumes a completely linear program, which is decidedly not the case with interrupts. The compiler may even decide to keep the variable completely in the registers -- which are saved on the stack when entering the ISR function and restored when leaving it.

@6v6gt Added debounce code, the rpm value is correct some of the times

DEBOUNCE value of 30 gives good tachometer values 90% of the times, that's not good enough.

@Takata I'm guessing with a signal of max 3,000 RPM (100Hz @ 2 pulses per revolution) you need a lockout of about 3ms if you do it in software. However, if the signal is very noisy, shorter wires and/or making the pull up resistor stronger are options. Probably around 2k pulled up to 5 volts is the strongest you can go to. Do you know what the tachometer sensor is based on ? Hall effect, read switch or other ?

@Takata Your debounce logic looks rather elaborate. I've added as simple version to chapter 5 of my answer. It is simply an extension of your original ISR and requires no additional global or loop() code. It works by accepting the first pulse then ignoring those which follow in the next 3ms.  If the total pullup resistance is around 10K, you could possibly achieve the same effect with 2 or 3  100nF capacitors between pin 2 and GND

@6v6gt Amazing, Thank you very much!

@Takata I've just noticed that the interrupt trigger is the RISING edge in your code. For open collector output it should really be FALLING. The falling edge is cleaner because the transistor at the output pulls down sharply when switched on. When switched off, the output floats up due to the pullup resistor and any capacitive effect of the sensor.  Whether it makes any real difference in your case I don't know.

@6v6gt Actually in my case RISING works better. I posted an update I hope you can help me figure it out, Thanks again!

@Takata Post your updated code. Some things to try (1) reduce the pullup to 5v resistor to around 2k (no lower than 1k) (2) increase the print baud rate from 9600 to 115200 (3) try a 100nf capacitor between nano pin D2 and GND (assumes a ~2k pullup resistor as suggested above). (4) check the output with a n oscilloscope. An alternative would be an optical method with an IR LED and IR photo transistor. A magnetic method could be subject to interference with the existing fan mechanism.


text:
converting comma delimited Serial message to 7 Unsigned Long variables
Working on a project where I get an input where its a comma delimited string like:
"255,10000000,42949672950254,12,22".

and then the numbers (no commas), would be split into 6 Long variables
like
var1 = 255
var2 = 10000000
...

I wanted a function like this:
void extractIntegersFromString(String str, int& integer1, int& integer2, int& integer3, int& integer4, int& integer5, int& integer6, int& integer7) {
  int count = 0;
  String temp = "";

  for (int i = 0; i < str.length(); i++) {
    char c = str.charAt(i);

    if (c == ',') {
      if (count == 0)
        integer1 = String(temp).toInt();
      else if (count == 1)
        integer2 = String(temp).toInt();
      else if (count == 2)
        integer3 = String(temp).toInt();
      else if (count == 3)
        integer4 = String(temp).toInt();
      else if (count == 4)
        integer5 = String(temp).toInt();
      else if (count == 5)
        integer6 = String(temp).toInt();
      else if (count == 6)
        integer7 = String(temp).toInt();

      count++;
      temp = "";
    } else if (c >= '0' && c <= '9') {
      temp += c;
    }
  }

  // Store the last integer if the string doesn't end with a comma
  if (temp != "") {
    if (count == 0)
      integer1 = String(temp).toInt();
    else if (count == 1)
      integer2 = String(temp).toInt();
    else if (count == 2)
      integer3 = String(temp).toInt();
    else if (count == 3)
      integer4 = String(temp).toInt();
    else if (count == 4)
      integer5 = String(temp).toInt();
    else if (count == 5)
      integer6 = String(temp).toInt();
    else if (count == 6)
      integer7 = String(temp).toInt();
  }
}

This function makes it work through ints, but I need the larger size of a Long.
P.S. I've tried the atol() function (and similar others), but that didn't work...

First of all, it is worth noting that the third number in you example
message (100000000000, i.e. 1011) is too large to fit in an
unsigned long. On AVR-based Arduinos, and most non-64-bit platforms,
an unsigned long is 32-bits wide and can only hold numbers up to
4294967295 (about 4.3×109). I do not know of any easy way to
parse such a large number on AVR.
That being said, for parsing this kind of string into unsigned long
numbers, I would recommend the strtoul() function. Compared
to atol(), it has the benefit that it tells you where the number it
read ended, so you know where to search for the next one: it saves you a
call to strchr(). It also allows some error-checking, so you know
whether the message does conform to the expected format.
Here is a tentative implementation:
/*
 * Parse up to `count` numeric values from `message`,
 * which must be in comma-separated-values format.
 *
 * Return the number of values successfully parsed.
 */
int parse_message(const char *message,
                  unsigned long *values, int count) {
    for (int i = 0; i < count; i++) {
        char *end;  // pointer to next non-digit
        values[i] = strtoul(message, &end, 10);
        if (end == message) return i;  // parsing failed
        if (*end == ',') end++;        // skip comma
        message = end;                 // move to the next field
    }
    return count;
}

And a small test sketch:
void setup() {
    Serial.begin(9600);

    unsigned long values[7];
    int count = parse_message("255,10000000,100000000000,0,255,12,22",
            values, 7);
    Serial.print(count);
    Serial.println(" numbers successfully parsed:");
    for (int i = 0; i < count; i++)
        Serial.println(values[i]);
}

void loop() {}

Thank you for your reply, I'll check it and I'll accept the answer for future reference!! :)

String.toInt actually returns a long. See the code:
long String::toInt(void) const
{
    if (buffer) return atol(buffer);
    return 0;
}

I've tried the atol() function (and similar others), but that didn't work

Please post your "try", don't just say that you did it. Maybe you did it incorrectly.

Re your entire technique: There is a function strtok that is specifically designed to break up a string into substrings at a delimiter. You could use that rather than re-inventing the wheel.
However that doesn't solve your specific problem of converting the substrings into a long.

Its a bit long; how would I include it here?

"Its a bit long; how would I include it here? "  ... If someone asks for something in the comments, the answer (for just about any of the dozens of stackexchange web sites) is to edit the question and make it better.

Edit your question and show the half-a-dozen or so lines of code where you used the atol() function. Also show the results. "Didn't work" is to vague it could mean anything. Did it not compile? If it did compile what results did you get? Show the numbers. Don't say "it didn't work".