text:
What's is the best way to convert std::string to String?
Pardon me, I am a novice programmer. I was trying to use the toInt() function for a std::string but I noticed that toInt() only works for the String class. So, I have an std::string sliderValue and wanted to convert it to the String class so I could use the toInt() function. Here, I found a way that seemed to pacify Intellisense, vMicro, and building. I did:
String convertValue = strcpy(new char[sliderValue.length() + 1], sliderValue.c_str());

so I could do:
ledcWrite(ledChannel, convertValue.toInt()  * (10.24));

Is there a better way to do this or am I on point? Also, I'd love to get insight in what I'm doing, if possible. Thanks folks!
P.S. I looked up this here at arduino stackexchange, and it didn't seem to provide a solution specific to my question.

If you have std::string, chances are you also have std::stoi

There is absolutely no need to use String (for anything, generally...). Instead you can either (if you have it) use std::stoi() or use strtol() on the c_str of the string.
ledcWrite(ledChannel, std::stoi(sliderValue)  * (10.24));

Or
ledcWrite(ledChannel, strtol(sliderValue.c_str(), NULL, 10)  * (10.24));

The former just converts into the latter anyway.


text:
Driving higher loads with PWM
My Arduino Pro Micro can source 500mA from 3.3V VCC, when it is USB powered.
The chip itself, is rated for 200mA, though, and its output pins for 20mA recommended, 40mA max.
I am looking to have 3 PWM outputs, though, each doing 120mA. The combined 360mA would be in-spec for VCC, but not for the chip.
Is there a buffer IC that I can use that will switch these loads at that current, and can keep up with a few hundred Hz PWM?
From what I've read, you can switch loads with discrete transistors, but these require extra components like resistors? Are there CMOS chips that will take the PWM signal and output it at 120mA?
I am looking to source the current, not sink it.
The load in my application are LEDs driven with constant-current drivers that are daisy chained. I just want to PWM the Vled supply so I can dim per channel, of the entire daisy chain.
UPDATE: I went with @Majenko's solution of pre-biased DTB114EK. Although it somewhat works, it seems to struggle to deliver 30mA out, even though it is rated at 500mA?
UPDATE: The DTB113ZC works better. Due to a lower bias resistor, I can get more current through it.

@gbg that datasheet seems to indicate it needs 4.5V to operate? My Arduino runs with 3.3V as VCC. Also, 2A per channel is far more than I need?

Wait, what kind of load do you have? RGB LED, I presume?

@gbg It is complicated. I drive LEDs with a TLC5928 but I want to dim them per channel, by modulating Vled. I now there is the TLC5940 option, but I want to stick with the 5928. So the load is a led, hooked up to a constant current driver. I'll add a link to my application.

You can get pre-biased transistors that don't need resistors, such as the DTB114ECHZG.

@Majenko Thanks! That looks interesting. So I would hook my PWM output to the base, my VCC to emitter and the load to the collector? Also it mentions 'invertor.' Does that mean that I need to reverse my duty cycle?

That's correct. You pull the base LOW to turn the output ON. You could add an NPN (or n-FET) to invert it for you if you wanted but that's more components...

How about the ULN2003?

@gbg They sink current, not source it.

I used this module https://wiki.seeedstudio.com/Grove-MOSFET/

Use a transistor. Here is an example schematic and calculations I did for an NPN BJT transistor. You can learn how to do the math and process yourself following my answer.

Here is a part that will do the job for you, just 4 wires to connect.  Use your favorite search engine or go to your favorite china supplier and use this term: "Low Control High Voltage 12V 24V 36V switch Mosfet Module For Arduino Connect IO MCU PWM Control Motor Speed 3V 5V". You will get many choices several in the dollar range. It is opto isolated so that eliminates the ground connections etc. I have used them several times and they work nicely.

source: Stack Exchange

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

sort: votes


text:
Hardware implementation of trigonometric functions?
Is anybody aware as to whether there are any modern microcontrollers that have hardware implementations of trigonometric functions? According to my understanding, modern CPUs have basic maths functions such as square roots and the trigonometric functions implemented in hardware to increase the speed and/or throughput of these maths functions. Do any widely used microcontrollers you know of have similar hardware implementations?
The reason I am asking this is because I want to know if it is feasible to implement more efficient trigonometric functions for specific use cases. On modern CPUs with the right compiler settings, it is almost always faster to use or derive from the built in trigonometric functions, rather than rolling your own software implementation specific to your problem.

It does belong in the question doesn't it.. hehe. And no, I'm talking about whether software implementations can realistically be faster than the standard implementations provided by standard libraries. Be that specialised versions of the taylor series, or other non-standard approaches to implementing something like sine.

I'm actually beating around the bush to avoid embarrassing myself, I have a class to generate a continuous sine wave of a constant frequency/sampling rate, and it doesn't have a place in modern high performance code due to the aforementioned built in trigonometric functions present on modern CPUs. However I would like to know if it has a use in lower processing power devices such as microcontrollers and microprocessors. Should I delete this question and actually provide the code for criticism?

"are you not aware of the purpose of this site?" mate all I was asking was if microcontrollers had something like a single machine instruction to compute trigonometric functions. There doesn't seem to be a general "microcontroller" stack exchange site so I thought this place would be best. Apparently not.

Electronics Stack Exchange is more targeted at microcontrollers in general. For your question to be on-topic here you would need to be asking about an Arduino implementation. As Arduino is, generally speaking, targeted at beginners there would probably be no such thing.

For small / slow MCUs it is more common to use a LUT than to calculate these kind of numbers on the fly.

I do not know the answer to your main question, but I will try to answer
the underlying question:

I want to know if it is feasible to implement more efficient
trigonometric functions for specific use cases.

There are microcontrollers that do not have hardware implementations
of trig functions, and that is the main point. The AVRs powering many
Arduinos are among them: they don't even have hardware floating point.
The libc provides implementations of the trig functions that are both
quite accurate (about 24 bits of accuracy) and very slow (about
100 µs for a cos() on an Uno).
There are also situations where you do not need that level of accuracy.
So yes, custom trig functions that hit the right balance between speed
and accuracy can be helpful on Arduinos. Note that the right balance is
project specific, so there is no one-size-fits-all, and rolling your own
can make sense.
For reference, I once wrote a fixed-point cos() accurate to
9.53 × 10−5 that ran in 6.77 µs on average on
an Uno. I can provide a link if someone is interested. If you can do
better (faster at same accuracy, or more accurate at same speed) I
definitely would love to see that.

I wrote a class that generated a continuous sine wave using the spring equation (F = -kx, where x is the desired resting length of the spring), basically meaning that each sample of the sine wave (assuming a constant sampling rate and frequency) would only require two multiplications and two additions. The tradeoff for this solution is that it is continuous, you cannot call sin(1), then sin(5), then sin(3), you just sample from a sine wave of a set frequency. There are two other tradeoffs, memory for storage of the spring state, and the integration of floating point errors.

The integration of floating point errors does not have a large effect on the shape of the wave, it just means it tends to go in and out of sync with the sin function after multiple samplings. You can recalibrate the function by calling standard sine and cosine function once per recalibration. I don't not why I'm talking about this. I just wanted to talk about it. Because I'm very egotistical.

I wanted to test if this solution actually is faster than repeatedly calling something like sin(x) repeatedly to fill a buffer or something, but I appear to have misplaced the cable I need to actually program my Arduino.

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


text:
Model locomotive circuit review
I am building a model scale locomotive and therefore use Arduino for the DC motor, smoke generator, sound and lights. Can you help me with reviewing the circuit?
Power comes from rechargeable batteries (9.6V). This will supply the buck converter and the motor shield. Rest of circuit runs on 5V. A few MOSFETS regulate power for LEDs and smoke generator. MOSFET is overkill for this scale I know now. The locomotive has two parts: locomotive itself and the tender where the batteries and boards are put in. I just need to connect 5 cables for it to work.
Can you help reviewing if there are any errors / electrical shorts possibilities. Please don't add unnecessary complexity.

a schematic diagram is almost always clearer than a wiring diagram ... a quick glance reveals a couple of unknowns ... are mosfet connections correct? ... can DFplayer handle a 4 ohm speaker?

Shouldn't the red and white LEDs swap when the direction changes? (Three white on the front, 1 red at the back) This is not possible with this design.

I think you also need to connect 5V to the Vcc pin of the motor driver board. 2) I'd connect the LED to 5V. That way their brightness will remain constant, even when the battery voltage drops due to discharge. This will also run them more effeciently; giving you better battery life. 3) I'd add resistor to the base of the mosfets. 4) You may need to run the leds at less than 20mA, as they might be too bright.


text:
NFC hang after RF_ON command
We have developed our board with PN5180 NFC but I cannot make it work properly. After I send RF_ON command I am stuck on STATE_CHANGE_IRQ_STAT while waiting for TX_RFON_IRQ_STAT but the state never changes. In this moment I can see sinus vawes on the oscilloscope. If I ignore it I will be stuck waiting for the RX_STATUS register to reflect the TRANSCEIVE_STATE. If I ignore both, the TX_RFON_IRQ_STAT appears after few SEND_DATA sequences but card cannot be read. Has anyone experience this?
def init(self):

# 1. Loads the ISO 15693 protocol into the RF registers
self._send([LOAD_RF_CONFIG, 0x00, 0x80])

# 2. Switches the RF field ON.
self._send([RF_ON, 0x00])

answer = self.read_irq_status_register()
while ((TX_RFON_IRQ_STAT & answer) == 0):
  answer = self.read_irq_status_register()
  self.show_status(answer)

return 1

The solution is that PN5180 simply cannot work without BUSY pin connected.


text:
ESP32 BLE service not visible to Node-RED
I've been trying to host a BLE-server on my ESP32 with a custom service. I'm trying to read the service data in NodeRED, but the service IDs and custom characteristics don't show up in NodeRED whenever I import the scan results of my BLE input node in NodeRED.
The device and service both show up fine on Android using NRFtool:

However, in NodeRED, the device shows up and connects just fine, but none of the characterestics are displayed at NodeRED's end:

I'm using NodeRED version 1.2.9 with the Generic BLE node. And the ESP32 sample i'm using can be found here.
I've also tried the BLE server examples included with the BLEDevice library with similar issues.
In addition to this: I'm not sure if this is just a typo in the node's error message, or if it's a typo in the node itself, but all mentions of the type "topic" are displayed as "tpoic" in NodeRED's debug log. Though i doubt this affects the functionality of the node in any way. Nowhere in my flow is there a mention of the keyword "tpoic".

Any suggestions as to how i could make my services show up in NodeRED would be appreciated.
Thank you.

Turns out BlueZ on linux no longer supports ESP32 BLE devices. I tried the same code on a bluefruit M0 and it worked just fine.


text:
Serial comm UART1 works on Arduino but makes ESP32 continuously reboot
This comm sketch simply read incoming bytes from the UART 1 where a device is attached.
It works normally on a real Arduino device.
But on ESP32, it makes it continuously reboot with the following messages:
([UPDATE] Note that there is no reboot on ESP32 is I use Serial2 instead of Serial1)
9:13:19.676 -> ets Jun  8 2016 00:22:57
19:13:19.676 ->
19:13:19.676 -> rst:0xc (SW_CPU_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
19:13:19.676 -> configsip: 0, SPIWP:0xee
19:13:19.676 -> clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
19:13:19.676 -> mode:DIO, clock div:1
19:13:19.676 -> load:0x3fff0018,len:4
19:13:19.676 -> load:0x3fff001c,len:1216
19:13:19.714 -> ho 0 tail 12 room 4
19:13:19.714 -> load:0x40078000,len:10944
19:13:19.714 -> load:0x40080400,len:6388
19:13:19.714 -> entry 0x400806b4
19:13:19.786 -> Yo! from serial UART 18/19
19:13:19.786 -> SbmDi⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮@D@⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮
@%cGuru Meditation Error: Core  1 panic'ed (IllegalInstruction). Exception was unhandled.
19:13:19.823 -> Memory dump at 0x400e90f4: ffffffff ffffffff ffffffff
19:13:19.823 -> Core 1 register dump:
19:13:19.823 -> PC      : 0x400e90f8  PS      : 0x00060530  A0      : 0x800d1529  A1      : 0x3ffb1f80
19:13:19.823 -> A2      : 0x3ffbfe88  A3      : 0x3ffbfe6c  A4      : 0x0001c200  A5      : 0x0800001c
19:13:19.823 -> A6      : 0x00004e20  A7      : 0x00000000  A8      : 0x800d0c4f  A9      : 0x3ffb1f60
19:13:19.857 -> A10     : 0x3ffbfe6c  A11     : 0x3f40013b  A12     : 0x0800001c  A13     : 0x00000009
19:13:19.857 -> A14     : 0x00000009  A15     : 0x00000000  SAR     : 0x00000016  EXCCAUSE: 0x00000000
19:13:19.857 -> EXCVADDR: 0x00000000  LBEG    : 0x400014fd  LEND    : 0x4000150d  LCOUNT  : 0xffffffbd
19:13:19.857 ->
19:13:19.857 -> ELF file SHA256: 0000000000000000
19:13:19.857 ->
19:13:19.857 -> Backtrace: 0x400e90f8:0x3ffb1f80 0x400d1526:0x3ffb1fb0 0x400860ed:0x3ffb1fd0
19:13:19.891 ->
19:13:19.891 -> Rebooting...

Here's my code:
#include <Arduino.h>

#define SbmDisplaySerial Serial1

void setup() {
  Serial.begin(115200);
  //Serial.setDebugOutput(true);
  Serial.println("Yo v0.0.1! from serial UART 18/19");

  SbmDisplaySerial.begin(9600, SERIAL_8N1);//, 16, 17);

  Serial.print("SbmDisplaySerial is ");
  Serial.println(SbmDisplaySerial);
}

int _loop = 1;

void loop() {
  // put your main code here, to run repeatedly:
  Serial.print("Loop #"); Serial.println(_loop++);
  delay(1000);

  if (!SbmDisplaySerial.available()) {
    delay(2000);
    Serial.println("No byte avail from the UART, looping…");
    return;
  }

   int b = 0;

   Serial.print("Synching with message limit (waiting for 0xA5 (165) header byte): ");
   int i=0;
   do {
     delay(10);
     b = SbmDisplaySerial.read();
     Serial.print(b);
     Serial.print(" ");
     if (i%128==0) Serial.println();
      i++;
   }
   while(b!=0xa5);

  Serial.println("Ok, packet started!");
  Serial.print("Received bytes: ");
  Serial.print(b);
  Serial.print(" ");

  int soc = 0;
  int voltage = 0;
  int current = 0;
  int capacity = 0;

  for(int i=1; i<16; i++) {
    b = SbmDisplaySerial.read()&0xff;

    Serial.print(b);
    Serial.print(" ");

    switch(i) {
      case  0: Serial.print("Header byte 0xA5");
        voltage = 0;
        current = 0;
        capacity = 0;
      break;
      case  1: soc = b; Serial.print("(SoC: ");  Serial.print(soc); Serial.print("%) "); break;

      case  2: voltage = b<<8; break;
      case  3: voltage |= b;  Serial.print("(");  Serial.print(float(voltage)*0.01); Serial.print("V) "); break;

      case  4: capacity = b<<24; break;
      case  5: capacity = b<<16; break;
      case  6: capacity = b<<8; break;
      case  7: capacity |= b;  Serial.print("(");  Serial.print(float(capacity)*0.001); Serial.print("A.h) "); break;

      case  8: current = b<<24; break;
      case  9: current = b<<16; break;
      case 10: current = b<<8; break;
      case 11: current |= b;  Serial.print("(");  Serial.print(float(current)*0.001); Serial.print("A) "); break;

      //case 12: current = b<<8; break;
      //case 13: current = b<<8; break;
      //case 10: current |= b;  Serial.print("(TOA: ");  Serial.print(float(current)*0.001); Serial.print("Seconds) "); break;
    }

    if (!SbmDisplaySerial.available()){
      delay(2000);
      Serial.print(" No more byte prior reaching 16 bytes, looping…");

      break;
    }
  }

  Serial.println("Waiting for next packet");
  delay(10000);

}

[UPDATE]
When ran on Arduino, I get typical logs as follows:
11:20:18.217 -> Yo v0.0.1! from serial UART 18/19
11:20:18.217 -> SbmDisplaySerial is 1
11:20:18.217 -> Loop #1
11:20:19.204 -> Synching with message limit (waiting for 0xA5 (165) header byte): 0
11:20:19.204 -> 0 0 0 0 165 Ok, packet started!
11:20:19.275 -> Received bytes: 165 28 (SoC: 28%) 4 251 (12.75V) 0 0 54 248 (14.07A.h) 255 255 0 0 (0.00A) 0 0 0 0 Waiting for next packet
11:20:29.263 -> Loop #2
11:20:30.266 -> Synching with message limit (waiting for 0xA5 (165) header byte): 0
11:20:30.266 -> 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 165 Ok, packet started!
11:20:30.508 -> Received bytes: 165 28 (SoC: 28%) 4 251 (12.75V) 0 0 182 0 (46.59A.h) 0 0 0 0 (0.00A) 0 0 0 0 Waiting for next packet

Serial.println(SbmDisplaySerial); how is that supposed to work?

You simply read: "10:46:23.574 -> SbmDisplaySerial is 1" but you can ignoire, it's pure logging message.

The problem is that SbmDisplaySerial (or any Arduino Serial object) is not equal to "1", but an object with all kinds of properties that you can't simply "print". I don't know why the Arduino (AVR) allows this, but the Serial implementation of the ESP32 might not handle this gracefully. Why don't you try leaving this Serial.println() statement out and see if it makes a difference?

FYI, I've tried your code on my own ESP32 and it does not crash. What Arduino IDE and ESP32 Core version are you using?

@StarCat This is used to know the state of the connection (see https://www.arduino.cc/reference/en/language/functions/communication/serial/ifserial/). And anyway, If I remove it it makes no change to the game.

Can you post a schematic, not a frizzy picture.

Here is what I've ended up with: I dropped Serial1 as I did not find anyway to make it run and I switched to Serial2, where everything works as expected.

#define SER1_RX 35
#define SER1_TX 32

void setup()
{
    Serial.begin(115200);                       //
    Serial.setDebugOutput(1);

    // For Serial1, be sure to set the communication port.
    Serial1.begin(115200, SER1_RX, SER1_TX);    // set the communication port
}


text:
Simulink resets arduino
I am working on servo motors control through serial communication protocol, I am sending data from Simulink to arduino and vice versa, The problem I am getting is that once I open Simulink Servo motors start turning while no command is sent or received from both, I tought that Simulink is initializing (reseting) arduino, so I decided to add a capacitor between Gnd & reset (I also tried with a resistor between 5v & reset), It actually works when I try to use Arduino IDE, Arduino is not reseting, but When i use it with Simulink it doesn't make change, Servo motors still turning randomly (I think that when I start or close simulation, Servo Are going to their initial position, I am not sure). I tried to add initial Position in Setup() function but in vain, It doesn't make sens!
I tried using different arduino cards (MEGA, ESP32...Etc.) but in vain.
Does anyone have an idea about how to figure out this problem?
Here is Simulink control code : & Arduino code :

#include <SCServo.h>
SCSCL sc;

//Estructura Union
typedef union {
  float number;
  uint8_t bytes[4];
} valor;
valor velocidad;

unsigned long timeold;
int vel = 0;
float value;
void setup() {

  Serial1.begin(1000000);
  sc.pSerial = &Serial1;
  Serial.begin(9600);
}

void loop() {
  //Pregunta si tenemos un dato a recibir
  if (Serial.available() > 0) {
    value = recepcion();
  }

  //Transforma el valor del voltaje (0-5) a velocidad
  vel = map(value, 0, 5, 0, 1023);
  //Activa el motor dirección Backward con la velocidad
  sc.WritePos(3,  value, 0);

  velocidad.number = sc.ReadPos(3);

  Serial.write('V');
  for (int i = 0; i < 4; i++) {
    Serial.write(velocidad.bytes[i]);
  }
  Serial.write('\n');
  delay(50);
}

//Recibir Flotante
float recepcion() {
  int i;
  valor buf;
  for (i = 0; i < 4; i++)
    buf.bytes[i] = Serial.read();
  return buf.number;
}
//Función para la lectura del encoder

Thank you !

first thing to try is to connect Simulink without sending any data at all

I tried to use Simulink to receive Servo motor angle from arduino, it works great, the servo is not turning randomly, I am getting the servo motor angle in real time. but when I start sending from simulink, the servo motor starts to turn to max & the min angle!

sounds like a software issue

Without knowing what code you're running on your arduino or what you're actually trying to do (or what this "simulink" thing is you're talking about) we will be hard pressed to help you.

Did you check your hardware handshake lines? AFAIK one of them is used to reset the Arduino.

I added The simulink control code @Majenko

@thebusybee actually, I have no idea about how to this, I google it but I found nothing about the handshake lines for arduino!

@jsotola seems to be like that but I can't figure out what is i t

https://majenko.co.uk/blog/our-blog-1/reading-serial-on-the-arduino-27

I don't know but it seems to work now! I just added a delay(100) after the serial.available() loop  & it works, anyone can explain this for me pleasE


text:
Millis() based timer program for 24x7 usage in Arduino
I have made an irrigation system using Arduino. Timer program is based on comparing the previous Millis() and current Millis(). I want to know the chance for error when the currentMillis() overflows and start from zero after 50 days, while the previous Millis() stored in the variable remains as a larger value.

What do you mean with "chance of error"? If you do it like in the BlinkWithoutDelay example the overflow is no problem as long as the time difference between the previous millis() value and the current one stays below the ~50 days, since millis() just cannot count longer.

See How can I handle the millis() rollover?.

arduino timekeeping is not accurate if you do not use an RTC module .... it is ok for timing intervals, such as watering every 12 hours ... but it is unable to water at a specific time

this may be useful ... https://github.com/OpenSprinkler


text:
ESP8266 with HC05 : expecting to receive more bytes then the 63 received
I'm trying to read a Ant BMS 32H with a ESP8266 and a HC05 module.
BMS is sending 146 bytes when asking for these by sending DB DB 0 0 0 0 (HEX)
I did test with my android phone and the app 'Serial Bluetooth Terminal' and I receive/see the 146 bytes.
When doing this with the ESP8266/HC05 I only receive 63 bytes.
I saw already that I shouldn't use delays before reading the serial buffer, as this could cause buffer overflows.
I have no clue on what the reason could be ... hope someone has some more knowledge then I do ...
Please see my code I use ( I didn't post the Process_Data() routine as this one is called afterwards )
Initial I tried without the cosmetic visualization ( extra lines of code taking cpu cycle to execute) and it give the same result
The result I receive :
---------------------------------------------------
Sending request (6 bytes) : DB DB 0 0 0 0  Answer :
00:AA 01:55 02:AA 03:FF 04:02 05:7B 06:08 07:43 08:08 09:43
10:08 11:47 12:08 13:41 14:08 15:3B 16:08 17:45 18:08 19:41
20:08 21:46 22:08 23:43 24:08 25:41 26:08 27:43 28:08 29:46
30:08 31:44 32:08 33:41 34:08 35:49 36:08 37:41 38:08 39:43
40:08 41:42 42:08 43:3F 44:08 45:3F 46:08 47:46 48:08 49:44
50:08 51:4F 52:08 53:38 54:08 55:3E 56:08 57:47 58:08 59:47
60:08 61:45 62:08
Bytes received : 63

My .ino :
#include <SoftwareSerial.h>;
SoftwareSerial EEBlue(12, 13); // RX | TX // AT command mode
// byte message[] = {0x5A, 0x5A, 0x5A, 0x00, 0x00, 0x5A, 0xDB, 0xDB, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0A };
byte message[] = {0xDB, 0xDB, 0x00, 0x00, 0x00, 0x00 };
byte bms[147]; // 82 + 65 = 147 bytes
int i;
int x;
int highbyte, lowbyte;
uint16_t a16bitvar;
unsigned int BattSOCG;
float BattPowerG;

void setup()
{
  Serial.begin(115200);
  delay(500);
  EEBlue.begin(38400);  //38400 Baud for AT commands , set by command : AT+UART=38400,1,0 or AT+UART=9600,1,0
  delay(500);
  Serial.println();
  Serial.println("Serial and Bluetooth started.");
  Serial.println(); Serial.println("");
}

void loop()
{
  AskBMSData();
  GetBMSData();
  Process_Data();
  delay(3000);
}

// ---------------------------------------------------------
void AskBMSData()
{
  Serial.print("Sending request ("); Serial.print(sizeof(message)); Serial.print(" bytes) : ");
  for (i=0; i<sizeof(message); i++)
  {
    Serial.print(message[i], HEX);
    Serial.print(" ");
  }

  EEBlue.write(message, sizeof(message));
}

void GetBMSData()
{
  Serial.println(" Answer :");
  // Feed any received bluetooth data to Terminal.
  i=0;
  while (EEBlue.available()) {
    bms[i]= EEBlue.read();
    if(i<10) Serial.print("0");
    Serial.print(i); Serial.print(":");
    if(bms[i]<16) Serial.print("0");
    Serial.print(bms[i], HEX);
    Serial.print(" ");
    x = (i+5)/10; x = 10*x-1; if(i==x) Serial.println();
    i++;
  }
  Serial.println(); Serial.print("Bytes received : ");Serial.println(i);Serial.println();
}

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

Code changed based on Chrisl's response to :
void GetBMSData()
{
  Serial.println(" Answer :");
  // Feed any received bluetooth data to Terminal.
  i=0;
  if (EEBlue.available()) {
      while (i<146) {
        bms[i]= EEBlue.read();
        i++;
        }
  }

  for (z=0; z<i; z++) {
    if(z<10) Serial.print("0");
    Serial.print(z); Serial.print(":");
    if(bms[z]<16) Serial.print("0");
    Serial.print(bms[z], HEX);
    Serial.print(" ");
    x = (z+5)/10; x = 10*x-1; if(z==x) Serial.println();
  }
  Serial.println(); Serial.print("Bytes received : ");Serial.println(i);Serial.println();
}

with result :
---------------------------------------------------
Sending request (6 bytes) : DB DB 0 0 0 0  Answer :
00:AA 01:55 02:AA 03:FF 04:02 05:71 06:08 07:23 08:08 09:23
10:08 11:26 12:08 13:21 14:08 15:1B 16:08 17:25 18:08 19:1E
20:08 21:27 22:08 23:24 24:08 25:1E 26:08 27:23 28:08 29:27
30:08 31:25 32:08 33:1F 34:08 35:28 36:08 37:21 38:08 39:22
40:08 41:22 42:08 43:1C 44:08 45:23 46:08 47:28 48:08 49:26
50:08 51:31 52:08 53:17 54:08 55:1E 56:08 57:28 58:08 59:29
60:08 61:25 62:08 63:FF 64:FF 65:FF 66:FF 67:FF 68:FF 69:FF
70:FF 71:FF 72:FF 73:FF 74:FF 75:FF 76:FF 77:FF 78:FF 79:FF
80:FF 81:FF 82:FF 83:FF 84:FF 85:FF 86:FF 87:FF 88:FF 89:FF
90:FF 91:FF 92:FF 93:FF 94:FF 95:FF 96:FF 97:FF 98:FF 99:FF
100:FF 101:FF 102:FF 103:FF 104:FF 105:FF 106:FF 107:FF 108:FF 109:FF
110:FF 111:FF 112:FF 113:FF 114:FF 115:FF 116:FF 117:FF 118:FF 119:FF
120:FF 121:FF 122:FF 123:FF 124:FF 125:FF 126:FF 127:FF 128:FF 129:FF
130:FF 131:FF 132:FF 133:FF 134:FF 135:FF 136:FF 137:FF 138:FF 139:FF
140:FF 141:FF 142:FF 143:FF 144:FF 145:FF
Bytes received : 146

you are printing six characters for every one received ... you could use hexadecimal addressing to reduce the number of lines printed ... first line would be 00 : AA 55 AA FF 02 71 08 23 08 23 08 26 08 21 08 1B ... second line 10 : 08 25 08 1E 08 27 08 24 08 1E 08 23 08 27 08 25

Indeed a nice way to visualize the output, but as I like to pick out certain byte visually, I like to be able to see at first view with one I need. But way of visualizing doesn't change/solve the problem, as now I do the visualization afterwards ones I have all bytes in variables.

I see 2 things, that might give you problems. First the one with a higher chance of being the important point:
You use
while (EEBlue.available())

in your GetBMSData() function. With serial (and especially over a packeted protocol like bluetooth) the sender might introduce pauses in the transmission of the data (for example when it needs to wait for more data, doing other tasks than sending or when a bluetooth packet ends and a new one must be send). You cannot control if and when these pauses happen. They might be big enough so that your while() loop can clear the internal buffer of the SoftwareSerial library without already having received the full message.
With serial you cannot think of a message as one block of data, which arrives together at the same time. You need to account for it to take its time. For example you could loop inside that function, until you have received the full message. That would fit to your current code structure. Something like this:
while(i<146){
  if(EEBlue.available()){
    bms[i]= EEBlue.read();
    i++;
  }
}

Note: If for whatever reason less than the expected number of bytes is send, this code will block forever - or until it received that many bytes.
Or - if you want to do it non-blocking (also rewriting the rest of the code), then you could just allocate a buffer big enough for the whole message and only place the bytes as they arrive inside that buffer. The rest (like sending the data out over Serial can then be done, when you have all the data bytes of the message. In this case you don't need a while loop, since the loop() function already handles the looping. You just test on very loop iteration if data is available and read it. After you read a byte you test for the message being complete. If yes, do the printing and processing.

The second problem is not that probable, but I still want to include that here. You are doing quite some printing inside the while loop, printing at least 6 bytes for every received byte. Serial can take some time and if it takes to long you can fill up your buffer in the background, effectively loosing data. I would suggest using the while loop to just read() the bytes and save them in your array. The printing can then be done after the full message was received. For the human reading the Serial printout it will not be different, but you can prevent losing data this way.

I don't know exactly how to implement "For example you could loop inside that function, until you have received the full message." I tried to change my code, see edit original post

I added a small code snippet to my answer. Hope that helps


text:
Cannot change pointer for port in main loop
I am testing on an Arduino UNO. I want to use timer1 and interrupts to create various LED patterns. The LEDs may span multiple ports i.e PORTB and PORTD. I want to use a "volatile uint8_t*" pointer to store whether to toggle a pin on PORTB or PORTD i.e have the pointer store &PORTB or &POINTD. And then use it as necessary. However, once set, I cannot seem to be able to change the pointer in the loop.
Some more details:
I'm using timer1 in CTC mode (clear on compare match) and making use of both OCR1A and OCR1B interrupts.
When output compare A interrupt matches, the led is turned on and a flag is set for the main loop to change leds.
When output compare B interrupt matches, the led is turned off.
The switch statement works and the led pins can be changed i.e next_led and current_led, however, the next_port and current_port statements are ignored in the main loop.
The led pin change works when changing from case 3 to case 1 (when they are both PORTB), but when changing the next_port variable to PORTD this is completely ignored.
At the very beginning of the code, if I initialize current_port and next_port with &PORTD, then just PORTD led will light up and the main loop will not change the current_port and next_port variable to &PORTB.
I have tried using volatile uint16_t* for the next_port and current_port and that doesn't work, either.
What am I doing wrong?
int red_led = 9;    //PORTB 1
int green_led = 10; //PORTB 2

int led3 = 5;       //PORTD 5

volatile uint8_t current_led = 1; //port number of led
volatile uint8_t next_led = 1;

volatile uint8_t *current_port = &PORTB;
volatile uint8_t *next_port = &PORTB;

int counter = 0;
volatile int change_led_flag = 0;
volatile uint8_t led_state = 1;

uint16_t ocr1a_val = 10000-1; //determines period. 16MHz clock, Prescaler=8, 10000-1 ticks = 5ms period (200Hz)
uint16_t ocr1b_val = 9900-1; //determines duty cycle (99% for 10000 ticks)

void setup() {
  pinMode(red_led, OUTPUT);
  pinMode(green_led, OUTPUT);
  pinMode(led3, OUTPUT);

  TCCR1A = 0;
  TCCR1B = 0;

  //set CTC mode
  TCCR1B |= (1<<WGM12);

  //set OCR1A value
  OCR1A = ocr1a_val;
  //set OCR1B value
  OCR1B = ocr1b_val;

  //set pre-scaler to 8
  TCCR1B |= (1 << CS11);

  //enable output compare interrupts
  TIMSK1 |= (1 << OCIE1A);
  TIMSK1 |= (1 << OCIE1B);

  sei();
}

void loop() {
  if(change_led_flag == 1){
  change_led_flag = 0;
  current_led = next_led; //set the current led to what was just turned on
  current_port = next_port; //this statement doesn't do anything.
  switch (led_state) {
    case 1:
      led_state = 2;
      next_led = 2;
      next_port = &PORTB; //this statement doesn't do anything
      break;
    case 2:
      led_state = 3;
      next_led = 5;
      next_port = &PORTD; //this statement doesn't do anything
      break;
    case 3:
      led_state = 1;
      next_led = 1;
      next_port = &PORTB; //this statement doesn't do anything
      break;
    } //end switch statement
  } //end if

} //end loop()

//turn on next_led and set change_led_flag
ISR(TIMER1_COMPA_vect){
  *next_port |= (1 << next_led); //turn on led
  change_led_flag = 1; //set flag to update next led
}

//turn off current_led
ISR(TIMER1_COMPB_vect){
  *current_port &= ~(1 << current_led); //turn off led
}

I get the error: cannot convert 'volatile uint8_t* {aka volatile unsigned char*}' to 'volatile uint16_t* {aka volatile unsigned int*}' in initialization
volatile uint16_t *next_port = &PORTB;

Welcome to SE/Arduino! Please take the [tour] to learn how this site works. If you have any additional information, please [edit] your question, don't post a comment. It will not be read, this is not a forum. -- However, please reduce your program to the most simple example, where you change just the port pointer and use it to access the ports. -- If that does not work generally, you can fall back to use Arduino functions like digitalWrite() or use an enum and a switch, for example.

I don't know this is your problem, but it is a problem in any case.
The pointer itself, not just what it points to, would also need to be volatile qualified. That is:
volatile uint8_t *volatile current_port = &PORTB;
volatile uint8_t *volatile next_port = &PORTB;

The volatile after the pointer declarator (the *) determines the volatile quality of the pointer itself.  The volatile that you already had prior to the declarator is just qualifying what is pointed-to, the port in this case, which is needed for similar reasons.
Without the pointer itself being volatile, you can't expect to changes to it to be reflected correctly between the ISR contexts and the normal main line of execution that runs setup, loop and and most everything else.  The compiler/optimizer may assume since it can't see any way to get to code that can change the value that the value is therefore not changing.  ISR dispatches are outside its field of view.
Also in the when you update next_port outside of the ISR, you probaly should make sure interrupts are off while you update it:
noInterrupts();
next_port = &PORTB;
interrupts();

Because the pointer value is a two-byte address, if you don't disable the interrupts while assigning it your ISR can be dispatched midway through the assignment when the pointer object isn't yet valid.  I say should above, because in your situation the addresses that happen to be used for ports may all have the same upper byte value. It's a good habit to be in regardless.

Thank you so much! Adding the extra volatile fixed the code. (This is the first time I've used a volatile pointer that itself is volatile!)
You make some good points on the non-atomic assignments. It's probably a good idea to put the next_led assignment within that no interrupt block as well, so that the ISR won't dispatch with a mismatched led and port. Thanks again!


text:
Failure using references variables in classes
Theoretical Q
I'm having some trouble when using a referenced variable in a class.
Class A have an int a=0. Class B has an instance of Class A, and referencing int &a=A.a, and in the same manner Class C has an instance of Class B and int &a=B.a. Code crashed when trying to update a variable when using C instance.
Relvant Example
I'm creating a library for TFT+Touch 2.4 screen, to handle buttons more easily.
Libraries XPT2046_Touchscreen and Adafruit_ILI9341 are included here, but initiated in main .ino file for easier handling in loop and more control in main code.
1) MessageTFT
A "basic" class was created, called MessageTFT. This class creates the graphics, and stores its geometrical properties and color as shown below.
2) ButtonTFT
ButtonTFT based on MessageTFT adding touch capabilities to it. Its geometrical and color parameters are referenced to MessageTFT. When creating a button instance, user defines its properties but, actually it is referenced to MessageTFT.
ButtonTFT and MessagesTFT works as expected. For example a button is defined in .ino:
ButtonTFT butt;

and defined in void setup():
  butt.a = 200;
  butt.b = 60;
  butt.xc = tft.width() / 2;
  butt.yc = tft.height() - butt.b / 2;
  butt.txt_size = 1;
  butt.face_color = ILI9341_CASET;
  butt.txt_color = ILI9341_DARKGREY;
  butt.border_color = ILI9341_MAGENTA;
  butt.roundRect = false;
  butt.createButton("Press!");

and in void loop():
  if (ts.touched())
  {
    TS_Point p = ts.getPoint();
    if (butt.checkPress(p))
      {
        Serial.print("Pressed");
      }
  }

3) buttonArrayTFT
Evolving to buttonArrayTFT, which spreads up to 8 buttons x and y centered on screen. Here again using same way to reference relevant properties (in buttonArrayTFT each button's size and position are not defined by user, but calculated to optimize size and position). Now variable are referenced to a ButtonTFT instance, for example &txt_size = _button0.txt_size as shown below.
Since txt_size is common for all button members in that array of buttons, it is referenced for all buttons later in code.
Also buttonArrayTFT works as expected, when defining its instance as:
char *a[] = {"All Windows", "Saloon", "Room", "Specific"};
buttonArrayTFT mainWindows;

and created:
  mainWindows.create_array(4, 1, a);

as a 4X1 button array with text for each button as in a.
The Problem (code crashes)
when trying to pass a value for any of referenced parameter ( taking txt_size as an example ):
mainWindows.txt_size = 3;          // <----- This
mainWindows.create_array(4, 1, a);

While when doing same thing when initiating a button (see up ), I use same way to update button's text size (which is refenced to MessageTFT ).
What may be the reason for that ??
Guy
.h file:
#ifndef TFT_GUI_h
#define TFT_GUI_h

#include <SPI.h>
#include <Adafruit_GFX.h>
#include <Adafruit_ILI9341.h>
#include <XPT2046_Touchscreen.h>

/* Screen calibration */
#define TS_MIN_X 350
#define TS_MIN_Y 350
#define TS_MAX_X 3800
#define TS_MAX_Y 3800
/* ~~~~~~~~~~~~~~~~~ */

/* For Wemos Mini and TFT screen 2.4" */
#define TFT_CS D0
#define TFT_DC D8
#define TFT_RST -1
#define TS_CS D3
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */

const uint8_t _pos_corr_factor_x = 3;
const uint8_t _pos_corr_factor_y = 4;

extern XPT2046_Touchscreen ts; /* Touch screen */
extern Adafruit_ILI9341 tft;   /* Graphics */

class MessageTFT
{
public:
  int xc = 0;
  int yc = 0;
  uint8_t a = 0;
  uint8_t b = 0;
  uint8_t txt_size = 3;
  uint8_t border_thickness = 1;
  char txt_buf[20];
  bool roundRect = true;
  uint8_t screen_rotation = 0;
  uint16_t face_color = ILI9341_GREENYELLOW;
  uint16_t txt_color = ILI9341_BLACK;
  uint16_t border_color = ILI9341_RED;
  Adafruit_ILI9341 *TFT[1];

public:
  MessageTFT(Adafruit_ILI9341 &_tft = tft);
  void createMSG(char *txt);
  void clear_screen(uint8_t c = 0);

private:
  void _put_text(char *txt);
  void _drawFace();
  void _drawBorder();
};

class ButtonTFT
{
public:
  /* Following vars belong to MSG class*/
  MessageTFT MSGwindow;
  int &xc = MSGwindow.xc;
  int &yc = MSGwindow.yc;
  uint8_t &a = MSGwindow.a;
  uint8_t &b = MSGwindow.b;
  uint8_t &txt_size = MSGwindow.txt_size;
  uint8_t &screen_rotation = MSGwindow.screen_rotation;
  uint16_t &face_color = MSGwindow.face_color;
  uint16_t &txt_color = MSGwindow.txt_color;
  uint16_t &border_color = MSGwindow.border_color;
  bool &roundRect = MSGwindow.roundRect;
  char *txt_buf = MSGwindow.txt_buf;
  /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */

  XPT2046_Touchscreen *TS[1];

public:
  ButtonTFT(XPT2046_Touchscreen &_ts = ts, Adafruit_ILI9341 &_tft = tft);
  void createButton(char *txt);
  bool wait4press();
  bool checkPress(TS_Point &p);

private:
  int _tft_x, _tft_y;

private:
  void _put_text();
  void _press_cb();
  /* fucntions below converts touchscreen values to TFT coordinates */
  void _conv_ts_tft(TS_Point &p);
  bool _check_press_geometry(TS_Point &p);
  int _TS2TFT_x(int px);
  int _TS2TFT_y(int py);
};

class buttonArrayTFT
{
public:
  buttonArrayTFT(XPT2046_Touchscreen &_ts = ts, Adafruit_ILI9341 &_tft = tft);
  void create_array(uint8_t R, uint8_t C, char *but_txt[]);
  uint8_t checkPress(TS_Point &p);

public:
  uint8_t &txt_size = _button0.txt_size;
  uint16_t &txt_color = _button0.txt_color;
  uint16_t &border_color = _button0.border_color;
  bool &roundRect = _button0.roundRect;
  int shift_array = 0;

private:
  ButtonTFT _button0;
  ButtonTFT _button1;
  ButtonTFT _button2;
  ButtonTFT _button3;
  ButtonTFT _button4;
  ButtonTFT _button5;
  ButtonTFT _button6;
  ButtonTFT _button7;
  ButtonTFT *_buttons[8] = {&_button0, &_button1, &_button2, &_button3,
                            &_button4, &_button5, &_button6, &_button7};

private:
  uint8_t _num_items = 0;
};

#endif

Edit1: How Constructors are defined in .cpp file
MessageTFT::MessageTFT(Adafruit_ILI9341 &_tft)
{
  TFT[0] = &_tft; // <--- stored in a pointer
}

and
ButtonTFT::ButtonTFT(XPT2046_Touchscreen &_ts, Adafruit_ILI9341 &_tft) : MSGwindow(_tft)
{
  MSGwindow.TFT[0] = &_tft;
  TS[0] = &_ts;
}

and
buttonArrayTFT::buttonArrayTFT(XPT2046_Touchscreen &_ts, Adafruit_ILI9341 &_tft)
    : _button0(_ts, _tft), _button1(_ts, _tft), _button2(_ts, _tft),
      _button3(_ts, _tft), _button4(_ts, _tft), _button5(_ts, _tft),
      _button6(_ts, _tft), _button7(_ts, _tft)
{
  _button0.MSGwindow.TFT[0] = &_tft;
  _button0.TS[0] = &_ts;
}

Sounds like you should actually be using inheritance and polymorphism for this task.

For example in my display library twButton inherits from Widget which itself is a form of Image that is then a virtual Cariad display device.

@Majenko can you please tell what is wrong in my code?

I'm not sure what value this is going to have for Arduino users, but here goes. Your question seem to be an over-complicated form of this the following:
My code:
struct MessageTFT {uint8_t txt_size = 3;};

struct ButtonTFT {
  MessageTFT MSGwindow;
  uint8_t &txt_size = MSGwindow.txt_size;
};

struct buttonArrayTFT {
  uint8_t &txt_size = _button0.txt_size;
  ButtonTFT _button0;
};

buttonArrayTFT bat;

void setup() {
  Serial.begin(9600);
  Serial.println(F("\n\n\nStart."));
}

void loop() {
  Serial.println(bat.txt_size++, DEC);
  delay(1000);
}

My question:
Why does this crash? ...or not print the correct value? or whatever.
I don't think I'm straw-manning (for lack of better term) your question.  But, the question is kind of a mess, so this a best-effort response to it.
If I've clarified the question to the point of being off-topic, so be it. If I do have the correct distillation, if nothing else what people can get out of this is that your questions here can usually be made simpler.
The declared order of members in a class is relevant to the order of initialization; there's more to it than just that. In any case, _button0 has not been initialized prior to your uint8_t &txt_size = _button0.txt_size; The mechanism underlying a member reference in a class is basically that of a pointer.  You are essentially copying an uninitialized pointer out of _button0 and into the txt_size member of buttonArrayTFT; that is the uint8_t &txt_size = MSGwindow.txt_size has not yet been executed.
You can fix this by doing nothing more than reordering the members like so:
struct buttonArrayTFT {
  ButtonTFT _button0;
  uint8_t &txt_size = _button0.txt_size;
};

Now uint8_t &txt_size = MSGwindow.txt_size; in ButtonTFT executes prior to uint8_t &txt_size = _button0.txt_size; in buttonArrayTFT.
This will fix the problem as I've presented. Should you do this? I'm not sure. But then that's not what was asked anyway. Still, you may be better served by getting rid reference members or converting them to inline functions that return a reference type. Or any number of other strategies.
At a minimum this is a problem your code has.

Re “You are essentially copying an uninitialized pointer”: My understanding is that, even though _button0 has not been initialized at this point, it has already been allocated. He is thus copying a pointer to uninitialized data, not an uninitialized pointer. Did I miss something?

The mechanism underlying  uint8_t &txt_size in ButtonTFT is roughly speaking a pointer. When the reference in ButtonTFT is bound to  the txt_size field in MSGwindow, it is initing two bytes of ButtonTFT with the address of the field in MSGwindow. Those two bytes (which are basically a pointer) have not be initialized prior to uint8_t &txt_size = _button0.txt_size; The uint8_t &txt_size = _button0.txt_size;  is binding the txt_size reference of buttonArrayTFT to its counterpart in the ButtonTFT member.This binding is effectively the copying of an (unitialized) pointer.

I'm not sure I do it justice in a comment, I mangled the above pretty bad trying to make it fit. If you want you can find me on libera.chat and I'll explain there.  Or spend some time with it and if it's still not making sense, I will try to update the answer later. The "pointers" I'm speaking of are only to illustrate what's happening underneath the references in terms of something that may already be understood.

Now it is clearer in my mind, thanks!

@timemage I don't understand why did you assume _button0 is not initiaed correctly. please see EDIT 1 in my question

In buttonArrayTFT you have uint8_t &txt_size = _button0.txt_size; and seven lines later you have: ButtonTFT _button0;  If that is in your code as you've shown it, irrespective of what else is in your code, then what I've said the answer applies.


text:
Comments change compiled behavior (sysTickHook weak reference override)
I have a very simple routine that lights up the built-in LED (pin 13) when a system tick timer fires off its interrupt.
I override the weak reference to int sysTickHook(void) found in hooks.c. I found that in generalfor this to work I need to use extern "C" linkage
The part that is bewildering is that this interrupt fires off fine without extern "C" if there are the comments above it as shown below. This is the minimal reproducible example I can find.  Can someone explain this?
I'm using the plain old Arduino IDE 1.8.16.
void setup() {
  pinMode(13,OUTPUT);
  digitalWrite(13,LOW);
}

void loop() {}

// {          -- if you remove this line sysTickHook will not be called
// extern "C" -- if you remove this line sysTickHook will not be called
int sysTickHook()
{
  digitalWrite(13,HIGH);
  return 0;
}

It's probably the function prototypes the IDE puts in that're breaking it.

How would those be affected by the presence of a comment?

I would look into it further, but if I were going to put the effort into that I'd want to know what board support package you were using and what board was selected.

@timemage I havn't installed anything third party nor modified any of the installed libraries. I added via the board manager "Arduino SAM boards 1.6.12". To compile and upload I am just using the "Arduino Due (Programming Port)" drop down. The verbose compiation says Using board 'arduino_due_x_dbg' from platform What other info can I provide?

The problem is the preprocessor in the IDE. It's not clever enough to work out the extern "C" when adding function prototypes.
With your comments you end up with:
#include <Arduino.h>
#line 1 "/home/matt/t/t.ino"
#line 1 "/home/matt/t/t.ino"
void setup();
#line 6 "/home/matt/t/t.ino"
void loop();
#line 10 "/home/matt/t/t.ino"
 extern "C" int sysTickHook(); // << The extern gets added here from the comment
#line 1 "/home/matt/t/t.ino"
void setup() {
  pinMode(13,OUTPUT);
  digitalWrite(13,LOW);
}

void loop() {}

// {          -- if you remove this line sysTickHook will not be called
// extern "C" -- if you remove this line sysTickHook will not be called
int sysTickHook()
{
  digitalWrite(13,HIGH);
  return 0;
}

It finds the extern in the comment and thinks it's real code. If you remove the comment markers it ends up with broken code, as you have a stray { in there. If you remove the comments entirely you end up with the function in the C++ linkage, which changes the function name internally and doesn't then override the weak function. The same happens if you remove just the first comment.
Basically having those comments breaks the preprocessor in such a way that it works.  The proper way of doing it is:
void setup() {
  pinMode(13,OUTPUT);
  digitalWrite(13,LOW);
}

void loop() {}

extern "C" {
  int sysTickHook()
  {
    digitalWrite(13,HIGH);
    return 0;
  }
}

Treating comments as code is a pretty huge bug! Can the Arduino IDE preprocessor really
be broken in this way?

@AdamV.Steele Sure it can. It's less broken than it used to be - it used to even put the prototypes in completely the wrong place and broke any attempt at using structs as parameters.

@AdamV.Steele, lol, welcome to Arduino.


text:
Instances of a class inside another class - is there a way to control the amount?
I have a class with 12 instances of a button, to create a keypad( meaning that this is the only case I use 12 instances). But this class can be just a button array of any other number between 1-12. I'm looking for a way to minimize class overhead of 12 instances, when I most of the time use much less.
'.h' file:
class buttonArrayTFT
{
public:
  buttonArrayTFT(XPT2046_Touchscreen &_ts = ts, Adafruit_ILI9341 &_tft = tft);
  void create_array(uint8_t R, uint8_t C, char *but_txt[]);
  uint8_t checkPress(TS_Point &p);

public:

protected:
  ButtonTFT _button0;
  ButtonTFT *_buttons[12] = {&_button0, &_button1, &_button2, &_button3,
                             &_button4, &_button5, &_button6, &_button7,
                             &_button8, &_button9, &_button10, &_button11};
private:
  ButtonTFT _button1;
  ButtonTFT _button2;
  ButtonTFT _button3;
  ButtonTFT _button4;
  ButtonTFT _button5;
  ButtonTFT _button6;
  ButtonTFT _button7;
  ButtonTFT _button8;
  ButtonTFT _button9;
  ButtonTFT _button10;
  ButtonTFT _button11;

private:
  uint8_t _num_items = 0;
};

http://www.cplusplus.com/doc/oldtutorial/templates/

@Majenko Can you please point?

As pointed out in a comment on your original question, a template is likely the best solution.
Templates allow you to write highly flexible code. I won't explain why; that's something that goes a little beyond the actual question. However, the following will show that you can create a template that means you can create a buttonArrayTFT class with N number of buttonTFT elements, so long as N is known at compile time. The link given as  a comment talks describes various aspects of templates but does not necessarily explain how to string it all together.
From the section Non-type parameters for templates, you will see that you can specify an integer as a parameter for creating N elements of an array member variable.
But what about the type parameter, T? You can simply omit it. You don't actually have to create a template for a type.
In your .h file:
template <uint8_t ARRAY_SIZE>
class buttonArrayTFT
{
public:
// One thing to remember about templates: you have to pack the definition
// into the header file with the declaration to avoid all manner of headaches.

    buttonArrayTFT(XPT2046_Touchscreen &_ts = ts, Adafruit_ILI9341 &_tft = tft)
    {
    // Perhaps this is a good opportunity to check that the specified
    // size of the array is sensible, i.e. not zero and no more than 12.
        if ((ARRAY_SIZE == 0) || (ARRAY_SIZE > 12))
        {
            // decide how you want to handle this problem
        }
            // Add the rest of your constructor here
    }

    void create_array(uint8_t R, uint8_t C, char *but_txt[]);
    uint8_t checkPress(TS_Point &p);

    // This little piece of magic allows you to access buttonTFT 'x' of the
    // private _buttonArray as if a buttonArrayTFT class was an array
    buttonTFT &operator[](uint8_t index)
    {
    // Check that 'index' is a valid element in the array
        if (index > _num_items)
        {
            // decide how you want to handle this problem
        }
        return _buttonArray[index];
    }
private:
    buttonTFT _buttonArray [ARRAY_SIZE];
    // I recommend making this constant
    const uint8_t _num_items = ARRAY_SIZE;
};

I shall leave it up to you to sort out your privates, publics and protecteds, and I have left out ButtonTFT _button0; to keep you on your toes.
You'll also notice that the array is private, as before, but there is now no array-of-pointers-to-buttons. This is because there is no need; the magic buttonTFT &operator[](int index) allows you to access array elements directly.
In your .ino file, or as appropriate, you use the following code to create and then wield the class:
buttonArrayTFT<4> myFourButtonArray(/* constructor arguments as required*/);
buttonArrayTFT<12> myTwelveButtonArray(/* constructor arguments as required*/);

This gives you two instances of the class, with the respective number of buttonTFT elements! You can now access specific buttons using the following code:
myFourButtonArray[0];    // Returns a reference to the first buttonTFT
myTwelveButtonArray[10]; // Returns a reference to the eleventh buttonTFT
myFourButtonArray[n]     // Returns a reference to the 'n+1'th buttonTFT

On the assumption that the buttonTFT class has some kind of 'read' function that returns a TRUE or FALSE for the status of the button, you can write:
if (myFourButtonArray[0].read())
{
    // executed if the button is ON
}
else
{
    // executed if the button is OFF
}

A NOTE ON CONST-NESS:
The overloading of operator[], while wonderfully magic, is open to abuse. However, this is no different from your original code. The array of buttonTFT elements is private but there is public access to all the buttons almost as if the array was not private. In the case of your original code, one could write:
myButtonArray._buttons[0] = myButtonArray._buttons[1];

Now _buttons[0] points to the same buttonTFT as _buttons[1].
Ouch. Now myButtonArray._buttons[0]->read() is literally the same thing as myButtonArray._buttons[1]->read().
That said, my code does not make it a great deal better; the equivalent code:
myFourButtonArray[0] = myFourButtonArray[1];

Simply copies the right hand side over to the left hand side. You still have two distinct buttonTFT instances, with probably no memory leaks, but I am guessing that buttonTFT class may contain a reference to an Input pin, so the _button[0] pin will now be whatever _button[1] pin is because the member variable that stores the pin reference will be overwritten.
To solve this weakness, simply add the const qualifier to the beginning of the operator[] overload:
const buttonTFT &operator[](uint8_t index)
{ // };

Now the buttonTFT element cannot be altered. This of course brings in a new headache that all functions that rely on myArray[n] also need to be constant. It is up to you to determine how constant correctness should be interpreted and whether it is worth the hassle.

Well- so much information to learn :)) firstly - thank you very much for a concise answer. Some clarifications are needed (and perhaps some more will follow ). 1) I didn't know that .h file can get 'if' statements and not only headers. 2) you wrote return theArray[index] what parameter is theArray ? 3) the use of &operator - can you please explain how does it work ? 4) can you noe how the .cpp file will look like

theArray was likely meant to refer to _buttonArray member (rather than parameter).

I wrote the code example with my own member names and missed one of them when I was changing them to match yours. Answer has been edited.

@Guy.D (1) Yes, you can write whatever you want in a .h file, providing it is genuine C++ code of course. When it comes to templates, you cannot easily split the definition and the declaration into separate files because of the way the the compilation works. Google has plenty of articles on the topic. (2) My apologies, that was left over from when I wrote the example and couldn't remember what you had called your members.

@Guy.D (3) The '&' actually belongs to the buttonTFT type specifier, but convention dictates that it is written this way. The symbol means that the function returns a reference. The concept of Operators might confuse matters, so have a read about them in this article (4) I cannot show you how the .cpp file looks as I do not know what is in it! I can tell you that any code relating to the templated class belongs in the .h file, everything else goes in the .cpp file.

int x = 7; int& y = x, z = x; y is a reference to an int that been bound to x; essentially a new name for x. z is just an int (not a reference) and is just copy-initialized with x's value. So really, the & goes with the declared thing.  Same thing with pointers, int* u, v; u is a pointer to int; v is just an int.  For whatever reason most C++ users (not me) want to write the declarator next to the base type, even though that's not what it's connected to syntactically.  I guess they just want to pretend the language works differently from how it actually does.

@CharlieHanson I understand what & refers to, and that wasn't the actual question (perhaps lack of my English skills), what is the actuall use of operator member. Now, I wrote my class as you & majenko explained, but I got errors when I coded it back inside a library (.h and .cpp). Can you please point that out ?

@Guy.D An 'operator' is something that does operations on something else. Think of the simple code int x = 1 + 2. The '+' is the operator, and the compiler knows that int + int is the simple mathmatical sum. But what about myType t = &foo + &bar ? The compiler does not know how to 'add' one myType to another so you have to overload the operator and write the code that is to be executed. In order to remove confusion, the '+' is referred to as operator+. All operators, like -, '&&, (), etc. are similarly referred to as operator-, operator&&, operator().

@CharlieHanson and that way when using [] it returns a pointer the button's instance?

@Guy.D It will return whatever type you declare the operator function to return. In this case, you want operator[] to return a reference to a buttonTFT, not a reference to a buttonArrayTFT because that doesn't make any sense. You also don't want it to return a pointer because _buttonArray is an array of buttonTFT, not buttonTFT*. Also, as I explained in my answer, *(buttonTFT[x]) = (*buttonTFT[y]) will leave you with the left hand pointer pointing to the right hand pointer, but only for the duration of that line of code, so in theory nothing would actually happen.

You can use a template class to provide compile time parameters to your class to tune it. This is most often used in the context of providing a type for the class to operate on. However it's not limited to that. It's also often used to provide a storage size or other similar constant to the class.
They kind of work like preprocessor macros. You specify a token in the class and then give that token a value when you instantiate an object. That token can then be used all over the place in your class.
In your case you can provide the number of elements in your array of buttons as a template variable, for example (note: untested):
template <int N> class buttonArrayTFT {
    protected:
        ButtonTFT _buttons[N];
    public:
        void doSomething();
};

template <int N> void buttonArrayTFT::doSomething() {
    for (int i = 0; i < N; i++) {
        _buttons[i].doSomethingOnAButton();
    }
}

Of course you have to treat your objects a little differently since you can't make an array of pointers to predefined objects any more. Instead just a simple array of objects should be enough.
You then instantiate your class passing the number of elements you want:
// Array of 12 buttons
buttonArrayTFT<12> myButtons;
// and do something
myButtons.doSomething();

Does 'ButtonTFT _buttons[N]' replace the entire definition? in my code I use a pointer array to N instances, so it seems lacking something (or my understanding)

I wrote the class not inside a library, and all was well. BUT, when I write it inside my lib file, I get errors. How should it be noted that way ?

@Guy.D What errors are you getting?

Please see my answer below

@Guy.D Because the template is created at compile time you can't create a separate TU with it in - it effectively has to be 100% inline. It will only work in the header file.

There are more options to solve your question.

To use a template as recommended in the other answers is a fancy option, but if you use a template multiple times, it creates a real class for every template value and you will see it on used flash size.

The best option in my opinion is to provide the array to the class over a constructor. Create a global array of buttons and hand it over to buttonArrayTFT object over a constructor.
const uint8_t BUTTON_COUNT = 12;
ButtonTFT buttons[BUTTON_COUNT];
ButtonArrayTFT buttonArrayTFT(buttons, BUTTON_COUNT);

The ButtonArrayTFT class (simplified) would be like:
class ButtonArrayTFT {
private:
  ButtonTFT *buttons;
  uint8_t count;
public:
  ButtonArrayTFT(ButtonTFT *_buttons, uint8_t _count) {
    buttons = _buttons;
    count = _count;
  }

Other option is to use dynamic allocation on heap. If you would create a ButtonArrayTFT object only once at start and never delete it it would not cause heap fragmentation.
class ButtonArrayTFT {
private:
  ButtonTFT *buttons;
  uint8_t count;
public:
  ButtonArrayTFT(uint8_t _count) {
    count = _count;
    buttons = new ButtonTFT[count];
  }

I'm trying to "digest" all new things in one question (polymorphism,inline,&operator,template ...ahhhhhhh). I'll try understand the way you suggested in a while :) TNX!

The global approach is a good option if you don't mind having direct access to the buttons from anywhere within the code. Hiding them within a class reminds 'future me', and anyone else who inherits the code, that they're hidden for a reason. No idea what the reason is but it prevents unwanted fiddling. The dynamic allocation would benefit from a memory tracker; a static variable that increases by count * sizeof(button) in the constructor, plus maybe a static_assert, will prevent hitting a memory wall.

And +1 for the line about creating one complete class for each distinct number of buttons. I hadn't considered that if the same technique is used on numerous GUI elements the program space could soon evaporate.

I want to share my final updated library (thanks to answers by Majenko&Charlie), perhaps it'll help others.
.h file
template <uint8_t N>
class buttonArray_TFT
{
public:
  int8_t dx = 5;         /* define spacing between buttons */
  int8_t dy = 5;         /* define spacing between buttons */
  uint8_t scale_f = 100; /* change the cale of array. 100% take entire screen */
  uint8_t shift_y = 255; /* Shifts in y director*/
  uint8_t shift_x = 255; /* Shifts in x director*/
  int shrink_shift = 0;  /* shrink array in pixels, and shifts up/ down (+/-) */

  uint8_t &a = butarray[0].a;
  uint8_t &b = butarray[0].b;
  uint8_t &txt_size = butarray[0].txt_size;
  uint16_t &txt_color = butarray[0].txt_color;
  uint16_t &border_color = butarray[0].border_color;
  uint16_t &face_color = butarray[0].face_color;
  bool &roundRect = butarray[0].roundRect;

protected:
  ButtonTFT butarray[N];

public:
  buttonArray_TFT(XPT2046_Touchscreen &_ts = ts, Adafruit_ILI9341 &_tft = tft);
  void create_array(uint8_t R, uint8_t C, char *but_txt[]);
  uint8_t checkPress(TS_Point &p);
};

and more in :
.h file :
template <uint8_t N>
buttonArray_TFT<N>::buttonArray_TFT(XPT2046_Touchscreen &_ts, Adafruit_ILI9341 &_tft)
{
  for (int i = 0; i < N; i++)
  {
    butarray[i].TS[0] = &ts;
    butarray[i].TFT[0] = &tft;
  }
}

template <uint8_t N>
void buttonArray_TFT<N>::create_array(uint8_t R, uint8_t C, char *but_txt[])
{
\\ Code
}

template <uint8_t N>
uint8_t buttonArray_TFT<N>::checkPress(TS_Point &p)
{
  for (uint8_t i = 0; i < N; i++)
  {
    if (butarray[i].checkPress(p))
    {
      return i;
    }
  }
  return 99;
}

You cannot split the code into two files. EVERYTHING for the buttonTFT class must be in the .h file, as both Majenko and I have said. I know it goes against all convention that you have otherwise been taught but templates are the exception to the rule.

@CharlieHanson - Thanks. I'll correct my answer. Appreciate explanaiton about operator


text:
motor driver only works on one side:
I have 3 motor drivers and all 3 other them only seem to only work on one of the 2 sides. I have used a voltmeter to check the voltages across the each of the 2 sections on each motor driver. For all 3 of the motor drivers, 2 of them had one side which had a voltage of 5V (which should be 7.2 volts as thats the power supply) and the other sides of the 2 motor drivers was 0-0.05V (so effectively no voltage). The other motor driver had no voltage from either of the 2 sides. Are all 3 of the motor drivers faulty or have I broke them? The schematic for the motor drivers was as follows:

(Apart from instead of a 12V source, a 7.2V source is used buts thats the amount of Volts I need for the motors. The arduino I used was an Arduino mega rather than an UNO shown in this diagram as I got this diagram off the internet)
Heres a link for the place where I ordered the motor drivers from:
https://thepihut.com/products/l298n-motor-stepper-driver
Here is my code:
    #include <PS2X_lib.h> //for v1.6
    int enA = 3;
    int in1 = 8;
    int in2 = 7;
    int enB = 9;
    int in3 = 5;
    int in4 = 4;
    int error = 0;
    byte type = 0;
    byte vibrate = 0;
    int light_one_pin = 36;
    int light_two_pin = 38;
    bool lights_on = false;
    PS2X ps2x;
    void setup(){
     Serial.begin(9600);
     pinMode(enA, OUTPUT);
     pinMode(in1, OUTPUT);
     pinMode(in2, OUTPUT);
     pinMode(in3, OUTPUT);
     pinMode(in4, OUTPUT);
     pinMode(light_one_pin, OUTPUT);
     pinMode(light_two_pin, OUTPUT);

     //CHANGES for v1.6 HERE!!! **************PAY ATTENTION*************
     for(int x = 0; x < 100; x++)
     {
      error = ps2x.config_gamepad(13,11,10,12, true, true);   //setup pins and settings:  GamePad(clock, command, attention, data, Pressures?, Rumble?) check for error
     }
     error = 0;

    }

    void loop() {
      ps2x.read_gamepad(false, vibrate);

      if(ps2x.ButtonPressed(PSB_GREEN) && lights_on == false)
      {
         digitalWrite(light_one_pin, HIGH);
         digitalWrite(light_two_pin, HIGH);
         lights_on = true;
         Serial.println("on");
      }
      else if(ps2x.ButtonPressed(PSB_GREEN) && lights_on == true)
      {
          digitalWrite(light_one_pin, LOW);
          digitalWrite(light_two_pin, LOW);
          lights_on = false;
          Serial.println("off");
      }

      if(ps2x.Analog(PSS_LY) < 128)
        {
          digitalWrite(in1, LOW);//all fowards wheel
          digitalWrite(in2, HIGH);
          digitalWrite(in3, HIGH);
          digitalWrite(in4, LOW);
          analogWrite(enA, 255);
          analogWrite(enB, 255);
          Serial.println("forwards");

        }

        else if(ps2x.Analog(PSS_LY) > 128)
        {
          digitalWrite(in1, HIGH);//all backwards wheels
          digitalWrite(in2, LOW);
          digitalWrite(in3, LOW);
          digitalWrite(in4, HIGH);
          analogWrite(enA, 255);
          analogWrite(enB, 255);
          Serial.println("backwards");

        }

        else if(ps2x.Analog(PSS_LY) == 128)
        {
          analogWrite(enA, 0);
          analogWrite(enB, 0);
          Serial.println("stationary");

        }

        else if(ps2x.Analog(PSS_LX) == 128)
        {
            //Serial.println("still");
            //wheel_steering_servo.write(wheel_steering_servo_angle);
        }

        Serial.println(ps2x.Analog(PSS_LX));

    }

Please provide a link to the exact product that you are using for the motor drivers. And also show us your code. You can put those information into your question by editing it

@chrisl I have done that.

You have an UNO with pin numbers 36 and 38, eh?

@timemage Oh yeah sorry, my bad I forgot to mention it is an arduino Mega I am using

the correct thing to do, is to edit your post, instead of providing important detail in comments

Swap the motors left and right and see if the problem follows the motor. Swap the sets of INx/EN pins left and right and see if the problem follows the set of pins.

did you check if the library/shield requires some pins to be PWM pins?

Just a correction to something Coder9390 wrote:
The ENA and ENB pins on this motor drive are not supposed to be used as digital pins and receive HIGH or LOW, but as analog pins and receive a value in range 0-255 using a PWM pin (PWM pins are marked on the board with a ~). This enables you to control the speed of the motor, by simulating low voltage.
In your code you actually seem to do this correctly, so I don't think this is the problem. Setting the pinMode of ENA and ENB to OUTPUT on the other hand is correct, so it might actually be the problem. I couldn't reproduce your bug this way though, so it might be something else.
In case you don't need to control the speed of the motor and want it to always go full speed, you can use jumpers to short each EN pin with it's orthogonal-adjacent pin (which are marked in your image as 5v) to achieve the same effect of connecting them to 5v "manually" as Coder9390 suggested (basically by placing the jumpers there you are doing exactly that - connecting the EN pins to 5v).
Coder9390, if you implicitly meant to suggest using jumpers like this, then sorry for misrepresenting your answer. I thought it wasn't clear to beginners who might get here, and that it requires an elaboration.
See this motor driver usage explained here: https://create.arduino.cc/projecthub/ryanchan/how-to-use-the-l298n-motor-driver-b124c5

Very true, I having not much experience with these board, only knew that they enable the outputs, not control the speed, good info .

There are a couple of things that you can check-
Your code-
Chances are that all of the motor drivers are functional (as manufacturing defects are very rare) and that there is something wrong with the code.
1- The motor driver that you are using has 2 pins that should be labeled "ENA", "ENB" (or some variant of these), in order for the motor driver to work on both sides, both these pins must be high, if any one of these are low, then that side will not work. I highly recommend that you directly connect these 2 pins to 5V, and use the 4 inputs for the control.
2- The 4 input pins labeled "IN1", "IN2", "IN3", "IN4" are the pins that instructs the driver to move each side forward or back, check your code to make sure that these pins are high or low as per your requirement.
Another thing is that both the forward and back inputs of one side must not be high at the same time otherwise it won't work
Your hardware-
If you find that something is getting abnormally hot on the boards or worse if something is burnt, then you should check your circuit and make sure there are no problems.
--
A problem in your code, is that "ENB" is not set as an output and hence is not high, you should also modify the setup to set the "ENA", "ENB" to high to make sure that it is on.
So your setup should go something like this-
     Serial.begin(9600);
     pinMode(enA, OUTPUT);
     pinMode(enB, OUTPUT);
     digitalWrite(enA, HIGH);
     digitalWrite(enB, HIGH);
     pinMode(in1, OUTPUT);
     pinMode(in2, OUTPUT);
     pinMode(in3, OUTPUT);
     pinMode(in4, OUTPUT);
     pinMode(light_one_pin, OUTPUT);
     pinMode(light_two_pin, OUTPUT);


text:
Is it possible to use a slide switch without a resistor?
I understand how pullup and pulldown resistors work with push buttons and I also understand that an analogous idea can be applied to slide switches. Furthermore, I know that some versions of Arduino have an internal pullup resistor that can be used, if you adjust the code properly.
I was wondering, if I can, without using the internal pullup resistor, wire a slide switch without any kind of resistor like so:

As I understand, this should behave exactly the same as using a pull-down resistor. If the switch is on the left side, pin 7 would read LOW and if the switch is on the right side, it would read HIGH.
Is that a problem with wiring the switch like this? Is there a reason why using a resistor would be better?
In my final project I intend to use a Digispark board and I would not like to rely on its internal resistor and I also would like to avoid using an external resistor if I can.

Whats wrong about using the internal pullups? Thats easier than your circuit because you don't need the 5V connection. And for the code its just a pinMode(pin, INPUT_PULLUP) instead of pinMode(pin, INPUT). And a real life switch might have a short time where nothing connected during thr switching action. For handling that you might need to increase the debounce time with your setup.

You may be able to do it, or you may not. It depends on the switch.
There are two classes of slide switch:

Make-before-break
Break-before-make

In the former the contact you are sliding to is connected before the one you are sliding away from is disconnected. This can cause untold problems as you will basically create a short circuit between 5V and GND. Everything will die.
In the latter the contact you are sliding away from is disconnected first, and then the new contact you are sliding towards is connected. That is safer, but it does mean that there is a short period while you're sliding the switch where neither contact is connected. At this time the input pin is floating - just as if you had nothing connected at all (which is in fact the case).
That is of course not a desirable scenario as it's probably the most amount of bounce you will ever see in a switch - bounce you need to eliminate in software to give you a clean signal.
That period of uncertainty is eliminated if you have a pullup or pulldown resistor, since there is never a period where there is no connection, and there's never a period where you risk shorting out power and ground. All you have to content with then is the natural bounce of the contacts as they close.

Now I understand the importance of a resistor. One last question, though. Is there a difference between using a pullup or a pulldown resistor? Or can I use either?

It makes no difference, you can use either.

I'm not sure how common they are, but a Make-before-break switch will still be a problem, even if there's a pullup or pulldown on the center wire.

@PMF only if you continue with the (now pointless) connecting of both power and ground.


text:
can differential drive work together with ultrasonic sensor?
I've written a sketch to drive a differential drive system, specifically - to be able to drive strait. This does work.
So I am trying to add the ability to stop when the path is blocked using US sensor directed towards the front of the "car". I manage to get correct readings, but my "car" cannot move strait anymore.
I tried using the ping_timer() functionality of NewPing library, but it did not solve the problem. When the ultrasonic code is commented out, my "car" can go strait.
My algorithm for strait driving is essentially to compare the pulses from two rotary encoders fitted to the wheels, and if one exceeds the other by more than one pulse, shut down the relevant motor and turn on the other motor (if it wasn't on already) so the slower motor has a chance to keep-up.
I wonder if there is a problem in my code that I cannot find, I will be very thankful for anyone who can review my sketch:
#include <Arduino.h>
// #include <Servo.h>
#include <TimedAction.h>
#include <NewPing.h>

#define RIGHT_MOTOR_ON (0 - int(pulseCountRight <= pulseCountLeft + 1))
#define LEFT_MOTOR_ON (0 - int(pulseCountLeft <= pulseCountRight + 1))

const int EN_RIGHT = 6;
const int IN1_RIGHT = 7;
const int IN2_RIGHT = 8;
const int ENCODER_RIGHT = 2;

const int EN_LEFT = 5;
const int IN1_LEFT = 10;
const int IN2_LEFT = 11;
const int ENCODER_LEFT = 3;

const int SPEED = 100;

const int BW_TRUE = -1;
const int BW_FALSE = 0;

// const int SERVO_PIN = 9;
// const int SERVO_MAX_RIGHT = 0;
// const int SERVO_MAX_LEFT = 125;
const int SERVO_SWEEP_DELAY = 150;
// const int SERVO_TURN_RIGHT = -25;
// const int SERVO_TURN_LEFT = 25;

const int ULTRASONIC_TOO_CLOSE = 20;
// Timeout is the maximum time it would take sound to do a roundtrip with length of "ULTRASONIC_TOO_CLOSE".
// Formula is: DIST(cm) x TIME(us per cm).
const int ULTRASONIC_TIMEOUT = ULTRASONIC_TOO_CLOSE * US_ROUNDTRIP_CM;
const int ULTRASONIC_TRIG_PIN = 13;
const int ULTRASONIC_ECHO_PIN = 12;

unsigned int pulseCountRight = 0;
unsigned int pulseCountLeft = 0;

int movingStrait = BW_TRUE;
int stopping = BW_TRUE;

double distance = 0.0;

void pingTimer();
void checkTimer();

NewPing sonar(ULTRASONIC_TRIG_PIN, ULTRASONIC_ECHO_PIN, 400);

TimedAction pingTimerAction(SERVO_SWEEP_DELAY, pingTimer);

// Servo myServo;

void countPulse(unsigned int &counter) {
  ++counter;

  char c[1000];
  sprintf(c, "Pulses (right,left): %d,%d, Motor on (right,left): %d,%d", pulseCountRight, pulseCountLeft, RIGHT_MOTOR_ON, LEFT_MOTOR_ON);
  Serial.println(c);

  analogWrite(EN_RIGHT, SPEED & (RIGHT_MOTOR_ON | ~movingStrait) & ~stopping);
  analogWrite(EN_LEFT, SPEED & (LEFT_MOTOR_ON | ~movingStrait) & ~stopping);
}

void forward() {
  movingStrait = BW_TRUE;
  stopping = BW_FALSE;
  pulseCountRight = 0;
  pulseCountLeft = 0;

  digitalWrite(IN1_RIGHT, LOW);
  digitalWrite(IN2_RIGHT, HIGH);

  digitalWrite(IN1_LEFT, LOW);
  digitalWrite(IN2_LEFT, HIGH);

  analogWrite(EN_RIGHT, SPEED);
  analogWrite(EN_LEFT, SPEED);
}

void backwards() {
  movingStrait = BW_TRUE;
  stopping = BW_FALSE;
  pulseCountRight = 0;
  pulseCountLeft = 0;

  digitalWrite(IN1_RIGHT, HIGH);
  digitalWrite(IN2_RIGHT, LOW);

  digitalWrite(IN1_LEFT, HIGH);
  digitalWrite(IN2_LEFT, LOW);

  analogWrite(EN_RIGHT, SPEED);
  analogWrite(EN_LEFT, SPEED);
}

void right() {
  movingStrait = BW_FALSE;
  stopping = BW_FALSE;

  digitalWrite(IN1_RIGHT, LOW);
  digitalWrite(IN2_RIGHT, HIGH);

  digitalWrite(IN1_LEFT, HIGH);
  digitalWrite(IN2_LEFT, LOW);

  analogWrite(EN_RIGHT, SPEED);
  analogWrite(EN_LEFT, SPEED);
}

void left() {
  movingStrait = BW_FALSE;
  stopping = BW_FALSE;

  digitalWrite(IN1_RIGHT, HIGH);
  digitalWrite(IN2_RIGHT, LOW);

  digitalWrite(IN1_LEFT, LOW);
  digitalWrite(IN2_LEFT, HIGH);

  analogWrite(EN_RIGHT, SPEED);
  analogWrite(EN_LEFT, SPEED);
}

void stop() {
  movingStrait = BW_FALSE;
  stopping = BW_TRUE;

  digitalWrite(IN1_RIGHT, LOW);
  digitalWrite(IN2_RIGHT, LOW);

  digitalWrite(IN1_LEFT, LOW);
  digitalWrite(IN2_LEFT, LOW);
}

void setup() {
  Serial.begin(9600);
  Serial.println("DifferentialDrive2");

  pinMode(EN_RIGHT, OUTPUT);
  pinMode(EN_LEFT, OUTPUT);
  pinMode(IN1_RIGHT, OUTPUT);
  pinMode(IN2_RIGHT, OUTPUT);
  pinMode(IN1_LEFT, OUTPUT);
  pinMode(IN2_LEFT, OUTPUT);

  pinMode(ENCODER_RIGHT, INPUT_PULLUP);
  pinMode(ENCODER_LEFT, INPUT_PULLUP);

  // pinMode(SERVO_PIN, OUTPUT);

  pinMode(ULTRASONIC_TRIG_PIN, OUTPUT);
  pinMode(ULTRASONIC_ECHO_PIN, INPUT);

  attachInterrupt(digitalPinToInterrupt(ENCODER_RIGHT), [] { countPulse(pulseCountRight); }, CHANGE);
  attachInterrupt(digitalPinToInterrupt(ENCODER_LEFT), [] { countPulse(pulseCountLeft); }, CHANGE);

  digitalWrite(IN1_RIGHT, LOW);
  digitalWrite(IN2_RIGHT, HIGH);

  digitalWrite(IN1_LEFT, LOW);
  digitalWrite(IN2_LEFT, HIGH);

  analogWrite(EN_RIGHT, SPEED);
  analogWrite(EN_LEFT, SPEED);

  // myServo.attach(SERVO_PIN);
  // myServo.write((SERVO_MAX_RIGHT + SERVO_MAX_LEFT) / 2);

  forward();
}

unsigned long start_time = 0;

void pingTimer() {
  sonar.timer_stop();
  start_time = micros();
  sonar.ping_timer(checkTimer);
  // NewPing::timer_us(ULTRASONIC_TIMEOUT * 4, checkTimer);
}

void checkTimer() {
  // static int angle = SERVO_MAX_RIGHT;
  // static int direction = SERVO_TURN_LEFT;
  if (micros() - ULTRASONIC_TIMEOUT >= start_time && sonar.check_timer()) {
    distance = ((float) sonar.ping_result / (float) US_ROUNDTRIP_CM) / 2.0;
    if (distance < ULTRASONIC_TOO_CLOSE) {
      stop();
      Serial.println("stoppeing");
    }
  }
  // sonar.timer_stop();
}

void loop() {
  pingTimerAction.check();
  if (distance == 0 || distance > ULTRASONIC_TOO_CLOSE) {
    // forward();
  }
}

Here is a printout of the pulse counts and the status of the motors for a run:
DifferentialDrive2
Pulses (right,left): 1,0, Motor on (right,left): -1,-1
Pulses (right,left): 1,1, Motor on (right,left): -1,-1
Pulses (right,left): 2,1, Motor on (right,left): -1,-1
Pulses (right,left): 3,1, Motor on (right,left): 0,-1
Pulses (right,left): 4,1, Motor on (right,left): 0,-1
Pulses (right,left): 5,1, Motor on (right,left): 0,-1
Pulses (right,left): 6,1, Motor on (right,left): 0,-1
Pulses (right,left): 7,1, Motor on (right,left): 0,-1
Pulses (right,left): 8,1, Motor on (right,left): 0,-1
Pulses (right,left): 9,1, Motor on (right,left): 0,-1
Pulses (right,left): 9,2, Motor on (right,left): 0,-1
Pulses (right,left): 9,3, Motor on (right,left): 0,-1
Pulses (right,left): 9,4, Motor on (right,left): 0,-1
Pulses (right,left): 9,5, Motor on (right,left): 0,-1

Pulses (right,left): 9,6, Motor on (right,left): 0,-1
Pulses (right,left): 9,7, Motor on (right,left): 0,-1
Pulses (right,left): 9,8, Motor on (right,left): -1,-1
Pulses (right,left): 9,9, Motor on (right,left): -1,-1
Pulses (right,left): 10,9, Motor on (right,left): -1,-1
Pulses (right,left): 11,9, Motor on (right,left): 0,-1
Pulses (right,left): 12,9, Motor on (right,left): 0,-1
Pulses (right,left): 13,9, Motor on (right,left): 0,-1
Pulses (right,left): 14,9, Motor on (right,left): 0,-1
Pulses (right,left): 15,9, Motor on (right,left): 0,-1
Pulses (right,left): 16,9, Motor on (right,left): 0,-1
Pulses (right,left): 17,9, Motor on (right,left): 0,-1
Pulses (right,left): 17,10, Motor on (right,left): 0,-1
Pulses (right,left): 17,11, Motor on (right,left): 0,-1
Pulses (right,left): 17,12, Motor on (right,left): 0,-1
Pulses (right,left): 17,13, Motor on (right,left): 0,-1
Pulses (right,left): 17,14, Motor on (right,left): 0,-1
Pulses (right,left): 17,15, Motor on (right,left): 0,-1
Pulses (right,left): 17,16, Motor on (right,left): -1,-1
Pulses (right,left): 17,17, Motor on (right,left): -1,-1
Pulses (right,left): 18,17, Motor on (right,left): -1,-1
Pulses (right,left): 19,17, Motor on (right,left): 0,-1
Pulses (right,left): 20,17, Motor on (right,left): 0,-1
Pulses (right,left): 21,17, Motor on (right,left): 0,-1
Pulses (right,left): 22,17, Motor on (right,left): 0,-1
Pulses (right,left): 23,17, Motor on (right,left): 0,-1
Pulses (right,left): 24,17, Motor on (right,left): 0,-1
Pulses (right,left): 24,18, Motor on (right,left): 0,-1
Pulses (right,left): 24,19, Motor on (right,left): 0,-1
Pulses (right,left): 24,20, Motor on (right,left): 0,-1

What bugs me about this output is that I am expecting the slower motor not to open such large gaps, and I also know that in reality it did not open such large gaps. I suspect some pulses don't get counted for some reason, perhaps I am putting too much work on the micro-controller.
If the problem is not in my code, I wonder if this problem can be solved on a single Arduino device and I just have a weak algorithm, or perhaps it requires a separate device for the ultrasonic and a separate device for the differential drive.
Thanks in advance for any helpers.
PS. I am using this motor shield: https://osoyoo.com/2020/08/06/osoyoo-motor-shield/

The NewPing library uses a hardware timer for doing the background measurement, so does analogWrite. I suspect that there is a conflict for a hardware timer in your code. I currently cannot verify, but you should make sure, that these don't want to use the same timer

Thanks, chrisl. indeed I am using pins 2 and 3 for rotary encoders, and I see that pin 3 belongs to Timer2 which is used by NewPing for UNO boards. I understand that only pins 2 and 3 are usable for interrupts on UNO, so I guess I cannot use the ping_timer function and also attachIntterup on pin 3 on the same board?

Thanks to @chrisl, here is the answer:
The NewPing library uses Timer2 on UNO, which means pin 3 (and 11) is not available for use. I have been using pin 3 for interrupts from a rotary encoder, which is probably the reason for the sluggish performance.
The bad news are there are only two interrupt pins on UNO - 2 and 3, so if I want to attach two rotary encoders to my two drive wheels, I cannot use interrupts to count the pulses. There may be a workaround, I couldn't think of one, but I think IR proximity sensors may be a better choice than my ultrasonic sensor because judging from code examples they are neither blocking nor do they need timers, but I didn't really dive deep into them yet so I may be wrong on this.

If you use the PinChangeInterrupt you can connect the rotary encoders do other pins. I think there are libraries available to handle that kind of interrupt easily. You can search for "Arduino library pin change interrupt". Though changing the design of your project in favor of IR proximity sensors is also a way of handling this.

Thanks! this is very useful. I didn't know this.

authors: יחזקאל הירשהורן


text:
How do I optimize this IRremote code?
I am using a ATTINY85 Digispark board with an IR receiver to light some LEDs in my project. The Digispark has a limitation that does not allow it to use the IRremote.h library. I know that there a series of workarounds for that (including a tiny_IRremote library), but I decided to use this simple code I have found online. It turns on/off a led according to a button press in my Remote:
#define led_pin 9
#define receive_pin 4

bool led_state = LOW;
unsigned long int remote_button_code = 835585799;

void setup() {

  pinMode(receive_pin, INPUT);
  pinMode(led_pin,OUTPUT);
  switch_state = digitalRead(switch_pin);

}

unsigned long int receiveIR() {
  // Wait for start pulse
  while(digitalRead(receive_pin) != LOW)

  if(pulseIn(receive_pin, HIGH, 20000) == 0) return 0;

  // Receive pulses
  unsigned long int result = 0;
  for(int i = 0; i < 32; i++) {
    int pulseLength = pulseIn(receive_pin, HIGH, 5000);
    if(pulseLength == 0) return 0;
    if(pulseLength > 1000) result |= (1UL<<i);
  }

  // Stop pulse
  while(digitalRead(receive_pin) != HIGH);

  return result;
}

void loop() {

  if (receiveIR() == remote_button_code){

    led_state^=1;
    digitalWrite(led_pin, led_state);

  };

}

My problem with this code, however, is on the line while(digitalRead(receive_pin) != LOW) (and I think in the line while(digitalRead(receive_pin) != HIGH)), it sticks the code in a loop until it receives a signal from the remote. This means I can not really use anything after the function receiveIR(), because once the code starts executing this function, it will only exit once a signal is received.
My workaround that is to put everything I want to run inside the
while(digitalRead(receive_pin) != LOW){
  }

in the receiveIR() function. Like so:
(this code uses a Sliding Switch to also control the LED)
#define led_pin 9
#define receive_pin 4
#define switch_pin 7

bool led_state = LOW;
bool switch_state;

unsigned long int remote_button_code = 835585799;

void setup() {

  pinMode(receive_pin, INPUT);
  pinMode(switch_pin, INPUT_PULLUP);
  pinMode(led_pin,OUTPUT);
  switch_state = digitalRead(switch_pin);
}

unsigned long int receiveIR() {
  // Wait for start pulse
  while(digitalRead(receive_pin) != LOW){

    if(switch_changed()){

      led_state^=1;
      digitalWrite(led_pin, led_state);

    }

  }

  if(pulseIn(receive_pin, HIGH, 20000) == 0) return 0;

  // Receive pulses
  unsigned long int result = 0;
  for(int i = 0; i < 32; i++) {
    int pulseLength = pulseIn(receive_pin, HIGH, 5000);
    if(pulseLength == 0) return 0;
    if(pulseLength > 1000) result |= (1UL<<i);
  }

  // Stop pulse
  while(digitalRead(receive_pin) != HIGH);

  return result;
}

bool switch_changed(){

  if (digitalRead(switch_pin) != switch_state){

    switch_state ^=1;

    return true;
  }

    return false;

}

void loop() {

  if (receiveIR() == remote_button_code){

    led_state^=1;
    digitalWrite(led_pin, led_state);

  };

}

This workaround does the job, but it is not very elegant. Is there a way to modify the first code, so I can use other functions after I call the receiveIR() function?

move first two lines of receiveIR() into loop() ... do not use while, use if .... use a flag like signalStarted = true to "remember" if receive_pin has detected signal ...  something like this inside loop() ... the if statements are not nested ... if signal is detected and flag is not set, then set flag and start timer .... if flag is set and timer expired, then run receiveIR() ... do other stuff in loop()

forgot one test at the begining of loop() ... if signal not detected  then clear flag ... the if statement order does not really matter


text:
Arduino Nano PID Controller with Potentiometer + IBT-2 Motor Control Board
I have a potentiometer connected to an analog pin A1 and would like to implement PID
Control to move a robot arm up and down based on to a given serial command. For this
to work I will need PID out produce a direction and speed output.
#include <AutoPID.h>

// PID settings and gains
#define OUTPUT_MIN 0
#define OUTPUT_MAX 255
#define KP 0.12
#define KI 0.8
#define KD 0.003

// Variables on PID values
float analogReadValue, setPoint, outputVal;

int SENSOR_PIN = A0; // center pin of the potentiometer

int RPWM_Output = 10; //IBT-2 Motor Control
int LPWM_Output = 11; //

bool BarUp;
bool BarLow;
bool BarStop;

float sensorA1;

char c;

// Input/output variables passed by reference, so they are updated automatically
AutoPID myPID(&analogReadValue, &setPoint, &outputVal, OUTPUT_MIN, OUTPUT_MAX, KP, KI, KD);

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

  //Motor Direction controls
  pinMode(RPWM_Output, OUTPUT);
  pinMode(LPWM_Output, OUTPUT);

  myPID.setTimeStep(500);
}

float AnalogSensor()
{
    // read the input on analog pin 0:
    int sensorValue = analogRead(SENSOR_PIN);
    // Convert the analog reading (which goes from 0 - 1023) to a voltage (0 - 5V):
    float voltage = sensorValue * (5.0 / 1023.0);

    return voltage;
}

void loop()
{
   analogReadValue=AnalogSensor();

  //Reading serial command
  if(Serial.available())
  {
     char c = Serial.read();

     if(c=='r')
     {
         BarLow=false;
         BarUp=true;
         Serial.println("Arm is Rising");
     }
     else if(c=='l')
     {
         BarUp=false;
         BarLow=true;
         Serial.println("Arm is lowering");
     }
}

if(BarUp)
{
  setPoint=UpperLimit;
  myPID.run();
}

if(BarLow)
{
  setPoint=LowerLimit;
  myPID.run();
}
}

void RaiseArm()
{
   analogWrite(LPWM_Output, 0);
   analogWrite(RPWM_Output, 20);

   delay(1000);

   StopArm();

   BarUp=false;
 }

 void LowerArm()
 {
   analogWrite(LPWM_Output, 20);
   analogWrite(RPWM_Output, 0);

   delay(1000);

   StopArm();

   BarLow=false;

 }

 void StopArm()
 {
    analogWrite(LPWM_Output, 0);
    analogWrite(RPWM_Output, 0);
 }

Ideally I would like to set the Setpoint to analog 5.0 for raising arm and analog
0 for lower arm. Baring in mind.
   analogWrite(LPWM_Output, 20);
   analogWrite(RPWM_Output, 0);

Is for raising arm and
   analogWrite(LPWM_Output, 20);
   analogWrite(RPWM_Output, 0);

Is lowering arm. Hope you can help as the current system is not implementing PID that can
potentially work. How can I out put a direction and speed from my pid function call to control the arm.

And what exactly is your problem in doing that? You didn't describe how exactly this is not working. Please be way more specific.

How can I output a direction and speed from my pid function call to control the arm direction and speed.  As I have not worked with PID previously.

do you understand the example code that is included with the AutoPID library?

Yes I understand parts of it but learning as I go. The Setpoint would be the desired Potentiometer value. I am trying to figure out how the output can be integrated with the direction and speed values to control the motor. analogWrite(LPWM_Output, 20);
analogWrite(RPWM_Output, 0);

The text about raising and lowering the arm doesn't match the code.  What does analogWrite(LPWM_Output, 20) actually do?  Is it's '20' what you would want to affect with the PID?    The way to understand PID is to focus on the "P"roportional term and the proportion of setpoint error that you want to convert into process output. Are you converting Ohms of error into PID duty cycle?  Volts of error into a servo position?  AnalogRead counts into speed?


text:
Arduino Nano I2C OLED display 0.96 inches 128x64 pixels
I have a strange issue while trying to run the hello world code on an arduino nano connected to an OLED display.
This is the code I used:
    #include <Adafruit_SSD1306.h>
Adafruit_SSD1306 display = Adafruit_SSD1306(128, 64, &Wire);

void setup() {

  // SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally
  display.begin(SSD1306_SWITCHCAPVCC, 0x3C); // Address 0x3C for 128x32

  display.display();
  delay(2000);

  display.clearDisplay();      //this line to clear previous logo
  display.setTextColor(WHITE); //without this no display
  display.print("Hello World!");//your TEXT here
  display.display();            //to shows or update your TEXT
}

void loop() {

 }

But I get this on the display.

Any idea what I could be missing?
Thanks !

Do you have the product link of your display?

I had this display laying around for a while, unfortunately I can't find the product link.

Is the driver IC SSD1306? Can you see that at the back of the display?

Not sure where can I see that, I added a picture with the back.

Why are you using Adafruit_SSD1306 library? It is possible that the display driver is not SSD1306. Also, from your second picture, it looks like the address is 0x78. In the code, you are using 0x3C. Also, show us how did you connect the display with Arduino Nano.

Also, check if the display I2C pins have pull-ups.

@Fahad This doesn't look like an I2C problem, but rather something with the font handling (note that the "H" and "W" are correct, but the rest of the letters are somewhat off (L=E, S=L, etc.) I'd try reinstalling the library.

Good point. I have seen other people said sometimes Chinese manufactured display have the address 0x7A but works with 0x3C. But the pull-up can be a problem. If there is no pull-up, the floating state can generate garbage data.

0x7A is 0x3C << 1 which is correct. I2C addresses are 7 bits and the 8th bit (rightmost) is use as a R/W flag. So you shift the I2C address one to the left and then add a 1 or 0 to the left for read/write operation (I forget which way around it is). The Arduino library does that for you, so you need to provide the "unshifted" address of 0x3C.

Mystery solved :)
After some more reading it appears that the display driver is actually SH1106, so after using the right library I got the display working.


text:
Updating ESP32 firmware from another ESP32 over USB, similar to how esptool.py works
Is there a way to update the firmware on one ESP32 from another ESP32 over USB, similar to how firmware can be updated using esptool.py?
This would essentially be like a port of whatever magic esptool.py uses over USB to update an ESP32, but instead of running through Python it would be an Arduino C++ sketch and would read the firmware to write to the other ESP32 from SPIFFS.

since ESP32 doesn't have an USB peripheral on chip, a better idea would be to that over the UART. did you research before asking? did you find something? did you try something?

Thanks for sharing your opinion, @Juraj.  However, all of the ESP32s that I am working with include a CP2102 USB to UART bridge.

can CP2102 act as USB host? no.

That's a great point, @Juraj

you know that you can use OTA upload?

You can use the SD card to update the firmware.
Here is the example code

The esp32 can update itself. To store and apply the updated sketch's binary it uses the Update library bundled with the ESP32 Arduino boards support package.
Then there are libraries for different ways of transporting the binary over network:

ArduinoOTA for upload from the Arduino IDE
HTTPUpdate to download the binary from a web server
HTTPUpdateServer to upload the binary to ESP32 over a web page

The keyword is "OTA update" as "over the air update" even it is possible to transport the update over cable too.