text:
Can Bus to receive and transmit on the same mcu
So I've been working on a project over the last few month using homemade boards on a CAN bus. It's working well when using a board as a sender and another one as receiver.
I now have 3 boards and on which there are several sensor.
My purpose here is to be able for every board to share data and use other from another mcu.
An quick overview of the project for a better understanding :
I'm trying to automate a RC plane.
MCU-1 : Potentiometers + GPS
MCU-2 : 1 accelerometer + 1 barometer
MCU-3 : 1 differential pressure transmitter + 1 radio transmitter
I'd like to be able, for MCU-1 to receive and use data from MCU-2 and in the same time to transmit data to MCU-3. (They both have many more components and tasks to achieved, that why I don't have all the sensors on the same board)
I don't think it's important but MCU1 and 3 are ATmega328p (the one from the nano board) and MCU2 is an ATmega2560
My question :
Is it possible ? I mean is it possible to have a MCU running as a Sender and a Receiver at the same time ? and how to do it ? :)
Also is it possible to have a MCU running as a receiver, let's say 90% of the time and sender 10% (or after an update) ? If the first situation isn't possible this one could be a solution for my project.
Thank you
Undeadguy

Yes, it is possible.

CAN is a multi-master serial bus standard for connecting Electronic Control Units [ECUs] also known as nodes. Two or more nodes are required on the CAN network to communicate. The complexity of the node can range from a simple I/O device up to an embedded computer with a CAN interface and sophisticated software.
-- Wikipedia

You should understand how collision detection works in a multi-master CAN bus and ensure that you implement it (or it is implemented in your chosen CAN library) to allow reliable operation:

The CAN specifications use the terms "dominant" bits and "recessive" bits where dominant is a logical 0 (actively driven to a voltage by the transmitter) and recessive is a logical 1 (passively returned to a voltage by a resistor). The idle state is represented by the recessive level (Logical 1). If one node transmits a dominant bit and another node transmits a recessive bit then there is a collision and the dominant bit "wins". This means there is no delay to the higher-priority message, and the node transmitting the lower priority message automatically attempts to re-transmit six bit clocks after the end of the dominant message. This makes CAN very suitable as a real time prioritized communications system.
The exact voltages for a logical 0 or 1 depend on the physical layer used, but the basic principle of CAN requires that each node listens to the data on the CAN network including the transmitting node(s) itself (themselves). If a logical 1 is transmitted by all transmitting nodes at the same time, then a logical 1 is seen by all of the nodes, including both the transmitting node(s) and receiving node(s). If a logical 0 is transmitted by all transmitting node(s) at the same time, then a logical 0 is seen by all nodes. If a logical 0 is being transmitted by one or more nodes, and a logical 1 is being transmitted by one or more nodes, then a logical 0 is seen by all nodes including the node(s) transmitting the logical 1. When a node transmits a logical 1 but sees a logical 0, it realizes that there is a contention and it quits transmitting. By using this process, any node that transmits a logical 1 when another node transmits a logical 0 "drops out" or loses the arbitration. A node that loses arbitration re-queues its message for later transmission and the CAN frame bit-stream continues without error until only one node is left transmitting. This means that the node that transmits the first 1 loses arbitration. Since the 11 (or 29 for CAN 2.0B) bit identifier is transmitted by all nodes at the start of the CAN frame, the node with the lowest identifier transmits more zeros at the start of the frame, and that is the node that wins the arbitration or has the highest priority.
For example, consider an 11-bit ID CAN network, with two nodes with IDs of 15 (binary representation, 00000001111) and 16 (binary representation, 00000010000). If these two nodes transmit at the same time, each will first transmit the start bit then transmit the first six zeros of their ID with no arbitration decision being made.

Thank you for this info.
That's what I thought when I choose CAN. However I didn't find any library capable of having multiple master... Any idea where I could find one ?


text:
Slave Select on Analog pin for Can Bus
I have recently made a shield for an arduino mega2560 with among others sensors, a CAN interface (MCP2515 and ISO1050).
The purpose is to create a CAN network with several arduino uno and one Mega.
Until now, the network is working well on all the Uno but unfortunately not on the Mega. As I have others sensors on the SPI bus, I've kept the MOSI, MISO and SCK pins unchanged (51,50,52) and I put the SS on the Analog pin A13 (number 67 for digital), which was the nearest unused pin I had during the routing process. Before making the shield I was careful and I've check if I could use it as a SS for my purpose.
Despite my caution, it appears that I'm not able to communicate within the CAN bus.
Before going futher, I'm using the SeeedStudio library made for their shield to test the connection.
I've tried to use A13 (using an #define)and 67 for the
SPI_CS_PIN = 67;

without any success.
I've also tried to force the bus to be active with a digitalWrite at the beginning of the setup().
// demo: CAN-BUS Shield, send data
// loovee@seeed.cc

#include <mcp_can.h>
#include <SPI.h>

// the cs pin of the version after v1.1 is default to D9
// v0.9b and v1.0 is default D10
const int SPI_CS_PIN = 67;

MCP_CAN CAN(SPI_CS_PIN);                                    // Set CS pin

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

while (CAN_OK != CAN.begin(CAN_500KBPS))              // init can bus : baudrate = 500k
{
    Serial.println("CAN BUS Shield init fail");
    Serial.println(" Init CAN BUS Shield again");
    delay(100);
}
Serial.println("CAN BUS Shield init ok!");
}

unsigned char stmp[8] = {0, 0, 0, 0, 0, 0, 0, 0};

void loop()
{
// send data:  id = 0x00, standrad frame, data len = 8, stmp: data buf
stmp[7] = stmp[7]+1;
if(stmp[7] == 100)
{
    stmp[7] = 0;
    stmp[6] = stmp[6] + 1;

    if(stmp[6] == 100)
    {
        stmp[6] = 0;
        stmp[5] = stmp[6] + 1;
    }
}

CAN.sendMsgBuf(0x00, 0, 8, stmp);
delay(100);                       // send data per 100ms
}

If you have any idea on why it's not working and a way to solve this problem, please let me know :)
Undeadguy.

Try adding pinMode(53, OUTPUT); to the start of your setup().

I've tried : no success :(
However could you explain to me what effect making this pin as an output could have on the other pin ? Is this particular pin always selected as the SS ?

That is the hardware SS pin. The ATMega's SPI peripheral uses the direction of that pin to determine the direction of the SPI port. It has to always be OUTPUT for the SPI to work as a master.

source: Stack Exchange

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

sort: votes


text:
Error when moving stepper motor - Alexa curtain opener
I've hit a wall with my code and keep getting a Panic error like this:

Panic /Users/lewisaburrow/Library/Arduino15/packages/esp8266/hardware/esp8266/2.3.0/cores/esp8266/core_esp8266_main.cpp:98 __yield
ctx: sys
  sp: 3ffff9d0 end: 3fffffb0 offset: 01b0

Please can you help shed some light on the error?
It's used to open and close curtains using Alexa by tricking it into thinking it is a Belkin WeMo device. It runs on an Adafruit Feather HUZZAH with ESP8266.
When I test the Alexa connection code it works fine. It's based on Fauxmo https://bitbucket.org/xoseperez/fauxmoesp
    And when I try the code in isolation that moves the stepper motor it works just fine.(This is with an Adafruit Featherwing Motor Controller: https://www.adafruit.com/product/2927 ). It's after the two are 'blended' together that I experience this issue...
The entire code looks like this:
#include <Arduino.h>
#ifdef ESP32
#include <WiFi.h>
#else
#include <ESP8266WiFi.h>
#endif
#include "fauxmoESP.h"
#include "credentials.sample.h"

#define SERIAL_BAUDRATE                 115200
#define LED                             2

fauxmoESP fauxmo;

//--------------------------------------------------
// Motor

#include <Wire.h>
#include <Adafruit_MotorShield.h>
#include "utility/Adafruit_MS_PWMServoDriver.h"

// Create the motor shield object with the default I2C address
Adafruit_MotorShield AFMS = Adafruit_MotorShield();
// Or, create it with a different I2C address (say for stacking)
// Adafruit_MotorShield AFMS = Adafruit_MotorShield(0x61);

// Connect a stepper motor with 200 steps per revolution (1.8 degree)
// to motor port #2 (M3 and M4)
Adafruit_StepperMotor *myMotor = AFMS.getStepper(200, 2);

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

// -----------------------------------------------------------------------------
// Wifi
// -----------------------------------------------------------------------------

void wifiSetup() {

// Set WIFI module to STA mode
WiFi.mode(WIFI_STA);

// Connect
Serial.printf("[WIFI] Connecting to %s ", WIFI_SSID);
WiFi.begin(WIFI_SSID, WIFI_PASS);

// Wait
while (WiFi.status() != WL_CONNECTED) {
    Serial.print(".");
    delay(100);
}
Serial.println();

// Connected!
Serial.printf("[WIFI] STATION Mode, SSID: %s, IP address: %s\n", WiFi.SSID().c_str(), WiFi.localIP().toString().c_str());

}

void setup() {

// Init serial port and clean garbage
Serial.begin(SERIAL_BAUDRATE);
Serial.println();
Serial.println();

// Wifi
wifiSetup();

// LED
pinMode(LED, OUTPUT);
digitalWrite(LED, HIGH);

// You can enable or disable the library at any moment
// Disabling it will prevent the devices from being discovered and switched
fauxmo.enable(true);

// Add virtual devices
fauxmo.addDevice("bedroom curtain");
//fauxmo.addDevice("switch two"); // You can add more devices
//fauxmo.addDevice("switch three");

// -------------------------------
// Motor

AFMS.begin();  // create with the default frequency 1.6KHz
//AFMS.begin(1000);  // OR with a different frequency, say 1KHz

myMotor->setSpeed(10);  // 10 rpm

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

// fauxmoESP 2.0.0 has changed the callback signature to add the device_id,
// this way it's easier to match devices to action without having to compare strings.
fauxmo.onSetState([](unsigned char device_id, const char * device_name, bool state) {
    Serial.printf("[MAIN] Device #%d (%s) state: %s\n", device_id, device_name, state ? "ON" : "OFF");
    digitalWrite(LED, !state);

    if (state == HIGH) {
      Serial.print("Closing the curtain...");
    }
    else {
      Serial.print("Opening the curtain...");
      openCurtain();
    }

});

// Callback to retrieve current state (for GetBinaryState queries)
fauxmo.onGetState([](unsigned char device_id, const char * device_name) {
    return !digitalRead(LED);
});

}

void openCurtain() {
myMotor->step(100, FORWARD, SINGLE);
}

void closeCurtain() {
myMotor->step(100, BACKWARD, SINGLE);
}

void loop() {

// Since fauxmoESP 2.0 the library uses the "compatibility" mode by
// default, this means that it uses WiFiUdp class instead of AsyncUDP.
// The later requires the Arduino Core for ESP8266 staging version
// whilst the former works fine with current stable 2.3.0 version.
// But, since it's not "async" anymore we have to manually poll for UDP
// packets
fauxmo.handle();

static unsigned long last = millis();
if (millis() - last > 5000) {
    last = millis();
    Serial.printf("[MAIN] Free heap: %d bytes\n", ESP.getFreeHeap());

}

}

and this is the full error being reported before the ESP8266 tries to reset itself:
[MAIN] Device #0 (bedroom curtain) state: OFF
Opening the curtain...
Panic
/Users/lewisaburrow/Library/Arduino15/packages/esp8266/hardware/esp8266/2.3.0/cores/esp8266/core_esp8266_main.cpp:98 __yield

ctx: sys
sp: 3ffff9d0 end: 3fffffb0 offset: 01b0

>>>stack>>>
3ffffb80:  00000001 00000002 3ffee770 40204b82
3ffffb90:  4010702c 00007530 00000064 402059fd
3ffffba0:  00000001 00000064 00007530 40204eca
3ffffbb0:  00000001 00000000 3ffee984 402053e9
3ffffbc0:  3ffe84e7 65526574 3ffffba0 3ffffe00
3ffffbd0:  3ffee78c 00000000 3ffee984 40202204
3ffffbe0:  3ffee78c 00000000 3ffee984 40202271
3ffffbf0:  65707954 3ffffc00 00000000 40203881
3ffffc00:  54534f50 70752f20 632f706e 72746e6f
3ffffc10:  622f6c6f 63697361 6e657665 48203174
3ffffc20:  2f505454 0d312e31 736f480a 31203a74
3ffffc30:  312e3239 312e3836 3933312e 3032353a
3ffffc40:  0a0d3030 65636341 203a7470 0d2a2f2a
3ffffc50:  6e6f430a 746e6574 7079742d 74203a65
3ffffc60:  2f747865 3b6c6d78 61686320 74657372
3ffffc70:  7475223d 22382d66 4f530a0d 43415041
3ffffc80:  4e4f4954 7522203a 423a6e72 696b6c65
3ffffc90:  65733a6e 63697672 61623a65 65636973
3ffffca0:  746e6576 5323313a 69427465 7972616e
3ffffcb0:  74617453 0a0d2265 746e6f43 2d746e65
3ffffcc0:  676e654c 203a6874 0d393932 3c0a0d0a
3ffffcd0:  6c6d783f 72657620 6e6f6973 2e31223d
3ffffce0:  65202230 646f636e 3d676e69 66747522
3ffffcf0:  3f22382d 3a733c3e 65766e45 65706f6c
3ffffd00:  6c6d7820 733a736e 7468223d 2f3a7074
3ffffd10:  6863732f 73616d65 6c6d782e 70616f73
3ffffd20:  67726f2e 616f732f 6e652f70 6f6c6576
3ffffd30:  222f6570 653a7320 646f636e 53676e69
3ffffd40:  656c7974 7468223d 2f3a7074 6863732f
3ffffd50:  73616d65 6c6d782e 70616f73 67726f2e
3ffffd60:  616f732f 6e652f70 69646f63 222f676e
3ffffd70:  3a733c3e 79646f42 3a753c3e 42746553
3ffffd80:  72616e69 61745379 78206574 736e6c6d
3ffffd90:  223d753a 3a6e7275 6b6c6542 733a6e69
3ffffda0:  69767265 623a6563 63697361 6e657665
3ffffdb0:  22313a74 69423c3e 7972616e 74617453
3ffffdc0:  3c303e65 6e69422f 53797261 65746174
3ffffdd0:  752f3c3e 7465533a 616e6942 74537972
3ffffde0:  3e657461 3a732f3c 79646f42 732f3c3e
3ffffdf0:  766e453a 706f6c65 00003e65 40101ea2
3ffffe00:  3fff0a5c 00000002 3fff0d0c 4010020c
3ffffe10:  40102bb5 3ffec9a8 3ffffe60 3fff0d0c
3ffffe20:  00000000 3ffee78c 3ffeb7c2 40203a5c
3ffffe30:  54534f50 70752f20 632f706e 72746e6f
3ffffe40:  622f6c6f 63697361 6e657665 48203174
3ffffe50:  2f505454 00312e31 3ffe97fc 00000001
3ffffe60:  000001fa 00007fff 000000ed 4010020c
3ffffe70:  3ffee960 04c14103 00002200 00000000
3ffffe80:  3fff0d0c 3fff09bc 00000000 40203a80
3ffffe90:  3ffe97c0 00000000 3fff0084 40204504
3ffffea0:  3fff0bdc 00000030 0000000f ffffffff
3ffffeb0:  3fff026c 3fff0274 00000006 3fff0080
3ffffec0:  3fff0bdc 3fff0088 3fff0084 4020454f
3ffffed0:  3fff0bdc 3fff0088 3fff0084 40229c30
3ffffee0:  000001fa 8b01a8c0 00000018 000001fa
3ffffef0:  00000018 00000000 3ffeea40 401074e4
3fffff00:  40100000 00000000 00000064 3fff0270
3fffff10:  3ffeb79a 3fff0274 3fff09bc 40228139
3fffff20:  3ffeff94 3fff072c 3fff072c 3ffedaf0
3fffff30:  00000000 3fff09bc 0000001c 3fff072c
3fffff40:  3ffeb78c 00000000 3fff09bc 40227535
3fffff50:  6301a8c0 00000258 00000000 0000001c
3fffff60:  00000002 0000001a 40207f53 3ffec9a8
3fffff70:  3ffeb764 3fffdcc0 3ffe9040 3ffe9040
3fffff80:  40207ec6 3ffec9a8 00000000 3fff079c
3fffff90:  3fffdc80 00000000 3fff09bc 4021bfbb
3fffffa0:  40000f49 3fffdab0 3fffdab0 40000f49
<<<stack<<<

ets Jan  8 2013,rst cause:2, boot mode:(1,7)

ets Jan  8 2013,rst cause:4, boot mode:(1,7)

wdt reset

fauxmo.enable(true); is in different spot in the example at https://bitbucket.org/xoseperez/fauxmoesp

comment out all the motor code .... do you still get the error?

Hi @jsotola thanks for your suggestion.
I commented out all the motor code and nothing had a panic this time. I then went back and uncommented the motor code but removed any calls for functions that would involve invoking the code. (Specifically I commented out line 113 where I call for 'openCurtain();' This is also worked without a panic.
So it only seems to panic when the motor code tries to execute something.

I guess motor code does not finish executing within allowed time slot. Thus watchdog resets the esp.

That sounds like it could be the problem. Is there a way to execute the motor code whilst letting the watchdog know the code is working on something and not to restart?

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

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


text:
Combining two sketches that both work on their own, but don't work when combined
I've got a program for a password protected doorlock, which I got working.
I'm trying to add to the code, to add functionality where I can toggle an LED on/off with a button.
Both codes function on their own and serve their desired purpose, but when I try to combine them into the same sketch, the LED button works but the rest of my design stops working. I can no longer input a password to activate the motor.
How can I combine the two codes and have them both work?
Here is the working keypad/lock code
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <Keypad.h>

#define Password_Length 5

int signalPin = 10;
int greenLedPin = 11;
int redLedPin = 12;
char Data[Password_Length] = "4";
char Master[Password_Length] = "1234";
byte data_count = 0, master_count = 0;
bool Pass_is_good;
char customKey;

const byte ROWS = 4;
const byte COLS = 3;
bool ledState = 0;

char hexaKeys[ROWS][COLS] = {
  {'1', '2', '3'},
  {'4', '5', '6'},
  {'7', '8', '9'},
  {'*', '0', '#'}
};

byte rowPins[ROWS] = {9, 8, 7, 6};
byte colPins[COLS] = {5, 4, 3};

Keypad customKeypad = Keypad(makeKeymap(hexaKeys), rowPins, colPins, ROWS,     COLS);

LiquidCrystal_I2C lcd(0x3f, 16, 2);

void setup()
{
  lcd.init();
  lcd.backlight();
  Serial.begin(9600);
  lcd.clear();

  pinMode(redLedPin, OUTPUT);
  pinMode(greenLedPin, OUTPUT);
  digitalWrite(redLedPin, LOW);
  digitalWrite(greenLedPin, LOW);
}

void loop()
{
  lcd.setCursor(0,0);
  lcd.print("Enter Password:");

  customKey = customKeypad.getKey();
  if (customKey){
    Data[data_count] = customKey;
    lcd.setCursor(data_count,1);
    lcd.print(Data[data_count]);
    data_count++;
    }

if(data_count == Password_Length-1){
    lcd.clear();

    if(!strcmp(Data, Master)){
      lcd.print("Correct");
      pinMode(signalPin, OUTPUT);
      digitalWrite(signalPin, LOW); //turns on motor
      digitalWrite(greenLedPin, HIGH); //turns on led
      delay(2000);
      digitalWrite(signalPin, HIGH); //turns off motor
      digitalWrite(greenLedPin, LOW); //turns off led
      }
    else{
      lcd.print("Incorrect");
      digitalWrite(redLedPin, HIGH); //turns on led
      delay(2000);
      digitalWrite(redLedPin, LOW); //turns off led
      }

    lcd.clear();
    clearData();
  }
}

void clearData(){
  while(data_count !=0){
    Data[data_count--] = 0;
  }
  return;
}

and here is the code I'm using for the LED on/off toggle button
int button = 2;
int led = 13;
int status = false;

void setup(){
pinMode(led, OUTPUT);
pinMode(button, INPUT_PULLUP); // set the internal pull up resistor,
unpressed button is HIGH
}

void loop()
{
//a) if the button is not pressed the false status is reversed by !status
and the LED turns on
//b) if the button is pressed the true status is reversed by !status and
the LED turns off

if (digitalRead(button) == true) {
status = !status;
digitalWrite(led, status);
} while(digitalRead(button) == true);
delay(50); // keeps a small delay
}

I just figured out that the original password code will still function, but only if i keep the LED toggle button held down.

By the way, digitalRead does not return true or false, it returns HIGH or LOW. Coincidentally they are the same numbers internally, but it is better practice to check for what the function is documented to return. See: https://www.arduino.cc/reference/en/language/functions/digital-io/digitalread/

Let's step back from the Arduino for a minute and ask: assuming you know how to cook some bacon, and also how to boil some eggs, how would you simultaneously cook bacon and eggs?
Basically you would have to interleave any process (such as waiting for the water to boil) with some other process (such as waiting for the bacon to cook).
Once you have this concept in your head you can just take the two pieces of code, and wherever you are planning to wait for something to happen, see if the other thing is able to be done.
I have done a post about this: http://www.gammon.com.au/blink

I just figured out that the original password code will still function, but only if i keep the LED toggle button held down.

Well, you need to remove any blocking loops from either part of the code.
Your code here blocks:
if (digitalRead(button) == true) {
status = !status;
digitalWrite(led, status);
} while(digitalRead(button) == true);

That's like (in my analogy) of thinking "oh the water is boiling, I'll have to stare at the eggs until they are cooked". Instead you could check the bacon, check the eggs, check the bacon again, and so on.
I'm giving you these analogies to help you solve the general problem, not this particular bit of coding.

i understand that the code blocks, but that code also makes the LED toggle on and off like i need, so how do i integrate that in a way that it doesnt block the rest?

Replace the LED code with something like this (not compiled or tested):
void loop ()
  {
  static int oldReading = LOW;
  int newReading = digitalRead (button);
  if (newReading != oldReading)  // it changed!
    {
    oldReading = newReading;  // remember new reading state
    if (newReading == HIGH)
      {
      status = !status;
      digitalWrite(led, status);
      }  // end of a HIGH reading
    }  // end of changed state

   // password stuff here

   }  // end of loop

Now, whatever you do with the button, the code doesn't stop (block) so the password stuff is still executed.

thanks, that makes sense, but im too new to this stuff to know how to rectify that

i understand that the code blocks, but that code also makes the LED toggle on and off like i need, so how do i integrate that in a way that it doesnt block the rest?


text:
Attiny85 route vcc though output pin
I'm still learning the basics so please bare with me if something seems unclear ;-)
I want to hook up an Attiny85 to a WiFi module (esp8266) and 2 sensors. The VCC will be provided by a battery pack and a step-up/step-down converter to ensure steady voltage without too much efficiency loss. Right now the modules are all hooked up to the VCC rail, together with the Attiny85 in one circuit.
I would like to take a sample, and then make as much of the circuit power down until the next reading with a 2 minute interval or so.
While looking for power saving modes for the esp8266 and struggling a bit with it, it got me thinking. What if I let Attiny85 handle the WiFi and sensors circuit via an OUTPUT pin and just turn that high or low. I read somewhere that an OUTPUT pin would not be able to supply as much current as if it was directly connected. That would probably be the case for me here since the WiFi module draws significant current.
Maybe using a transistor to "flip the switch" be a good solution instead if that is the case?
So my question is, is my way of thinking here even viable? How do I know what kind of max current can go through an OUTPUT pin?

Sorry, maybe I don't understand your point but an esp8266 far exceeds that current draw. Would those numbers not confirm my concern?

Sorry, I mis-read.

No problem. If the numbers are correct though, it sort of answers at least a portion of the question.

Absolute maximum current for a pin is 40mA. A transistor/mosfet would be a good solution. Make sure all other pins going to the ESP are set to LOW before turning off the power to the ESP. Voltage on the input pins of the ESP should not exceed its Vcc, which will become 0Volt once you turn off the transistor.

What you want is a P-channel MOSFET to control the power. Something with a nice low "logic level" gate threshold.

simulate this circuit – Schematic created using CircuitLab
R1 keeps it switched off.  Set the output to LOW to pull the gate down and enable the MOSFET.
Be sure to "stop" your Serial connection and set both TX and RX pins to INPUT to prevent damage to the ESP8266 (or ATTiny) while powered off.

Might need transistors between the Aduino and the ESP8266 to break the Rx/Tx lines. Otherwise they could go higher (due to the USB interface on the Arduino, which is connected to D0/D) then the ESP8266's VCC pin and could damage the diode clamp's on the ESP8266 inputs, or possibly appear to phantom power it.

I will try to find one that suits my needs and try it out. Regarding the tx/rx lines I set them both to LOW and INPUT before cutting the power. Would that be enough or will the above still be an issue?

That is good. That is really all you need to do.

In my case VCC will be 3.3V and since GPIO is also from the same power source it will also be 3.3V. Also, once the circuit is cut off from power, I would like to put the attiny85 in sleep mode and not use any power for a while. If I understand this correctly, a P-channel MOSFET needs power to cut the power, is that correct? With this in mind, is this component still the one I want? Sorry, I might not have explained this very well in my question.

It needs a voltage. No (or miniscule) current though. The gate is like a capacitor. Once charged it doesn't draw anything to speak of - only tiny leakage current too small to measure.

Oh now I understand! Thank you so much. Will digitalWrite(pin, LOW) "pull the gate down"? Guess the only thing to look for now is one that has a volt range within 3.3V and try it out!

Yep, LOW is "on", and "INPUT" or "HIGH" are off.

Would this one be a good choice? I'd rather have one with pins like a "normal" transistor, but it doesn't matter that much. Why are the voltages negative?
http://www.onsemi.com/pub/Collateral/FDN302P-D.PDF

That's pretty good, yes. The voltages are relative to source, and the source is the highest potential in a P fet, so everything is below it.

Just curious, would keeping the p channel mosfet gate high in this circuit even with the resistor draw current (obviously yes, but pretty low) while an n channel would not draw any current at all while the circuit is open and gate pulled low? I’m using batteries in this project so every uA is precious.

No, it won't. The gate is like a capacitor. Once charged nothing more flows.

Perfect! Thank you so much for your help!

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


text:
HC-05 and p-channel mosfet
I'm trying to use a MOSFET (BS250P datasheet) to switch a circuit on and off while the MCU is asleep. It's a P-channel MOSFET that closes the circuit when the gate is pulled low. The most power hungry module in my circuit is a HC-05 bluetooth module. The specs on the website I bought it at rates it at 3.3V - 6V and a max current draw of 50mA when pairing and around 9mA when connected. Hooking it up to an Arduino 3.3V source confirms that it works at that voltage and pairs it up with another identical module just fine.
Now when I put that same 3.3V source through the MOSFET with a 10k pull up resistor and connects the HC-05 to the drain, the module does not power up. I measured the voltage on the drain and when nothing is connected it's the same as the source. After connecting the HC-05 it's about 2.4V (maybe this is a clue). Even if I run the power through a step up converter to 4.10V it does not power up through the MOSFET. If I increase the voltage to 5V it all works fine. I would ideally run the circuit at 3.6V in order to preserve current for the rest of the modules, and not having to use a voltage regulator for the RX of the HC-05.
I assume the issue is with the MOSFET properties, but as far as I can read from the datasheet it can sustain 230mA current. It has a VGS(th) of 3.6V, but since I'm always pulling the MOSFET low in this scenario that shouldn't be an issue? Measuring the resistance when the gate is pulled low indeed gives just a few ohms as the datasheet suggests.
So basically, what am I missing here? :-) Thank you for any help with this!

That's not a good choice of MOSFET I'm afraid.
The on resistance is quoted as 14Ω when the gate is at -10V - however, you are only able to get -5V, so it will be considerably worse.
That massive on resistance will be causing a massive voltage drop, which is what you are experiencing.
You should find a MOSFET with an on resistance that is in the milli-ohm range when the gate is between 0V and -5V.

Hi again Majenko and thank you! I know it's not allowed to ask for shopping items etc so I won't, but these would be available with pins as well, not only surface mounted?

You may need to shop around a little for a through-hole one. I only ever use SMD devices unless I have a really good reason not to, so I don't know what is available in larget packages.

The problem with through-hole is they tend to be either high on resistance (i.e., low current capacity) for logic switching, in a small (TO-92) case, or low on resistance for high current use, and hence in a (relatively) massive TO-220 case. For instance the NDP6020P has the resistance specs you want but is aimed at higher currents, so is chunky.

The LP0701N3 has higher resistance, though considerably lower than your current one, but in a smaller case.

Thanks for the links! I found the NDP6020P in my go to shop for electronics. Apart from being clunky, even in a battery scenario it would actually perform better in terms of battery life with less resistance than the LP0701N3?

It wouldn't make much difference really.

I ordered both and will experiment, measure and learn. Just one more thing that I don't yet understand is that when I use the mosfet I have now and I pull the gate to -3.3V, the resistance over D and S is only 7 ohms. I must be misunderstanding something here because I'm experiencing the voltage drop when the module is connected, but not when it's not connected. I'm assuming that current has something to do with the resistance increase in the mosfet when the load is there?

Yep, it sure does. It's non linear.

Got the mosfets (both of the 2 you mentioned) and confirmed that they work exactly like I want them to. Thanks again Majenko!


text:
Attiny85 SoftwareSerial not working on battery power
I have a very small test project running on an Attiny85 (set to internal 8MHz).
Everything works when powering the circuit from an Arduino (3.3 or 5.0 volt). But when changing the  power to a 18650 battery with a voltage of around 4.0v the Attiny85 still works, because the LED blinks, but nothing is coming through via the UART. What could be the reason for this?
#include <SendOnlySoftwareSerial.h>
#define PHOTO_RESISTOR_PIN A1
#define UART_TX_PIN 0
#define LED_PIN 1

SendOnlySoftwareSerial esp(UART_TX_PIN);

void setup() {
  esp.begin(9600);
  pinMode(PHOTO_RESISTOR_PIN, INPUT);
  pinMode(LED_PIN, OUTPUT);
  pinMode(UART_TX_PIN, OUTPUT);
}

void loop() {
  digitalWrite(LED_PIN, HIGH);
  int light = analogRead(PHOTO_RESISTOR_PIN);
  esp.println(light);
  delay(1000);
  digitalWrite(LED_PIN, LOW);
  delay(1000);
}

Do yoou not have the ground of the ATTiny circuit connected to the ground of the UART board???

That was it! So the reason why that works when running off the Arduino power is that they share the same ground in the computer (that powers them both)?

Yep. You might like to read this:https://majenko.co.uk/blog/importance-sharing-grounds

Absolutely, thank you!

Unless you connect the ground of your ATTiny to the ground of your USB UART interface there is no circuit for the electrons to flow around.
It works when powered from the computer because everything shared the same ground connection.


text:
Send readings to PC using HC-05
My project, briefly explained is a weather station that will send data periodically from an Arduino UNO (later an attiny85) to my PC for processing. I'm using a HC-05 bluetooth module to establish a serial connection to my (Linux Mint) Laptop. That all works with blueman-manager and rfcomm using gui tools manually.
So here comes the twist. Since the bluetooth module draws significant current, I will shut it down when it's not used by simply disconnecting the power to it and the sensors. Then I would like the module to wake up when the power comes on again and send the readings to the PC, automatically.
From what I read a bluetooth module can only initiate a connection in master mode. I have tried setting this with an AT command and that part works, but I don't know how to go about creating the persistent connection to my PC that will connect up again after a power loss so that I can send the next reading.
Another part of this is of course that the Laptop running Linux Mint must be able to create the serial port (or ideally use the same port) when the bluetooth module wants to send data.
I realize this question is a bit broad, but any pointers are welcome and I'm curious first of all if this is the right way of accomplishing this task.
Thank you!

I can't answer your question on BL but here's a suggestion: Why not use a Bluetooth Low-Energy module (like the HM-10)? These modules should be well-designed for continious low-power consumption and deepsleep capabilities. You could also use the ESP32 with onboard BLE and put that chip into deepsleep, or any other kind of ultra-low-power BLE beacon.

You might also find this interesting: https://www.youtube.com/watch?v=1i-6cz4KHXE

That is very interesting, thank you! Do you have any experience using the HM-10? I'm a little confused on how to use the AT commands on them that would initiate the sleep mode. On the EC-05 I set it by holding the button and it enters a separate mode. On the EM-10 it seems to be able to accept AT commands in "normal" mode? That would actually be much better since the Arduino could then send that command whenever it wanted without having to set it to AT mode. Can't seem to find any information on that :-/


text:
eclipse photon with cdt-arduino plugin can't upload sketches
i've recently decided to give eclipse-photon-cdt a shot. i use it with the built in arduino plugin, downloaded my feather m0 board config and tried to upload an empty sketch. failed, the console shows it tries to connect but fails. of course arudino ide 1.8.5 succeeds wonderfully.
point is if i copy paste the command line activating bossac i get the same result. i also know why. when using scripts i need to use a python scripts that uses serial signaling to reset the feather into bootloader mode. arduino ide does it on his own probably using java. eclipse doesn't do that which sounds like a huge bug to me.
am i missing something ? or did they actually assumed i'll press twice on the reset button on the board each and every time i want to upload a sketch ?

if you want to use Eclipse with Arduino, use Sloeber plugin

that's a poor answer, it tell me don't use that tool, use another, i'm not keen on eclipse i can use any other tool or build system like cmake\make\platformio or frameworks like zephyr or mynewt that already have it and use vim\sublime etc... suggesting another tool does not solve my problem only promoites that you are using another tool you like better.

It is not an answer. Majenko wrote a good answer. It is "If you want to use Eclipse". Sloeber integrates into Eclipse the Arduino build tools and hardware packages of Arduino IDE. the reset there works

It sounds to me like Eclipse doesn't know how to reboot the board into the bootloader.
Traditional Arduinos automatically boot into the bootloader when the board is reset, and the board resets every time you open the serial port thanks to the USB chip having DTR connected (through a capacitor) to the reset pin of the man MCU.
Chips with a direct USB connection can't do that (boards like the M0 Feather, the Leonardo, etc).  Instead they have to be rebooted by opening the serial port at 1200 baud and then closing it again.
With the "traditional" boards the IDE neither knows, nor cares, about rebooting the board - it just happens. However with direct USB boards the IDE has to have specific code to perform the reboot at the right time. The Arduino IDE has that code. However I would guess that the Eclipse plugin either doesn't implement that, or doesn't have the ability to implement it.
So you will have to manually reset the board for programming.

i thought so. it's interesting about the AVR's didn't know that, is the capicitor resides inside the MCU or is it external part that is connected to the USB ? also the DTR is set or reset when the port opens ? AFAIK it's supposed to be set when the port is open, but if u want to reset the board you want to pull down the reset pin meaning you want DTR to be unset. can you please elaborate ?

Capacitor is external. DTR is an active low signal.


text:
How to write a code to detect how many times the IR detector has detected an IR signal.... HELP
I am trying to write a code so that I can detect how many times the IR detector has detected the IR signal from the IR transmitter.

Welcome to Arduino:SE. What have you managed to do so far?. You might find this helpful: How to ask a good question for Arduino Stack Exchange

Its quite simple:
IRDetectorLibraryObject ir;
int counter = 0;

void setup()
{
    ir.setup();
}
void loop ()
{
    if (ir.detectedSignal())
    {
      ++counter;
    }
}

Of course all that relies on you having an IR detector library like the one i imagined you had, and you only wanting to count the detections and never know what the value is, but apart from that...

It would be great if you can also give us the circuit diagram...

The compiler says it cannot recognize the data type of IRDetectorLibraryObject

It wont recognise it because you need to find one that is compatible with your hardware and use that name instead.  As for a circuit diagram that depends on you hardware, if you don't specify that then I can only guess that you need to plug the wires from the IR detector into a microprocessor, and you might want to power the uP from a 5v source, but your hardware may be different to the hardware I am imagining you have.


text:
trouble getting out of a for loop in a function and go back to a FSM with a button
I have a finite state machine that goes to a function called patternOne, I can't seam to get out of this function though once I am in it and get back to the finite state machine. When I press a button my serial port shows it's been pressed but still stays in the function patternOne, I don't know how to get out of it and why this is happening. My code is below:
#include <SPI.h>
SPISettings settingsA(2000000, MSBFIRST, SPI_MODE1);
#include <SFE_MicroOLED.h>  // Include the SFE_MicroOLED library
#include <Wire.h>  // Include Wire if you're using I2C
volatile unsigned long prevTime = 0;

int time_interval_for_chip = 5;
int blinking_interval = 500;
unsigned long current_time = 0;
#define PIN_RESET A6  // Connect RST to pin 9

#define DC_JUMPER 0

MicroOLED oled(PIN_RESET, DC_JUMPER);// I2C declaration

const int buttonpin = A8;
volatile int buttonState = 0;   // variable for reading the pushbutton status
volatile int buttonState2 = 0;
int buttonstate3 = 1;
const int buttonpin2 = A7;

enum State {flip, intro, option1, pattern1, intro_flip, option1_flipped, pattern1_flipped, pattern2, pattern3};
//enum is the data type that consists of user defined varaibles ie like the words pattern, intro, ext
State state = flip; //telling the intial state to start at intro

unsigned int column_pattern1[] = {0b0000000100000100, 0b0000001000001000,0b0100000010000010};
//unsigned int column_off_pattern1[]={0b0000000000000100, 0b00000000000001000,0b0100000000000010};
const int css1 = 10;
const int css2 = A0;
void setup() {
  oled.begin();    // Initialize the OLED
  oled.clear(ALL); // Clear the display's internal memory
  //  oled.display();  // Display what's in the buffer (splashscreen)
  //  delay(1000);     // Delay 1000 ms
  oled.clear(PAGE); // Clear the buffer.
  //

  pinMode(css1, OUTPUT);
  pinMode(css2, OUTPUT);
  Serial.begin(9600);
  SPI.begin();
  SPI.beginTransaction(settingsA);

  pinMode(buttonpin, INPUT_PULLDOWN);
  pinMode(buttonpin2, INPUT_PULLDOWN);
  // watermark generates this interrupt
  attachInterrupt(buttonpin, button_pressed, FALLING); // interrrupt 1 is data ready
  //attachInterrupt(buttonpin2, button_pressed2, FALLING); // interrrupt 1 is data ready

}

void loop() {

  // blinking output 4 and 8 while using a finite state machine to change from intro to a patter
  //turning off the desplay when a pattern is chosen

  switch (state) {
    case flip:
    oled.setFontType(1);
  oled.setCursor(0, 0);  // Set the text cursor to the upper-left of the screen.
  //oled.setFontType(2);
  //  oled.setCursor(0, 0);
  oled.print(" Flip  Screen?");
  oled.setFontType(0);
  oled.setCursor(0, 30);
  oled.print("yes");
  oled.setCursor(40, 30);
  oled.print("no");
  oled.circle(10, 43, 3.5);
  oled.circle(50, 43, 3.5);
  oled.display();
  buttonState = 0;

  if (digitalRead(buttonpin2) == HIGH) {
        oled.circleFill(50, 43, 3.5);
        oled.display();
        oled.clear(PAGE); // Clear the buffer.
        delay(500);
        //buttonstate3=0;
     state=intro;
  }
   if (digitalRead(buttonpin) != buttonState) {
    oled.circleFill(10, 43, 3.5);
     oled.display();
        oled.clear(PAGE); // Clear the buffer.
        delay(500);
        state=intro_flip;
   }
  break;

    case intro:

      oled.setFontType(1);
      oled.setCursor(0, 0);  // Set the text cursor to the upper-left of the screen.
      //oled.setFontType(2);
      //  oled.setCursor(0, 0);
      oled.print("choose pattern");
      oled.circle(10, 40, 7);
      oled.display();
      buttonState = 0;

      if (digitalRead(buttonpin) != buttonState) {

        buttonState = 0; //reset button state
        oled.circleFill(10, 40, 7);
        oled.display();
        delay(500);
        state = option1;

      }
      break;

    case option1:
      oled.clear(PAGE); // Clear the buffer.

      //delay(300);
      oled.setFontType(0);
      oled.setCursor(0, 0);  // Set the text cursor to the upper-left of the screen.
      //oled.setFontType(2);
      //  oled.setCursor(0, 0);
      oled.print("Pattern 1");
      oled.setCursor(0, 10);
      oled.print("next");
      oled.setCursor(40, 10);
      oled.print("yes");
      oled.circle(10, 40, 7);
      oled.circle(50, 40, 7);
      oled.display();

      if (digitalRead(buttonpin2) == HIGH) {
        Serial.println("right button pressed");

        oled.circleFill(50, 40, 7);
        oled.display();
        delay(500);
        state = pattern1;

      }
      break;
        case pattern1:
      oled.clear(PAGE);
      oled.display();

      patternONE();
      buttonState=0;
      if (digitalRead(buttonpin) != buttonState) {
        Serial.println("left button pressed");
        //         //delay to register that the button was pressed
        delay(500);
        //
        state = intro;
      }
      break;

////////////////////////////////////////////////////////
///////////FLIPPED FINITE STATE MACHINE/////////////////
////////////////////////////////////////////////////////

case intro_flip:
  oled.flipVertical(true);
    oled.flipHorizontal(true);
     oled.setFontType(1);
      oled.setCursor(0, 0);  // Set the text cursor to the upper-left of the screen.
      //oled.setFontType(2);
      //  oled.setCursor(0, 0);
      oled.print("choose pattern");
      oled.circle(50, 40, 7);
      oled.display();
      buttonState = 0;

      if (digitalRead(buttonpin) != buttonState) {

        buttonState = 0; //reset button state
        oled.circleFill(50, 40, 7);
        oled.display();
        delay(500);
        state = option1_flipped;

      }
      break;

      case option1_flipped:
oled.flipVertical(true);
    oled.flipHorizontal(true);
      oled.clear(PAGE); // Clear the buffer.

      //delay(300);
      oled.setFontType(0);
      oled.setCursor(0, 0);  // Set the text cursor to the upper-left of the screen.
      //oled.setFontType(2);
      //  oled.setCursor(0, 0);
      oled.print("Pattern 1");
       oled.setCursor(0, 10);
      oled.print("yes");
      oled.setCursor(40, 10);
      oled.print("next");
      oled.circle(10, 40, 7);
      oled.circle(50, 40, 7);
      oled.display();

      if (digitalRead(buttonpin2) == HIGH) {
        Serial.println("right button pressed");

        oled.circleFill(10, 40, 7);
        oled.display();
        delay(500);
        state = pattern1_flipped;

      }
      break;

       case pattern1_flipped:
      oled.clear(PAGE);
      oled.display();

      patternONE();
//      buttonState=0;
      if (digitalRead(buttonpin) != buttonState) {
        Serial.println("left button pressed");
        //         //delay to register that the button was pressed
        delay(500);
        //
        state = intro_flip;
      }
      break;

  }
}////////////////////////////////////////////////////////
///////////Pattern/////////////////
////////////////////////////////////////////////////////
void patternONE() {
buttonState = 0;
   unsigned int chip1 = 0;
  unsigned int chip2 = 0;
  byte inbyte = 0;
  byte inbyte2 = 0;

  for (int i = 0; i < 3; ++i) {

    digitalWrite(css2, LOW);
    chip2 = SPI.transfer16(column_pattern1[i]);
    Serial.print("chip2 column off=");
    Serial.println(chip2, BIN);
    digitalWrite(css2, HIGH);

    digitalWrite(css1, LOW);
    chip1 = SPI.transfer16(0b0001010000000000);
    Serial.print("chip1 row 8 on high driver= ");//not the chip is a look behind so the print statments are the previous output
    Serial.println(chip1, BIN);
    digitalWrite(css1, HIGH);

    delay(1);
    digitalWrite(css1, LOW);
    chip1 = SPI.transfer16(0b0100000100000000);
    Serial.print("chip1 row 4 and 6 on low driver= ");
    Serial.println(chip1, BIN);
    digitalWrite(css1, HIGH);

    delay(2000);

    digitalWrite(css1, LOW);
    chip1 = SPI.transfer16(0b0001010001010000);
    Serial.print("chip1 row 8 on low driver= ");
    Serial.println(chip1, BIN);
    digitalWrite(css1, HIGH);

    delay(1);

    digitalWrite(css1, LOW);
    chip1 = SPI.transfer16(0b0100000100000100);
    Serial.print("chip1 row 4 and 6 on high driver= ");
    Serial.println(chip1, BIN);
    digitalWrite(css1, HIGH);

    digitalWrite(css2, LOW);
    chip2 = SPI.transfer16(column_pattern1[i]);
    Serial.print("chip2 column on high driver= ");
    Serial.println(chip2, BIN);
    digitalWrite(css2, HIGH);

    //turn off the previous column
//    digitalWrite(css2, LOW);
//    chip2 = SPI.transfer16(column_off_pattern1[i]);
//    Serial.print("chip2 column on high driver= ");
//    Serial.println(chip2, BIN);
//    digitalWrite(css2, HIGH);
//
    delay(2000);

  }

}

// watermark generates this interrupt
void button_pressed()
{
  cli();
  //confirmitng that the button was pressed and that its not just like a bounce"
  if (millis() - prevTime > 50) {
    Serial.println("left button pressed");
    buttonState = 1;
  Serial.println("buttonState =");
  Serial.println(buttonState);
  }

  sei();
  prevTime = millis();

}

You could start with some old fashioned brute force Serial.println debugging.  Print the current state before the switch & print every change of state then add more printlns as needed to track down the error.

How do you know you never leave PatternONE() and are not just calling it over and over again?

hum thats a good question, if i'm calling it over and over again how do I leave it then?

See earlier comment -- debug with Serial.println()

thanks for the help Craig! it worked when I did the brute fore,

From your question, it sounds like you are expecting PatternONE() to return on a button press but I don't see any code in the function that refers to a button or acts on one. The function defines a local variable buttonState and initializes it to 0, but never refers to it again.
I suspect you meant that as a declaration of the global buttonState, but you have two problems: 1) the function never uses buttonState to initiate a return; and 2) the local definition buttonState hides the global one while it is in scope; i.e., while the function is executing.

Unless some code is missing, patternOne() does not declare a local variable.  It assigns a value of 0 to the global variable.

Oops - correct. It does reset the global, but never refers to it again.

it turned out I was suppose to comment out the buttonState=0; right after the patternONE(); in the case pattern1 and then it worked fine.


text:
Interesting issue with my wifi Car project
Hello so i build a nodemcu wifi controlled car, everything works fine expect i have one small issue, currently i have 2 9v batterys, one of them is connected to motor controller and other one is connected to nodemcu.. but the nodemcu's 9v battery gets hot in a minute and stops working. What am i doing wrong? + is connected to vcc and - is connected to grnd on nodemcu.

Have you measured the current flow from the battery that's getting hot with a multimeter? Have you checked for shorts? Do you need a common ground between the two batteries? Can you upload a complete schematic of your project by using the schematic tool (Ctrl+M)?

zinc-carbon battery? i did not think that they made those anymore.

the nodemcu's 9v battery gets hot in a minute and stops working. What am i doing wrong?

You're using a 9V battery.
Those batteries are useless. They have very little capacity, and can provide very little current. The NodeMCU needs a lot of current.
Choose a better battery. Maybe a Li-Poly battery would be good (mobile phone batteries are good for this).

This site suggested 9v batterys http://henrysbench.capnfatz.com/henrys-bench/arduino-projects-tips-and-more/powering-the-esp-12e-nodemcu-development-board/

LG B4 18650 li-ion battery 2600mAh 3.7V, is this okey?

@SezerYıldız No the site said This is my least favorite option. I don't call that a recommendation ;-) For the 18650 you may need a Step-up booster and deep discharge protection if not built in.

18650s are good cells. I'm not sure what the LDO dropout on the NodeMCU is off hand, but since a lithium cell is nearer 4.2V when fully charged it should be good for most of its charge range.

alright, i will open one of my xianomi powerbanks and extract the li ion batterys!

@SezerYıldız keep the protection circuitry on them intact and connected. That will prevent overdischarge and overcharging; both of which can be dangerous.

@ratchetfreak Over-discharge of a single cell isn't dangerous. It's not even unrecoverable. What is dangerous is over-discharge of a single cell in a multi-cell (series) pack which causes that cell to reverse charge with the current flowing from the other cells causing copper to pierce the electrolyte layer causing a short internally.

Why crack out the cells out of a power bank? Just use the 5V / 1A (probably) output of that power bank to power the NodeMCU. That's less work for the LDO / less heat to produce than with the 9V battery, and the USB power bank can output much higher currents.

Size? Maybe it's a large power bank, but only 1 cell would suffice for the project...

Yes majenko its a small car, but i have a big powerbank thats why i took out one soon i will post a picture


text:
Arduino Mega Pins for SoftwareSerial (vs. AltSoftSerial)
I am currently looking at using an Arduino Mega to build a MIDI Receive box that will then pump the data over USB, but am having design issues/uncertainties with the Arduino's receiving end.
I am looking to having (hopefully) 16 MIDI (as 5-pin DINs) inputs on this build, with no outputs other than the USB. The Mega has the 4 Rx pins, which still leaves me with 12 to create in software. From what I've read it appears that SoftwareSerial will not support simultaneous reads from different inputs, while AlftSofSerial does. However, it also appears (at least from what I've gathered) that AltSoftSerial is not supported on as many pins as I would need to make this work.
With my setup up, not all 16 MIDI devices would be sending data into the Arduino at once, but only 2 - 4; these would be operating at the same time though (i.e. a Keyboard note along with a volume fader), so I don't believe SoftwareSerial would work well for what I need.
Is it possible to work out what I need with SoftwareSerial/AltSoftSerial and the physical UARTs? If there's any necessary info that seems to be missing or I seem to be misunderstanding something, please let me know. Thanks!

It seems altsoftserial only supports one instance. Do you only need RX for MIDI? What baudrate?

For such a specialized application, you probably cannot rely on a library and have to program the hardware directly.

@Gerben I do only need it for MIDI. I was using 9600 in my hardware "tests" with only one device and it seemed to be working fine.

@CL I'll have to look up how to do this. Any helpful links to point me in the right direction?

AVR304 might be a start. But you need enough knowledge and experience to write your own AltSoftSerial library and to improve on that.

From what I've read it appears that SoftwareSerial will not support simultaneous reads from different inputs

Correct. You can only listen() on one instance at a time.
AltSoftSerial can only support 1 instance, but allows simultaneous transmit and receive, and doesn't block the whole system while either transmitting or receiving.
So the best you can hope for is 4 hardware UART and one AltSoftSerial for 5 ports.
I would suggest looking into the possibility of using multiple Arduino Mega boards with 4 ports on each (4 boards would give 16 ports in total) and have them communicate with each other through some other protocol (SPI or I2C for instance).

I had initially considered a setup similar to this, but had shrugged it off in an attempt to cut down costs, but looks like that may be the route to travel. Do you happen to know if there is another device with more UARTs? I was looking at the newest version of the Teensy, but it still only has 6.


text:
Arduino Pro Mini stopped working / broken
I need help, currently I am working in final project about portable monitoring system. I am using Arduino Pro Mini 5V/16MHz as microcontroller and a Li-Po battery to power it up through XL6019 boost converter. I have created the PCB and assembly all components but suddenly when I turned it on, the Arduino Pro Mini suddenly stopped working. Recently I am adding a feature to measure the battery capacity so I connected the battery voltage to arduino pro mini Analog Pin, is that the problem? But I have tested the method of measuring battery capacity using Arduino Uno before and it worked fine. .
I am confused right now about what is the main problem.. and also is there any way to repair the Pro Mini? The Pro Mini used in project can't be reseted and I can't upload any program to it.
Pls help.

What voltage did you connect to the Pro Mini's analog pin? Was it greater than 5 VDC?

The Li-Po battery output voltage, it around 3V - 4.2V (fully charged).

Are you have checked the voltage in the output of XL6019 is 5V?


text:
Linux can not open arduino IDE - java.lang.NullPointerException
I use arch linux. I installed arduino ide with pacman. When I try to run it, loading window will show for few socends and than program crashes. There are logs:
john@arch-thinkpad ~ [1]> arduino
Picked up JAVA_TOOL_OPTIONS:
Set log4j store directory /home/john/.arduino15
java.lang.NullPointerException
    at processing.app.Base.rebuildProgrammerMenu(Base.java:1705)
    at processing.app.Base.<init>(Base.java:286)
    at processing.app.Base.main(Base.java:150)
john@arch-thinkpad ~ [255]>

john@arch-thinkpad ~> arduino --version
Picked up JAVA_TOOL_OPTIONS:
Loading configuration...
Initializing packages...
Preparing boards...
Arduino: 1.8.13

What should I do to fix it ?
Thank you for your help

Delete your preferences.txt file.

I had to install arduino-avr-core package:
sudo pacman -S arduino-avr-core

Now it works fine

The first thing to do is delete your preferences.txt file. This is the most common cause of startup issues - some corruption or an invalid setting in that file can break the IDE completely.
rm ~/.arduino15/preferences.txt

If that doesn't fix it then you can delete your entire Arduino working directory, which will remove all installed cores and boards and give you a fresh installation:
rm -rf ~/.arduino15

There was some corruption to the package_index.json a little while ago - mid July - perhaps the OP was affected by that, even though it though the post phrasing suggests that they have only just installed the Arduino IDE. Anyway, the fix for that issue was to remove file ~/.arduino15/package_index.json and remove folder ~/.arduino15/cache - which would be worth trying before deleting the preferences file or entire settings directory if it is an old/configured install.

Thank you for your answer but it did not change anything and issue still remains.


text:
ESP8266 GET request code -1
I've read several other posts but I still couldn't solve the issue. I'm trying to connect to a website which is HTTP (not HTTPS) but I always get code -1 as response. If I open the link in the browser it works well. Not sure what I am missing? Here's my full code:
#include <ESP8266HTTPClient.h>
#include <esp8266wifi.h>

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

void setup() {
  Serial.begin(115200);
  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {

    delay(1000);
    Serial.print("Connecting..");

  }
}

void loop() {

  if (WiFi.status() == WL_CONNECTED) {
    HTTPClient http;
    http.begin("www.francescosoave.com/blind/getTime.php");
    http.addHeader("Content-Type", "text/html");
    int httpCode = http.GET();

    Serial.print("HTTP CODE: ");
    Serial.println(httpCode);

    if(httpCode > 0){
      String payload = http.getString();
      Serial.print("PAYLOAD: ");
      Serial.println(payload);
    }

    http.end();
  }

  delay(2000);
}

You omitted the protocol part of the url. The HttpClient implementation requires it.
Use http.begin("http://www.francescosoave.com/blind/getTime.php");
Do not use Content-type header. You do not send any content.
Turn-on debug in Tools menu. Set Debug Port to Serial and Debug Level to HTTP_CLIENT to see the error messages.

to add an additional point to @juraj answer these are the HTTP code for various errors written in ESP8266HTTPClient.h
#define HTTPCLIENT_DEFAULT_TCP_TIMEOUT (5000)

/// HTTP client errors
#define HTTPC_ERROR_CONNECTION_FAILED   (-1)
#define HTTPC_ERROR_SEND_HEADER_FAILED  (-2)
#define HTTPC_ERROR_SEND_PAYLOAD_FAILED (-3)
#define HTTPC_ERROR_NOT_CONNECTED       (-4)
#define HTTPC_ERROR_CONNECTION_LOST     (-5)
#define HTTPC_ERROR_NO_STREAM           (-6)
#define HTTPC_ERROR_NO_HTTP_SERVER      (-7)
#define HTTPC_ERROR_TOO_LESS_RAM        (-8)
#define HTTPC_ERROR_ENCODING            (-9)
#define HTTPC_ERROR_STREAM_WRITE        (-10)
#define HTTPC_ERROR_READ_TIMEOUT        (-11)

-1 usually indicate bad URL or bad wifi connection

-1 means that connect failed. in this case because of the wrong port used because of the missing protocol part


text:
Bluetooth Modules not communicating correctly
I plug in BT rx to digital 11, BT tx to digital 10 and then 5v and ground from the HC-05 to the arduino. I then upload this code to the HC-05 that is set as a master.
#include <SoftwareSerial.h>

SoftwareSerial mySerial(10, 11); // RX, TX

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

void loop() { // run over and over
  Serial.println(mySerial.read());
  delay(2000);
}

I then upload this code to the arduino with the HC-05 that is set as a slave:
#include <SoftwareSerial.h>
SoftwareSerial mySerial(10,11); // RX , TX

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

void loop() {
  // put your main code here, to run repeatedly:
  mySerial.write("100");
  delay(2000);
}

The issue is that I never receive "100" on the serial monitor, I only ever receive 49 and occasionally 48. When I changed it from "100" to "10" same thing happened. Any help would be appreciated.

UPDATE: I changed "100" to "hello" and now I'm getting values like 104, 101, 111, 108. I read something that the bytes may be getting mixed up because of how long or short a delay is.

49 is the decimal ASCII value of string 1 .... 48 is the decimal ASCII value of string 0 .... 104=h, 101=e, 108=l`  etc. etc.  ........... http://www.asciichart.com/ascii_decimal.html

Guessing I can't send strings over bluetooth then

you already are, the data being transmitted is always a binary value which has a decimal equivalent and an ASCII equivalent ..... just convert the ASCII values to string .... lot of places on web show you how

SoftwareSerial.read() returns a single character as an integer. When you print an integer the print() functions convert it to a human readable format.
You want to covert (cast) the output of read() to the char type. Either:
void loop() {
  char c;
  c = mySerial.read(); // store the result in a temporary variable c
  Serial.println(c);
  delay(2000);
}

or
void loop() {
  Serial.println((char)mySerial.read()); // cast the type to char befor printing.
  delay(2000);
}

However since only one character at a time is being read your output will be one character per line (assuming no data loss due to the delay):
1
0
0

"You are getting 49 and 48 occasionally"?
I would expect you to get 49, 48, 48, 49, 48, 48 ...
49 is '1' in ASCII and guess what 48 means :)
This is because you are writing and reading bytes not characters.  There is a very subtle difference.
change you receiver to this and it should make more sense.
void loop() { // run over and over
  const char letter = (char)mySerial.read(); // Turn the byte into an ASCII letter.
  Serial.println(letter);
  delay(2000);
}

It may all still go wrong, if you read <32 or >126 but ...
Here is an ASCII table to help:
ASCII Table

You should change the TX and the RX pins on the arduino board and pin it on to another pin other than the TXD and RXD as the are hardware pins....

The OP says they are using 10 and 11.


text:
Arduino Mega RS485
I am following the instructions from this page to set up RS485 communication between two Arduinos.
https://arduino-info.wikispaces.com/SoftwareSerialRS485Example
My wiring varies slightly from the demo in that;
DI (data in)is Pin 18 (11 in the example)
RO (receive out) is pin 19 (10 in the example)
DE (data enable) and RE (receive enable) jumpered together and to pin 5
When I use the script, I can see the built in LED go dark when sending, but I don't get the echo back, nor do I see the LED on the remote blink for the receive.
Is there a fundamental problem with the pins I am using on the MEGA, or am I having difficulty with the script?
Thanks!

it is not possible to comment on your script for obvious reasons

Have you connected ground correctly?

I don't know what is wrong with your setup, but I suggest you start by
testing with a simpler program.
Below is a program that simply copies bytes from the USB link (the bytes
coming from the Arduino's serial monitor) to the RS-485 bus, or the
other way around depending on a #define. Both Arduinos should be
connected as follows:
Arduino     transceiver
--------------------------------
GND         GND
5V          VCC
TX1 (18)    DI (driver input)
RX1 (19)    RO (receiver output)

Additionally, connect:

on the sending side:

the USB plug to your computer
the transceiver's DE (driver output enable) and RE (receiver output
enable) to the Arduino 5V

on the receiving side:

the transceiver's DE and RE to the Arduino GND

Make sure both Arduinos are powered and share a common ground.
Optionally, you can connect the receiving Arduino to your computer, if
you can manage to tell the USB links apart.
Then load the program below to both of them. Make sure you comment-out
the line #define SENDER before programming the receiver.
// The "sender" copies bytes from the USB link (Serial) to the RS-485
// bus (Serial1). The receiver copies them the other way around.
// Comment-out this line for the receiver.
#define SENDER

#ifdef SENDER
HardwareSerial &inputStream  = Serial;
HardwareSerial &outputStream = Serial1;
#else
HardwareSerial &inputStream  = Serial1;
HardwareSerial &outputStream = Serial;
#endif

void setup()
{
    inputStream.begin(9600);
    outputStream.begin(9600);
    pinMode(LED_BUILTIN, OUTPUT);  // used to show activity
}

void loop()
{
    // Copy input stream to output stream.
    if (inputStream.available()) {
        digitalWrite(LED_BUILTIN, HIGH);
        outputStream.write(inputStream.read());
        outputStream.flush();
        digitalWrite(LED_BUILTIN, LOW);
    }
}

Now you can test sending strings through the serial monitor and
seeing whether both LEDs blink. If you connect both Arduinos to your
computer, you could use a terminal emulator (screen, putty, minicom...
depending on your OS) to get the characters back from the receiving
Arduino.
If all that fails, get a scope and look at all the signals along the
path.

Thanks! I can't tell you how much of a huge help that was! The part I had missed was setting up the transceiver's DE (driver output enable) and RE (receiver output enable) to the Arduino 5V
and on the receiving side:
the transceiver's DE and RE to the Arduino GND. Works a treat now!


text:
DLHR differential pressure sensor SPI
I am new to using SPI with an Arduino. But I'm trying to wrap my head around the "coding protocols"/syntax of the Arduino IDE code. I understand the basics of how SPI works conceptually, just not how to actually use it with an Arduino Mega 2560. Most examples on YouTube are about how to play with LEDs and the examples on the Arduino blogs are very specific for two specific examples.
Analog reading is incredibly easy (which is what I am used to doing).
I have an AllSensors DLHR-L05D 18 bit differential pressure sensor (SPI, not I2C) [Datasheet: https://www.allsensors.com/cad/DS-0350_Rev_B.PDF]. Page 5 has the commands needed. From my understanding, I need to somehow send from the Arduino to the sensor a "start" sequence (0xAA) and a "read" (0xF0 and 0x00) sequence, but I'm not sure what that looks like when coding it.
Any and all advice/direction on how to "code up" this SPI device would be greatly appreciated!

I’d suggest finding one of the Adafruit sensors that uses SPI, and read source code of the library they provide for that sensor.

By any chance, are you planning to use this to measure static pressure between the return and supply of a HVAC system? If you are, I'm curious... do you just connect a few feet of plastic tubing (like you'd use for an aquarium air hose) to each barb, drill a small hole in the two ducts, shove a tube into each, and seal up around the tubes? Or do you need something specific on the duct side of the tube, like a metal tube of some kind? I know that for measuring atmospheric pressure, almost anything will do... but suspect distinguishing between 0.5" WC and 0.6" WC is a bit more demanding...

I'm using this sensor to measure atmospheric pressure differences in a moving object (i.e., using it for a pseudo-pitot-static system), so I am using plastic pitot tubes typically used in remote control aircraft. The data sheet says that this sensor is typically used in HVACs, but I haven't tried it in my HVAC per se.

Turns out, someone actually has a specific library to handle the I2C for this sensor, which helps tremendously: https://github.com/jeremycole/AllSensors_DLHR


text:
ISP with 115200 baud
I have a serial ISP programmer of protocol type "stk500v1" which expects 115200 baud data rate. I have used it successfully with Atmel Studio by calling avrdude manually (custom tool) in the past. This just involves the avrdude option

-b 115200

But recently I wanted to do use the Arduino software instead of Atmel Studio for a quick mockup. But everytime I try to "Upload with Programmer", the avrdude commandline includes the option

-b 19200

and so the programming fails.
I can make it work by changing the hard wired serial rate in the programmer from 115200 to 19200, but then of course the programming is dead slow, which I don't want.
I have also looked for a baudrate entry for stk500v1 in "avrdude.conf", but didn't find any. How can I change the baud rate for "Upload with programmer" in the Arduino software?

You have to edit the programmers.txt file. (The one in ~/.arduino15/packages/arduino/hardware/avr/1.6.21/, not the one in arduino-1.8.x/hardware/arduino/avr/)
avrisp.name=AVR ISP
avrisp.communication=serial
avrisp.protocol=stk500v1
avrisp.program.protocol=stk500v1
avrisp.program.speed=115200
avrisp.program.tool=avrdude
avrisp.program.extra_params=-P{serial.port} -b{program.speed}

Add a avrisp.program.speed option, and pass this option as one of the extra_params to the command line call of avrdude.
It is then used on line 112 of platform.txt:
tools.avrdude.program.pattern="{cmd.path}" "-C{config.path}" {program.verbose} {program.verify} -p{build.mcu} -c{protocol} {program.extra_params} "-Uflash:w:{build.path}/{build.project_name}.hex:i"

You could of course also make a copy of that avrisp entry, and add your own programmer, just give it a different name.

"programmers.txt" was the key! However I really had to change the one in "/hardware/arduino/avr/". Probably it's because I am  using Windows 10, or probably because I am still on Arduino 1.6.7. Anyway, it works now. Thank you so much!

They changed the way the board manager works in 1.8.x, in the new versions, other boards (cores) you install are in the ~/.arduino15/packages folder, including the standard AVR core. However, the old (1.6.x) hardware folder that you're using right now was not deleted, that's why I specifically added it. It's not a problem in 1.6.x, only newer versions.


text:
samd21 linking, change the base addresse from the default
I'm working on creating a safe firmware upgrade for my adafruit feather m0.
I understand from my CTO that wrote the previous upgrade that for either samd21 or all arm m0 (not sure which) the compiler compiles non relative addresses, meaning bx 0x3000 will jump to address 0x3000 and not 0x3000 bytes from my location.
My goal is to split the flash into 4 banks:

bootloader (2k)
user data
firmware #1
firmware #2
which firmware will be booted is up to a flag in the flash do decide.
i understand from my predecessor this is an issue since firmware#2 when loaded to ram might not run.
I disagree and do believe simple changes in the .ld script should accomplish the task.

My only question to  you guys is changing the .ld script .text address is enough ? i know the bootloader jumps to an address that was defined in the  .ld script if it's not 0xFFFFFF (if the flash was written to).
do i ned to change the .ld script to include two .text sections ? do i need to also define how they reside in the RAM as well ?
any examples ? hint ?
Thanks.

Have you looked at the Samd21 datasheet?

The data sheet explained in detail how the samd21 memory is laid out including the boot loader section. I have no idea what you mean about .id script what ide are you using? Also search google for samd21 application note AT07175. A good tutorial on how to program the bootloader

the basic ld script shows me the basic memory layout and defines the variables that later on the bootloader uses, i don't need the datasheet for that. ld script and not id script is a GNU script for the ld  (linker) that defines the layout in the binary and later on in the flash and memory layout.

A typical LD script consists of two sections - one that defines memory ("MEMORY") regions, and another that defines what to put in those memory regions ("SECTIONS").
To carve holes in an existing memory layout it is usually enough to just change the first section - the part that defines the layout of the memoy. Shrink and move existing blocks of memory and insert new ones.
For example you may have this at the moment:
MEMORY
{
  FLASH (rx) : ORIGIN = 0x00000000+0x2000, LENGTH = 0x00040000-0x2000 /* First 8KB used by bootloader */
  RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00008000
}

There is a hole already defined of size 0x2000 at the start of flash, and the sketch is loaded from 0x2000 onwards.
You may want to shrink and move that, and add a "user data" chunk. It's enough to just go:
MEMORY
{
  USERDATA (rx) : ORIGIN = 0x2000, LENGTH = 0x1000
  FLASH (rx) : ORIGIN = 0x3000, LENGTH = 0x00040000-0x3000
  RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00008000
}

(I collapsed some of the maths cus it's pointless).  Now the flash area (where the sketch goes) has been shrunk by 0x1000 and moved an extra 0x1000 up the memory map. A USERDATA chunk has been inserted which you can then use later on if you so wish.
To make things get put in there by the linker script (you don't need to change anything else to move the sketch data...) you can define a new section in the later part of the linker script:
.userdata :
{
    KEEP(*(.userdata))
    KEEP(*(.userdata.*))
} > USERDATA

That should then place anything that you put in a .userdata section (or a subsection within that) within your sketch into the USERDATA chunk of flash - separate from your sketch.
(sketch)
const uint8_t __attribute__((section(".userdata"), used)) data[] = { 10, 100, 123, 177, 221, 49 };

However, if you plan to use it like EEPROM and only write to it using code in your sketch then you don't need to worry about anything like that - just carve out the hole.  You can also provide some globals to help with your code, though:
(linker script)
PROVIDE(userdata_start = ORIGIN(USERDATA))
PROVIDE(userdata_length = LENGTH(USERDATA))

Then you can use those in your program to know where the USERDATA chunk is and how big it is (ideal if you ever choose to change it - no need to change your code, only the linker script).

tn the basic ld script at least the one i have the bootloader is not "holed" from the script it's part of it, it cannot be written to due to the use of fure 4 register i think that protects the first X bytes i think 16K in arduino's default.
In any case  the ld script also defines a .text region that is later on referred to from the bootloader and uses volatile __asm("bx ...") to jump  to that address if the parallel flash address meant for the sketch has code and is not 0xffff (which means it was erased).
how does the script "links" between the .text on the flash and the ram area ?

what i need is to compile my sketch once when it's base ram area is defined as X and flash X' and once when it's base is Y on the flash and Y' in the RAM. again as i understand all memory addresses are not relative.

Good point. The existing bootloader doesn't have a clue. The bootloader and the linker script both have to agree on what they are doing. If you change the linker script to start executing from a different area then you must also change the bootloader to jump to that area. There is no way for the bootloader to know anything unless you tell it.

that goes without saying :) i need to mark the beginning, just like it's marked today and get the bootloader to have both addresses or update the address somehow during the firmware upgrade. i'll think of that later on, the real question i guess is lets say i move the .Text segment 0x4000 bytes up the flash memory do i need to relocate it in the script in RAM as well ?  your answer says nothing much about the RAM just FLASH so i'm not sure.

What is there to "relocate" in RAM? RAM is separate to flash. Moving stuff in flash has no connection to RAM at all. If you want to slice up RAM you can. But that has no relevance to moving stuff in Flash.

Some bootloaders use a dedicated "jump" location that is separate from your sketch. The linker script then "loads" that area with a jump instruction that sends it to the real start of the code. That way the linker script dictates where the program goes in flash - as long as that dedicated jump area is always the same.

But... would it just not be simpler to keep the sketch where it is and place your user data at the end of flash?

no, because user data area is needed but not the worst of my problems, i want two firmwares on one flash, for that i need  to either be able to boot from a different address then the default and to be able to compile a matching program for this region OR download a firmware to bank1 and have the bootloader itself copy it to bank 0, but if the write fails, i'm done, chip is toast, it's aproblem.

Then you need to split the flash 50/50 with a little left over for configuration. Two separate linker scripts, one for bank A and one for bank B. Upload bank A, verify bank A is correct, change boot flag to boot from bank A. Then upload bank B, verify bank B is correct, and flip the boot flag for bank B. The bootloader can do that flipping of banks for you once the upload is verified I guess. Custom bootloader required, of course. And some off-line method of remembering what bank is currently in use so you compile the right version.


text:
Timer2 Compare Interrupt not working as expected
To get this out of the way first: I have already looked at "Timer2 does not work as it should" and "Timer2 “Clear OC2B on Compare Match” not working as expected in CTC mode" but have not found the answers there very useful.
Now on to my problem:
I'm trying to use the Timer2 in CTC mode to have an interrupt every 500us. For this, I have the following code:
#include "TimerTwo.h"

TimerTwo Timer2;

ISR(TIMER2_COMPA_vect) { //ISR on Compare Match A
  Timer2.isrCallback();
}

void TimerTwo::initialize() {
  cli();
  TCCR2A = 0;// set entire TCCR2A register to 0
  TCCR2B = 0;// same for TCCR2B
  TCNT2  = 0;//initialize counter value to 0

  // set compare match register for 2khz increments
  OCR2A = 124;// = (16*10^6) / (2000*64) - 1 (must be <256)

  // turn on CTC mode
  TCCR2A |= _BV(WGM21);

  // Set CS22 bit for 64 prescaler
  TCCR2B |=  _BV(CS22);

  // enable timer compare interrupt
  TIMSK2 |= _BV(OCIE2A);
  sei();
}

void TimerTwo::attachInterrupt(void (*isr)()) {
  TIMSK2 |= _BV(OCIE2A);
  isrCallback = isr;
}

void TimerTwo::detachInterrupt() {
  TIMSK2 &= ~_BV(OCIE2A);
  isrCallback = nullptr;
}

and
#ifndef TIMERTWO_H
#define TIMERTWO_H

#include <Arduino.h>

class TimerTwo
{
  public: //methods
    void initialize();
    void attachInterrupt(void (*isr)());
    void detachInterrupt();
    void (*isrCallback)();
};

extern TimerTwo Timer2;

#endif

It was inspired by the TimerOne library.
However, when I measure the period at the output pin (which I have attached inside some other code) I only get a period of 1ms. Even if I set ORC2A to 63, this fact doesn't change.
I have the constructor of this called inside my setup() so the registers should not be overwritten by the wiring.c.
I have also looked at the datasheet of the ATmega328p and checked that all registers are set correctly.
Thanks in advance for your help. If you need any further information, let me know.

What's in the isrCallback after the initialize? You should enable timer compare A interrupt in the attachInterrupt method only. And in the attachInterrupt it should be set first, than enabled.

A timer can only run as fast as the ISR that it triggers. If your ISR takes 1ms to run you will get no faster than 1ms - no matter what you set the period to (below 1ms).

It does not take 1ms, as I've already run it at faster speeds already just not with that timer.

@KIIV even after only activating it in the attachIntterupt it still does not work.

Try doubling OCR2A and see in you get a 2ms interval, or not. What Arduino board are you using? E.g. the Pro Mini 3.3V runs at 8Mhz, so half the speed of the 16Mhz your code is assuming.

To go back to my comment about my ISR: Apparently it DOES take about 1ms but that didn't have to do anything with the problem. I don't know how or why the logic analyzer I have showed my once that it could have a period of 30us but since I wasn't able to reproduce this result it was probably a bug or glitch.
The problem described here did not have to with that though since a simple blinky suffered the same problems.

So you're right that CTC is acting weird. I've noticed this few years ago too on different board, but I've always suspected asychronous mode (I've added 32k RTC Xtal on Arduino Mega).
However Fast PWM mode with OCR2A as a TOP value seems to be working:
class TimerTwo
{
  public: //methods
    void initialize();
    void attachInterrupt(void (*isr)());
    void detachInterrupt();
    void (*isrCallback)() = nullptr;
};

TimerTwo Timer2;

ISR(TIMER2_COMPA_vect) { //ISR on Compare Match A
  Timer2.isrCallback();
}

void TimerTwo::initialize() {
  cli();

  OCR2A = 124;                        // = (16*10^6) / (2000*64) - 1 (must be <256)
  TCCR2A = _BV(WGM21) | _BV(WGM20);   // turn on fast PWM mode with top in OCR2A
  TCCR2B = _BV(WGM22) | _BV(CS22);    // Set CS22 bit for 64 prescaler
  TCNT2  = 0;                         // initialize counter value to 0

  sei();
}

void TimerTwo::attachInterrupt(void (*isr)()) {
  isrCallback = isr;
  TIMSK2 |= _BV(OCIE2A);
}

void TimerTwo::detachInterrupt() {
  TIMSK2 &= ~_BV(OCIE2A);
  isrCallback = nullptr;
}

volatile uint32_t counter = 0;
void isrHandler() {
  ++counter;
}

void setup() {
  Serial.begin(115200);
  Timer2.initialize();
  Timer2.attachInterrupt(&isrHandler);
}

void loop() {
    static uint32_t counter_old = 0;
    Serial.println(counter - counter_old);
    counter_old = counter;
    delay(500);
}

EDIT: Ok, so after some digging on this issue I've found that setting CTC mode might cause OCR2A corruption (I guess?) . It seems to be working if you reorder the settings to:
  TCCR2B = 0;          // stop the timer and reset WGM22
  TCCR2A = _BV(WGM21); // turn on CTC mode with top in OCR2A
  OCR2A  = 124;        // = (16*10^6) / (2000*64) - 1 (must be <256)
  TCNT2  = 0;          //initialize counter value to 0
  TCCR2B = _BV(CS22);  // Set CS22 bit for 64 prescaler (for starting the timer)

Thanks, that really helped.
Another thing I found out, however, is that the code in my ISR takes longer than 1ms apparently. So I'll have to find a solution for that now quickly.


text:
Multiple #ifndef vs. single one #endif
My question is connected with the issue as linked:
Is there any good working MODBUS TCP master library available for Arduino?
An example of Modbus TCP master library as suggested in the post above. A part of ModbusTCP.h file:
#ifndef Modbus_TCPIP_h
#define Modbus_TCPIP_h

#ifndef WIZNET_W5100
#define WIZNET_W5100  0       /**< define 1 if  WIZNET W5100 IC is used, otherwise 0 */
#ifndef ENC28J60
#define ENC28J60      1       /**< define 1 if  ENC28J60 IC is used, otherwise 0     */
#ifndef ESP8266
#define ESP8266       0

//...The entire code of the header

#endif // Just a single one occurence of the #endif in the last line of the header code! 8-|

When I've run the compilation of it in my Arduino IDE, I've got an error as follows: unterminated #ifndef. Mentioned error has a four ocurrences in the error log and it is linked to: Modbus_TCPIP_h, WIZNET_W5100 and ENC28J60.
What should be modified in the header file?

These of course each need to be matched by an ending, as they are fully independent.  Are you confusing this with else clauses?

It's a bug in the library. Someone submitted a PR: https://github.com/goddland16/Modbus-TCP/pull/2 and the library owner merged it. Apparently neither of them bothered to test the code or even give it a quick look. That doesn't give me much confidence in the quality of their work. My advice is to look for an alternative library of higher quality.

you might have figured it out yourself if you asked why is ESP8266 not getting an error

Dear All. As per per1234 suggestion I would place the main question ones again: Is there any good working and also tested and proven MODBUS TCP master library available for Arduino?

The code is missing "#endif". Should look something like this:
#ifndef WIZNET_W5100
#define WIZNET_W5100  0       /**< define 1 if  WIZNET W5100 IC is used, otherwise 0 */
#endif
#ifndef ENC28J60
#define ENC28J60      1       /**< define 1 if  ENC28J60 IC is used, otherwise 0     */
#endif
#ifndef ESP8266
#define ESP8266       0
#endif

Cheers!

A new error available:modbusTCPlib_enc28j60:23: error: token "=" is not valid in preprocessor expressions
#define ENC28J60     = 1

Did you accept the answer above? And now adding a new question. Fun!

I'm trying fix the bugs in the code. In the moment nothing works. All trails brings nothing. So I would ask ones again. Is there any good working and also tested and proven and error free MODBUS TCP master library available for Arduino? Thank you in advance.

Have you read how to use this site? https://arduino.stackexchange.com/tour I recommend that you follow this procedure. It will give you more answers and friends.


text:
Low-Power library question
i'm study the Low-Power library to better undertand how it works.
In this part of code i have some question.
Sometime he uses commands like:
power_timer1_disable();
power_timer0_disable();

but in other part of code, example "TIMER2_OFF":
if (TCCR2B & CS22) clockSource |= (1 << CS22);
if (TCCR2B & CS21) clockSource |= (1 << CS21);
if (TCCR2B & CS20) clockSource |= (1 << CS20);

// Remove the clock source to shutdown Timer2
TCCR2B &= ~(1 << CS22);
TCCR2B &= ~(1 << CS21);
TCCR2B &= ~(1 << CS20);

power_timer2_disable();

he uses the register code and, in the end, the function.
Someone can explain to me why?

It's doing basically this:
clockSource = TCCR2B & (_BV(CS22) | _BV(CS21) | _BV(CS20)); // store prescaler
TCCR2B &= ~(_BV(CS22) | _BV(CS21) | _BV(CS20));             // select "no source" - disable clock source
power_timer2_disable(); // disable whole timer2 in Power Reduction Register

Definition of power_timer2_disable macro is:
#define power_timer2_disable()  (PRR |= (uint8_t)(1 << PRTIM2))

In short, you have to turn off the clock source before the power gets cut off by PRR register (to avoid unexpected behaviour).

Power Reduction Register
The Power Reduction Register (PRR), provides a method to stop the
clock to individual peripherals to reduce power consumption. The
current state of the peripheral is frozen and the I/O registers can
not be read or written. Resources used by the peripheral when stopping
the clock will remain occupied, hence the peripheral should in most
cases be disabled before stopping the clock. Waking up a module, which
is done by clearing the bit in PRR, puts the module in the same state
as before shutdown. Module shutdown can be used in Idle mode and
Active mode to significantly reduce the overall power consumption. In
all other sleep modes, the clock is already stopped.

Thx KIIV!
Is it in the datasheet those advice before use the, for example, power_timer2_disable?

@MarkCalaway It's definitely mentioned for the ADC module. I didn't checked it for the Timers.


text:
array to serial
i want to send an array of int to another arduino by serial.
To garantie a better robust during the transmission, i added < and > with endMarker and startMarker.
The receiver wait until the Hardware Serial is open, and read the data from the Software Serial from the sender.
Code for the sender:
int test[] = {1, 2, 3, 4, 5, 6, 7};

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

void loop() {
  for (byte i = 0; i < 7; i++) {
    Serial.write("<");
    Serial.write(test[i]);
    Serial.write(">");
    delay(500);
  }
}

Code for the reader, i edited the code from here: http://forum.arduino.cc/index.php?topic=396450
// Example 3 - Receive with start- and end-markers

include <SoftwareSerial.h>

const byte numChars = 32;
char receivedChars[numChars];

boolean newData = false;

SoftwareSerial mySerial(10, 11); // RX, TX Software Serial

void setup() {
    Serial.begin(9600);
    mySerial.begin(9600);
    Serial.println("<Arduino is ready>");
}

void loop() {
    recvWithStartEndMarkers();
    showNewData();
}

void recvWithStartEndMarkers() {
    static boolean recvInProgress = false;
    static byte ndx = 0;
    char startMarker = '<';
    char endMarker = '>';
    char rc;

    while (Serial.available() > 0 && newData == false) {
        rc = mySerial.read();

        if (recvInProgress == true) {
            if (rc != endMarker) {
                receivedChars[ndx] = rc;
                ndx++;
                if (ndx >= numChars) {
                    ndx = numChars - 1;
                }
            }
            else {
                receivedChars[ndx] = '\0'; // terminate the string
                recvInProgress = false;
                ndx = 0;
                newData = true;
            }
        }

        else if (rc == startMarker) {
            recvInProgress = true;
        }
    }
}

void showNewData() {
    if (newData == true) {
        Serial.print("This just in ... ");
        Serial.println(receivedChars);
        newData = false;
    }
}

I don't know if the problem is the serial.write, that send bytes, or i need to use serial.print to send string.

You are attempting to use an 8-bit binary protocol to transmit 16 bit values, and then wrapping it in ASCII characters.  There is:

No way to differentiate the ASCII characters from the 8 bit binary data, and
No way to fit 16 bits into an 8 bit protocol.

The simplest way is to use Serial.print to make the whole protocol ASCII:
Serial.print("<");
for (byte i = 0; i < 7; i++) {
  Serial.print(test[i]);
  if (i < 6) {
    Serial.print(",");
  }
}
Serial.println(">");

Which would send out:
<1,2,3,4,5,6,7>

Thx Majenko, can i use the example 5 ( http://forum.arduino.cc/index.php?topic=396450)  to read that output with other arduino?

You can use a variation of it, sure.


text:
Best approaches to reading a high-count quadrature encoder?
I have a 24v servo motor coupled to a 2,000 segment optical encoder that runs on 5v.
That's 2,000 "ticks" per revolution at it's base resolution. (Full quad reading allows 8,000 ticks per revolution, which I have no idea how a person could really USE! Egads that's tiny slices of a circle.)
It ALSO has a 'full-circle' index, a "Z" line.
That Z SEEMS to be coincident with A. Meaning that the clear slot in the rotor seems to be in the same place for both ONE of the A ticks and the only Z tick. I do not have an oscilliscope to verify this, but timestamping two different interrupts makes it seem like they do line up (one on A one on Z).
The motor runs at max 1075 RPM. So if I did the maths correctly that means there are 2,150,000 ticks per minute on the A/B lines plus 1075 ticks per minute on the Z line.
35,833.33-ish ticks per second on the A line.
17.9166-ish ticks per second on the Z line.

I have used sample code from a number of sources on both a Nano v3 and an Uno r3. I can't get counting to be accurate on either device, both lose ticks counting the A trigger and the coincidence of the A and Z ticks makes the interrupts 'stack' (both trigger almost instantaneously, but whichever was first gets processed and THEN the other gets processed...)
I do know that I can get IC's that will count for me, but there are MANY models and I do not have the ability to determine which would suit this situation the best.
Despite reading a great number of posts about encoders and the Arduino code to read them I still don't understand if the Nano or Uno COULD do this on their own at this speed.
GOAL:

Accurately track all 2000 pulses per revolution at 1075 RPM.
Accurately track FULL rotation pulses at 1075 RPM.
Use full rotations as error-checking against the 2000 count.
Provide error-checked count as an absolute count to external device.
Provide resettable zero-point to external device (remotely reset the count).

So please, if you would, inform me about or direct me to proven methods and resources for achieving the above goals?

Do you have to track rotation in both directions?

Yes. Intended use is in small CNC machine.

For this you would typically pick a microcontroller that has a quadrature encoder interface in it. You could count the pulses with a timer, but you wouldn't get direction information with that.


text:
Setting pinMode(pin,input/output) as per user requirement
I am working on arduino IDE and esp8266 nodemcu.
As i am going through the IDE I saw that there is a structure of void loop() and void setup() and all examples in the internet included defining the pinModes within the void setup() block.
I want to make a program where through mqtt or http the user will give input as to what type of device he/she wants to attach to the esp8266, so based on that i will have to set, INPUT/OUTPUT state on the following pins.
Now my initial idea was :
void setup()
{
    connectwifi();
}

void loop()
{
   call_some_function();
}

where call_some_function() will recieve the requirements from user over http. For example he wants a light on pin3, so pinMode(pin3,OUTPUT);
now what I wanted is that,
call the method - call_some_function() whenever the user needs to add an extra device to it, which means initally when we wanted to add 4 lights to esp8266, we will write
pinMode(pin1,OUTPUT);
pinMode(pin2,OUTPUT);
pinMode(pin3,OUTPUT);
pinMode(pin4,OUTPUT);

But now when I have a user defined input, my code will become something like this,
call_some_function()
{
     pin=(user gave me the pin no);
     state=(based on the device the server will send the state i.e IN/OUT);
     pinMode(pin,state);
}

Now my question is , calling this function 4 times and writing pinMode() function 4 times will result in same thing or separate?
Also is this doable, like can i write like this?
I will be calling this function from void loop() instead if void setup(), since I continuously listen for user input,
Cause I cannot find any other way of making user specific input

you can call pinMode anytime

Can u make ur comment as "answer ur question", cuz if furthur discussion turns out to be an answer then i can mark it as an Answer.

Now my question is , calling this function 4 times and writing pinMode() function 4 times will result in same thing or separate? Also is this doable, like can i write like this?

you can call pinMode anytime
And to add something more to pinMode. It is not just some preparation of the pin. It changes things for the connected circuit. Setting to INPUT lets the attached circuit rule. If there is a pull-up circuit the state will be HIGH, if pull-down LOW. INPUT_PULLUP holds the state HIGH but lets the attached circuit to pull it down. pinMode OUTPUT sets the pin LOW.
In two cases for now I use setting a pin to OUTPUT only for the time I want to control the attached circuit and the I set it back to INPUT. In first case I reset an esp8266 with EN pin connected by setting the pin LOW, then I let the external pull-up hold the EN pin HIGH. Second case is amplifier module for the tone() function. I set the pin to INPUT after tone() otherwise it catches noise.

pinMode() is usually called from setup() because in most cases, the pin mode remains the same throughout the run. Sometimes there is a reason to change it during the run, such as in your example, and you can call pinMode() at whenever is the appropriate time to do that.

Ok, ty.. Juaraj gave the correct answer first so I will mark his answer.