text:
Greyed out port for Raspberry pico in Arduino IDE - Ubuntu 20.04
I'm trying to figure out how to program my new Raspberry Pico with Arduino, but don't see a port to select so I can't upload the blink sketch.
Here's what I've done:

The Pico is working, I can program it with micro Python.
Just in case, I brought the Pico back to factory settings with the nuke file.
Installed support for the Pico in Arduino IDE. Version 2.1.0 of Arduino MBed RP2040 is installed.
While keeping BOOTSEL pressed, I plug in the Pico to my laptop (Ubuntu 20.04)
The board selected is "Raspberry Pi Pico"
But the option to select a port is greyed out :-(

It seems that I am omitting some step during the installation, but can't figure out what it is.
Any ideas?
Thanks!

I've come across this and this is how I worked around it (on Windows, but I suspect the problem and solution is the same).
A brand new Pico or one not programmed by the Arduino IDE does not have a serial port, which is why you can't see one. Arduino sketches are compiled with a serial port automatically, so once a serial port exists, it can be used for future uploads.
The Arduino solution is to use the 'Export compiled binary' option (for any sketch) and upload the UF2 file (which should be generated into the sketch folder) using virtual USB drive interface. When the sketch starts, the serial port will be available and can be used for future sketch uploads.
Another solution is to use an alternative Pico core. This one does not need the port selected, but will find and upload to a Pico in bootloader mode via the virtual USB drive.

Had this issue and tried everything that was described on forums.
The thing that worked for me was: I held the bootsel button until it opened pico  folder, then port button activated in the IDE and I chose UF2 port and then after upload, pico showed at COM7


text:
How to properly handle the Arduino String
I've read that the Arduino String is bad as it causes memory fragmentation, so I try to avoid them mostly. But I still have some occurences where I'm not quite sure if they are ok after all.
The first is in print statements:
I have a function which prints a success or error message to the serial port, like so: Serial.println("Success");. Is this ok or should I (for example) pre define the String using #define SUCCESS "SUCCESS"?
Which leads me to the next case, defines:
I'm using MQTT and have the topics defined like above, e.g. #define TOPIC_COLOR "light/color". Is this fine?
A third one is with ArduinoJSON:
I'm using Strings as keys, like so lights["red"] = redVal;. This call is made at multiple places so I assume the string would be created multiple times? A workaround/improvement I've thought of is using an enum defining the properties and using that as key.
Thanks for all comments, tips and explanations!

You're confusing "strings" with the Arduino String class.

@Majenko So my usage of those strings is fine?

Strings, as in "this", are just chunks of static data. It's when you start messing with String objects that problems occur. I don't know what ArduinoJSON does with string indices, though. On smaller MCUs (AVR) you should use F("stringliteral") to reduce RAM usage whenever possible, though.

@Majenko alright thank you. I don't know either but it seems commonly used so I assume it handles them good enough.
Thanks for the tip! I'm on an ESP8266 right now so that won't be a problem for now

a couple points: using Strings is fine sometimes; in setup(), static globals, consts, etc. It's more that modifying Strings is the real silent killer. The ESP also has much more ram and I've seen them "stop sinking" on code that will inevitably sink an AVR. I'm not saying String is not without pitfalls, just that not every single use is a showstopper.

+1 to @majenko's comments. I tend to avoid the String class, as I like to know what is actually going on, and I stick to char * and char [] in general (and the stdlib functions like sprintf, strlen, etc).
Couple of notes on your question:

"foo/bar" is fine. Some characters have special meanings in the C language itself, so you need to escape them with the \. For example if " was part of your literal string, you'd write "foo\"bar\""

I tend to use ArduinoJSON to parse. If my app is just sending JSON payloads, I just build it with sprintf or print which results in smaller programs. But, I guess it is a matter of choice. It is a great library.

Thanks! I'm using ArduinoJSON to parse and send, but also to store the current state, it's quite handy that it does all those things. As of now, storage is enough, if it gets sparse I'll have to think of something else...

source: Stack Exchange

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

sort: votes


text:
Weight scale with Arduino: calibration step
I'm not an expert about Arduino and I'm studying to create a project related to the bees remote monitoring.
I would like to monitor the internal humidity and temperature and the weight of the beehive boxes.
About the weight parameter my idea is to make a structure with 4 load cells.
I watched some video tutorials related to the creation of a weight scale with Arduino. I saw that it's necessary to calibrate the scale without any weight on the scale every time that Arduino will be started.
I'm not able to understand if there is a way to have this calibration in a different way: I mean,  I will place the beehives on my weight scales only one time and Is not possible to remove and put them back for each calibration step.
Is it really necessary or is there a way to have the calibration with the weight on the scales also?

Once the cells are calibrated w/ no weight those values can be stored and used. It's possible there might be some drift over time (not sure) but for this use case it shouldn't be a huge issue, assuming you're after an approximate hive weight. I'd also imagine you're more interested in weight differential than absolute weight, e.g., "am I having honey tonight" or "where have my bees gone?!"

Can you share the source of your remark: "...I saw that it's necessary to calibrate the scale without any weight on the scale every time that Arduino will be started.".

(Also see https://github.com/sparkfun/HX711-Load-Cell-Amplifier, the calibration program makes note of applications where there's a "constant" weight on the load cells between power cycles, although your weight won't be constant. IIRC temperature can also affect readings.)

Problem completely solved by SparkFun: https://github.com/sparkfun/Beehive_WiFi

It may be that in this application (beehive monitoring) it is not required to re-calibrate your load sensors before each use.  When a person is observing a scale to measure their own weight they will be sensitive to the scale reading zero before each use.  Even though being, say, a lb off is likely less than a 1% error when measuring their total body weight.  This site talks about load cell calibration and "recommends a yearly recalibration interval".  They also talk about temperature compensation.
As temperature and humidity will be monitored.  And nonlinear load sensor response to weight can be compensated in software, consider testing your setup under different conditions to determine what considerations need to be taken into account to provide the desired accuracy.

This image is from https://www.futek.com/load-cell-calibration-services

What I can find about calibrating load cells is that they are subject to "electrical influence, mechanical effects, instrumentation faults and
loose cables etc."
In the case of beehives, I'd add temperature, water, ice, snow, dirt & dust, and debris from the bees. The calibration suggestions I found were to calibrate "periodically", which suggests to me that the suggestion to calibrate at every startup assumes that the calibration will be lost at every power-down. That does not have to be the case - it can be store in a non-volatile memory such as EEPROM.
What I do think you'll need to do is calibrate each cells at 0%, 10%, ..., etc., of its full load, probably to 120% or 130% to allow for wind loading and asymmetric loading within the hive, and at a range of temperatures, make a set of force vs. cell output and temperature, from which to interpolate to get the 4 partial hive-weights.
They probably will need to recalibrated periodically, but for your application, a tare-value, measured at a reproducible hive condition, may be sufficient, if all you need is a differential weight.

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


text:
SPIFFS and LittleFS don't show all my files with readdir() and can't open() them
I created a simple sketch that just tries to list the files in SPIFFS. The SPIFFS filesystem was created with the version of mkspiffs that's part of the esp8266 package. The upload all seems to work, but it only lists the first file and not the rest.
After running the sketch I downloaded the flash memory and it compared OK so nothing is being corrupted...
$ esptool.py --port=/dev/ttyUSB0 read_flash  0x200000 0x10000 foo
$ cmp html.img foo
$

If I try the same with LittleFS then I get no files reported!
I also tried upgrading to the 3.0.0 libraries (and thus also the later version of mkspiffs that came with the library)
Clearly I'm doing something stupid and wrong!
Hopefully the following (showing how I build it, upload it) will help point out my mistake!
Thanks for any assistance...
================================================================
Creating Image file
This is done using the mkspiffs that comes with the package so it should(!) match the library used by the ESP8266
$ ~/.arduino15/packages/esp8266/tools/mkspiffs/2.5.0-4-b40a506/mkspiffs -c html html.img
/menu_frame.html
/change_ap.html
/top_frame.html
/index.html
/main_frame.html

Compiling with 4M2M memory layout
$ arduino-cli compile --fqbn=esp8266:esp8266:nodemcuv2:eesz=4M2M
Executable segment sizes:
IROM   : 265840          - code in flash         (default or ICACHE_FLASH_ATTR)
IRAM   : 26888   / 32768 - code in IRAM          (ICACHE_RAM_ATTR, ISRs...)
DATA   : 1248  )         - initialized variables (global, static) in RAM/HEAP
RODATA : 800   ) / 81920 - constants             (global, static) in RAM/HEAP
BSS    : 25120 )         - zeroed variables      (global, static) in RAM/HEAP
Sketch uses 294776 bytes (28%) of program storage space. Maximum is 1044464 bytes.
Global variables use 27168 bytes (33%) of dynamic memory, leaving 54752 bytes for local variables. Maximum is 81920 bytes.

Uploading, writing the bin at 0x0 and the filesystem at 0x200000
$ python ~/.arduino15/packages/esp8266/hardware/esp8266/2.7.4/tools/esptool/esptool.py --port=/dev/ttyUSB0 write_flash 0x0 SPIFFS.esp8266.esp8266.nodemcuv2.bin 0x200000 html.img
esptool.py v2.8
Serial port /dev/ttyUSB0
Connecting....
Detecting chip type... ESP8266
Chip is ESP8266EX
Features: WiFi
Crystal is 26MHz
MAC: b4:e6:2d:67:b1:45
Uploading stub...
Running stub...
Stub running...
Configuring flash size...
Auto-detected Flash size: 4MB
Compressed 298928 bytes to 219676...
Writing at 0x00034000... (100 %)
Wrote 298928 bytes (219676 compressed) at 0x00000000 in 19.5 seconds (effective 122.7 kbit/s)...
Hash of data verified.
Compressed 65536 bytes to 1353...
Writing at 0x00200000... (100 %)
Wrote 65536 bytes (1353 compressed) at 0x00200000 in 0.1 seconds (effective 4232.8 kbit/s)...
Hash of data verified.

Leaving...
Hard resetting via RTS pin...

Results:
... It shows 2M for the filesystem.
... But only one file is listed?
... If I use LittleFS instead then no files are listed!
Starting...
Total size of FS is: 1953282
Used size of FS is: 2259
File list:
/menu_frame.html
Finished

And, finally, the sketch
#include <FS.h>

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

  Serial.println("Starting...");

  SPIFFS.begin();

  FSInfo fs_info;
  SPIFFS.info(fs_info);

  Serial.print("Total size of FS is: ");
  Serial.println(fs_info.totalBytes);

  Serial.print("Used size of FS is: ");
  Serial.println(fs_info.usedBytes);

  Serial.println("File list: ");
  Dir dir = SPIFFS.openDir("/");
  while (dir.next())
  {
    Serial.println(dir.fileName());
  }
  Serial.println("Finished");
}

void loop() { }


text:
Wirelessly (but fast) transfer STEP and DIR output from Arduino to stepper driver
Very short version:
Looking for a way to wirelessly get STEP and DIR signals (only those two signals) from an Arduino to a DRV8825 stepper driver about a meter away:
Arduino -> STEP and DIR IO pins -> transmitter ) ) ( ( receiver -> DRV8825

edit Jan. 2024: Just to follow up on this; in the end I decided to simplify the whole setup I had, and moved all electronics, except for the power supply, to the moving part. A custom slip ring connects a PSU that is on the floor to the rotating platform that holds the Arduino, steppers, etc.
Long version:
For a project I've mounted an Arduino to a wooden board. The Arduino has a GRBL shield (basically a breakout board to four motor drivers for stepper motors (in my case the DRV8825)). Connected to this setup is a stepper motor. The power supply (NOT on the wooden board) for the motor is 24v, and I'm using a buck converter to take it down to 5v for the Arduino.
This whole board is rotating and the 24v gets passed to it using a custom sliding-contact with two contacts (24v and gnd).
Now this all works fine, but the problem is this: I have a second motor which I want to control from the same GRBL shield. But this motor is NOT on the rotating board.
If I place the motor driver next to this motor and power it from the same power supply (parallel to the sliding-contact) I have everything I need, except for the STEP and DIR signals from the Arduino.
Because there is no way I can add 2 more contacts to the sliding-contact (plus the signal would probably be too noisy anyway) I'm looking for a way to basically add a wireless bridge between the STEP and DIR output pins on the Arduino, and the STEP and DIR input pins on the motor driver. The motor and driver are about a meter away from the Arduino, so signal strength shouldn't be a problem.
I believe those well known 433Mhz transmitters are too slow for something like this, but I read most nRF24L01 modules are faster. Before I order some for a test setup, I was wondering if anyone already knows if this could work or not, knows a useful alternative, or has some suggestions for keywords to search for when trying to find another solution. I can find a lot of 'wireless' motor drivers online, but most are completely standalone units where the microcontroller is on the board, it's just controllable over wifi/bluetooth.

(Moved to "answer" for space; it's definitely not an answer. Sorry all!)
Minor points:

It's a motor controller shield; the GRBL is on the Arduino.
You'll need a motor controller at each motor; not clear if that's understood.
I'd also consider optical comms, although it has a different set of problems.

Ultimately I might approach this in a different way: instead of a single GCode box attempting to synchronize and control itself and an (essentially) independent system, I'd consider having a single GCode box (GBOX) controlling two independent systems (M1, M2).
GBOX would be a laptop/RPi/whatever that processes the "real" GCode. Based on the GCode commands, which in the end just tell motors what to do, I'd send each GCode command to its associated M1/M2 system.
How well this works depends a lot on the GCode, however; diagonals, arcs, etc. require motor cooperation, so a command like G02 X2Y0 R2 might cause problems, even though we can pull out the X and Y data. How the GCode is generated matters, but note that GBOX could also interpolate "tricky" commands to break them into something a dual-target system might be able to understand.
The "meaning" of the moves also matters: there's "getting from one place to another" and "getting from one place to another while drawing a line": the former may (or may not) have requirements around what that actually means, while the latter requires coordinated motion, and even if you're splitting the commands up correctly, even a fraction of a second difference in receive/action time will matter. Of course, you could also transmit both motors' commands to both motors and rely on timing or cross-Mn synch for starting their respective commands.
In the end it may be the only real way to make this work would be to have the "independent" systems be able to synchronize with each other, so that they know they're (a) ready to start, and (b) starting at the same time. GBOX could also potentially handle that synchronization as a "Go!!!" command is about as deterministic as it gets, especially if M1/M2 can receive a broadcast signal at the same time.
https://www.zikodrive.com/motor-control-case-studies-and-applications-2/a-remote-controlled-and-synchronised-stepper-motor-controller/ (very) briefly discusses the issues around synchronizing remote motors where their relative positions matter.

Not that I've given things like this any thought :p We had a similar approach to a similar, but non-wireless, project, but the motion control required was limited in scope, and synchronization was trivial, because the second system was limited in scope, and required no simultaneous cooperation with the primary system.

This GO signal sounds like a great idea. I can create two setups, have them use the same GCode but only connect their relevant motors. This should ensure they use the right timing (so motor X will wait for motor Y)
I have a lot of straight movements in my GCode so I could even execute them line by line with a GO in between to prevent a slowly increasing offset.
I borrowed a couple of NRF24L01's so I'm going to give the IO bridge idea a quick try, but could also use them to sync up the two setup. Thanks for the suggestion!


text:
Conditional compilation depending on sizeof(double)
Is there a macro (#define ...) somewhere in the bowels of Arduino IDE or core header files which tells me at compile time(!), if the double data type for a given platform/board is a true double precision floating point number (64 bit width) or "only" an alias for a single precision float (32 bit width)?
With Arduino, both can be the case. 8-bit AVR boards have double equal to float, ARM-based boards (like Arduino Zero) support "true" double precision.
I am working on a library which implements some bit-banging of floating point numbers (both single and double precision). Due to the low-level nature of the problem, there must be separate functions for float and double. I would like to do somthing like that:
uint32_t function_for_float(float f) {
    // function body here...
}

#if defined(HAS_64_BIT_DOUBLE)
uint64_t function_for_double(double d) {
    // function body here...
}
#endif

That way, a compile time error would be generated if somebody tried to use the "double" version on platforms which do not support the "true" double data type. I want the compiler error to be generated, because function_for_double() will do silently "the wrong thing" when fed a single precision float, leading potentially to difficult-to-debug problems.
Right now, I am defining a macro constant for every relevant board I own, like this:
#if defined(ARDUINO_SAMD_ZERO) \
 || defined(SAMD_FEATHER_M0_EXPRESS) \
 || defined(ADAFRUIT_FEATHER_M4_EXPRESS)
    #define HAS_64_BIT_DOUBLE
#endif

But this is ugly and not future-proof (new boards can/will become available...).
Any suggestions?

This is not really an Arduino question. Arduino uses g++ to compile, so your question really is "can g++ do this?" Judging by this - not really. You can assert if double isn't 8 bytes (I tested that) but not make a choice, unless there is another tricky way of doing it.

@NickGammon: Thanks for the link. I actually have a static_assert(sizeof(double) == 8) in the code of my "double function". However, then the complete library .cpp file will not compile on platforms where double ist only four bytes. This is what brought me to think about conditional complilation in the first place. I would like to generate a compiler error only if sombody tries to use the double version when he/she shouldn't. Somewhere in Arduino there surely must be definied that double is equal to float? I hope(d) to use this as a hook somehow...

The double data type is almost universally 8-bytes long, so you could
simply
#if !__AVR__
# define HAS_64_BIT_DOUBLE
#endif

Gcc provides a more specific macro though: __SIZEOF_DOUBLE__, which
has the same value as sizeof(double). But I do not know whether it is
provided by other compilers.

Perfect! I will make use macros __SIZEOF_DOUBLE__ and __SIZEOF_DOUBLE__, even if they are gcc/g++ specific. The Arduino IDE uses g++ as its backend, anyway, so this is "good enough" for me.

Just verified that __SIZEOF_DOUBLE__ == 4 on an Arduino Pro Mini (AVR 328p) and __SIZEOF_DOUBLE__ == 8 on an Adafruit Feather M0 (ARM Cortex-M0+ / SAMD21). Thanks a lot! I have selected your answer as the correct one.


text:
Make a Jack-Bluetooth Module for the car
I'm making a Jack-Bluetooth module so that I can send music to the car (or other devices w/ Jack plug) without an internal Bluetooth module in the car.
https://habr.com/en/post/456182/ says that I need around 44 kHz of sampling frequency to get high quality sound. Is there a BT module on the market w/ these specs?
Audio Recording using Arduino BT module says that the HC-05 HC-06 HC-07 are not good enough.
If there are no such cases, I think I should consider buying an Arduino that has an built-in BT/WiFi module or I can buy such a BT transmitter but beats the fun.

Just buy a small bluetooth audio receiver. There's fun, there's torture, and then there's trying to make your own bluetooth audio receiver. It's just not worth the effort, even if you enjoy torture.

There is no way you will do it with a bluetooth "module" to an Arduino. You need: * A arduino with builtin bluetooth. * An Arduino with an I2S interface and high quality CODEC. * A lot of skill in programming and an in-depth knowledge of Bluetooth audio protocols.


text:
Error Performing HTTP GET request on google sheets (Apps Script) using TTGO T-CALL
I've tried using several libraries such as TinyGSM, SoftwareSerial, AT commands but I'm guessing the problem to be with my GET request url is https://script.google.com/macros/s/GAS_ID/exec?tag=1234&value=5678 and the Apps Script code is
   function doGet(e){
      Logger.log("--- doGet ---");

      var tag = "",
      value = "";

   try {

// for debugging
if (e == null){e={}; e.parameters = {tag:"test",value:"-1"};}

tag = e.parameters.tag;
value = e.parameters.value;

// save the data to spreadsheet
save_data(tag, value);

  return ContentService.createTextOutput("Wrote:\n  tag: " + tag + "\n  value: " + value);

   }
 catch(error) {
   Logger.log(error);
return ContentService.createTextOutput("oops...." + error.message
                                        + "\n" + new Date()
                                        + "\ntag: " + tag +
                                        + "\nvalue: " + value);
        }
      }

     // Method to save given data to a sheet
    function save_data(tag, value){
    Logger.log("--- save_data ---");

    try {

    // Paste the URL of the Google Sheets starting from https thru /edit
    // For e.g.: https://docs.google.com/..../edit
     var ss = SpreadsheetApp.openByUrl("https://docs.google.com/spreadsheets/d/SPREAD_SHEET_ID/edit#gid=0");
var dataLoggerSheet = ss.getSheetByName("Sheet1");

// Get last edited row from DataLogger sheet
var row = dataLoggerSheet.getLastRow();

// Start Populating the data
dataLoggerSheet.getRange("A1").setValue(tag);
dataLoggerSheet.getRange("B1").setValue(value);
  //dataLoggerSheet.getRange("C" + row).setValue(tag); // tag
       /// dataLoggerSheet.getRange("D" + row).setValue(value); // value

    }

        catch(error) {
           Logger.log(JSON.stringify(error));
         }

         Logger.log("--- save_data end---");
          }

I've already tested the HTTP GET requests on other websites so there seems to be no problem with the device.
BTW this code (Apps Script) worked perfectly with nodeMCU with appropriate libraries and arduino code.
Please help me out.

What is the error?

please format your code properly ... the way it is now, the code indentation is awful, which makes the code unclear without doing copy and format


text:
Motor not switching with 2N3904
I have a small motor, it powers fine from the 3V3 and GND output of the arduino nano ble 33. However I need to be able to switch it on and off. My first attempt was to use an output pin, but that doesn't supply enough power. I'm trying to use a 2N3904 transistor (my first time attempting to use one, so sorry if I've done something stupid). I've tried wiring it as follows, but no luck:

Is this possible, or do I need something more substantial like a reed switch?

https://electronics.stackexchange.com/q/77262/6680

The motor draws 100 to 200 mA. From Figure 16 of the 2N3904 datasheet, the 100 mA curve shows an Ib of 10 mA and Vce of 0.35 V. This voltage drop is a large percentage of the supply voltage which reduces the voltage across the motor to 3.3 - 0.35 = 2.95 V which is at the limit of its specification, so consider using an N-channel MOSFET which has a much lower voltage drop across drain-source. Also, the motor requires a reverse-biased protection across its terminals.

If you use Logic Level UIS (Avalanche) rated MOSFET (check Vgs to be sure it is on) you will not need the diode. Remember the Arduino a Power Supply it is NOT! If you keep using the 3V from the arduino put more on order you will fry it in due time. I would guess you blew the gate of the 2N3904, you need a current limit resistor in series with the micro to base.

1st : you have to put an appropriate resistor between the output of your arduino and transistor Base pin

2nd : you have to connect you motor and biased transistor to >>>> a suitable power supply (which has enough current (Amps) on it's output)

you can use this circuit instead of yours :

3rd : don't forget to use the diode in the schematic; it protects transistors from you motor coil's spikes you can use 1n4147 ( it depends on the size of your motor but i think, it works for you ( i wasn't successful to take a look at your motor and it's specifications )

4th : ignore the number of transistor, you can use your transistor (2N3904) instead of it

5th :NOTICE : this circuit has a problem, you have to connect appropriate power supply and replace "arduino 5 volts" by the + of your power supply in this circuit schematic

good luck

If you are an electronic engineer, don't use an eletronics circuit that you grab from internet that has everything wrong with the design. 1) the resistor is too high, with the value, the Ibe is only (5-0.7)/10000=0.43mA, assume the DC current gain is 50, it will only capable of produce Ice of .43x50 = 21.5mA even with a correct 2N3904, this is more designed for driving a single LED, certainly not sufficient to drive a motor. 1N4007 is a retifier with very slow recovery time, not design for rapid recovery.

I mentioned that he can use appropriate resistor, and for diode, you are right, i edited the answer,i forgot this problem of 1n400X series, he can use 4147 one or others. As i said, he can use the appropriate values of resistor, i just take him an overall vision of his/her problem's solution


text:
Customizing system settings with defines?
I have written a library that contains a statically allocated buffer (f.g. struct taskList proc[TBL_SIZE];)
TBL_SIZE is a macro currently defined in my .h file.
I have heard that there's a way to set or reset the define statement inside the .ino file to customize this setting for some libraries, but I don't know how to do this myself, and by the time I realized that this was a problem I had forgotten what library allowed this setting.
This would be extremely useful as currently I have to edit my library every time I build a new project (or worse, am working on several at once with different settings).
My guess was a variant on an include guard, like this
#ifndef TBL_SIZE
#define TBL_SIZE 16 /*(or whatever)*/
#endif

block, but that failed to work. I tried it during a final project, so my memory is fuzzy from lack of sleep (and time, now), but I'm fairly sure I got an "undefined" error.
I don't know what this is called to search for it otherwise, so I'm hoping someone can help.

Here is more information about my specific issue:
In my .h (at the top, after the regular include guard):
#ifndef TBL_SIZE
#define TBL_SIZE 16
#endif

(Note that everything works if I just set this directly without the defines)
Further down the .h, inside my class:
struct task processes[TBL_SIZE];

In the main .ino file before the library includes:
#define TBL_SIZE 6
#include <CoRTOS.h>

Debug output of the build (I know from experience it built with 16 instead of 6 entries in that table from the memory size. The low memory warning is another big clue.)
Linking everything together...
"C:\\Users\\rdrag\\AppData\\Local\\Arduino15\\packages\\arduino\\tools\\avr-gcc\\7.3.0-atmel3.6.1-arduino7/bin/avr-gcc" -w -Os -g -flto -fuse-linker-plugin -Wl,--gc-sections -mmcu=atmega328p -o "C:\\Users\\rdrag\\AppData\\Local\\Temp\\arduino_build_258761/ECE554_ASP.ino.elf" "C:\\Users\\rdrag\\AppData\\Local\\Temp\\arduino_build_258761\\sketch\\ECE554_ASP.ino.cpp.o" "C:\\Users\\rdrag\\AppData\\Local\\Temp\\arduino_build_258761\\libraries\\CoRTOS\\CoRTOS.cpp.o" "C:\\Users\\rdrag\\AppData\\Local\\Temp\\arduino_build_258761\\libraries\\Adafruit_GFX_Library\\glcdfont.c.o" "C:\\Users\\rdrag\\AppData\\Local\\Temp\\arduino_build_258761\\libraries\\Adafruit_GFX_Library\\Adafruit_GFX.cpp.o" "C:\\Users\\rdrag\\AppData\\Local\\Temp\\arduino_build_258761\\libraries\\Adafruit_GFX_Library\\Adafruit_GrayOLED.cpp.o" "C:\\Users\\rdrag\\AppData\\Local\\Temp\\arduino_build_258761\\libraries\\Adafruit_GFX_Library\\Adafruit_SPITFT.cpp.o" "C:\\Users\\rdrag\\AppData\\Local\\Temp\\arduino_build_258761\\libraries\\Adafruit_BusIO\\Adafruit_BusIO_Register.cpp.o" "C:\\Users\\rdrag\\AppData\\Local\\Temp\\arduino_build_258761\\libraries\\Adafruit_BusIO\\Adafruit_I2CDevice.cpp.o" "C:\\Users\\rdrag\\AppData\\Local\\Temp\\arduino_build_258761\\libraries\\Adafruit_BusIO\\Adafruit_SPIDevice.cpp.o" "C:\\Users\\rdrag\\AppData\\Local\\Temp\\arduino_build_258761\\libraries\\Wire\\Wire.cpp.o" "C:\\Users\\rdrag\\AppData\\Local\\Temp\\arduino_build_258761\\libraries\\Wire\\utility\\twi.c.o" "C:\\Users\\rdrag\\AppData\\Local\\Temp\\arduino_build_258761\\libraries\\Adafruit_SSD1306\\Adafruit_SSD1306.cpp.o" "C:\\Users\\rdrag\\AppData\\Local\\Temp\\arduino_build_258761\\libraries\\SPI\\SPI.cpp.o" "C:\\Users\\rdrag\\AppData\\Local\\Temp\\arduino_build_258761\\libraries\\SparkFun_BME280_Arduino_Library-master\\SparkFunBME280.cpp.o" "C:\\Users\\rdrag\\AppData\\Local\\Temp\\arduino_build_258761/core\\core.a" "-LC:\\Users\\rdrag\\AppData\\Local\\Temp\\arduino_build_258761" -lm
C:\Users\rdrag\Documents\Arduino\libraries\CoRTOS\src/CoRTOS.h:38:7: note: array types have different bounds
 class cortos_class {
       ^
"C:\\Users\\rdrag\\AppData\\Local\\Arduino15\\packages\\arduino\\tools\\avr-gcc\\7.3.0-atmel3.6.1-arduino7/bin/avr-objcopy" -O ihex -j .eeprom --set-section-flags=.eeprom=alloc,load --no-change-warnings --change-section-lma .eeprom=0 "C:\\Users\\rdrag\\AppData\\Local\\Temp\\arduino_build_258761/ECE554_ASP.ino.elf" "C:\\Users\\rdrag\\AppData\\Local\\Temp\\arduino_build_258761/ECE554_ASP.ino.eep"
"C:\\Users\\rdrag\\AppData\\Local\\Arduino15\\packages\\arduino\\tools\\avr-gcc\\7.3.0-atmel3.6.1-arduino7/bin/avr-objcopy" -O ihex -R .eeprom "C:\\Users\\rdrag\\AppData\\Local\\Temp\\arduino_build_258761/ECE554_ASP.ino.elf" "C:\\Users\\rdrag\\AppData\\Local\\Temp\\arduino_build_258761/ECE554_ASP.ino.hex"
Multiple libraries were found for "Adafruit_GFX.h"
 Used: C:\Users\rdrag\Documents\Arduino\libraries\Adafruit_GFX_Library
 Not used: C:\Users\rdrag\Documents\Arduino\libraries\Adafruit-GFX-Library-master
Multiple libraries were found for "Adafruit_I2CDevice.h"
 Used: C:\Users\rdrag\Documents\Arduino\libraries\Adafruit_BusIO
 Not used: C:\Users\rdrag\Documents\Arduino\libraries\Adafruit_BusIO-master
Multiple libraries were found for "Adafruit_SSD1306.h"
 Used: C:\Users\rdrag\Documents\Arduino\libraries\Adafruit_SSD1306
 Not used: C:\Users\rdrag\Documents\Arduino\libraries\Adafruit_SSD1306-master
Using library CoRTOS at version 0.2.0 in folder: C:\Users\rdrag\Documents\Arduino\libraries\CoRTOS
Using library Adafruit_GFX_Library at version 1.10.7 in folder: C:\Users\rdrag\Documents\Arduino\libraries\Adafruit_GFX_Library
Using library Adafruit_BusIO at version 1.7.3 in folder: C:\Users\rdrag\Documents\Arduino\libraries\Adafruit_BusIO
Using library Wire at version 1.0 in folder: C:\Users\rdrag\AppData\Local\Arduino15\packages\arduino\hardware\avr\1.8.3\libraries\Wire
Using library Adafruit_SSD1306 at version 2.4.5 in folder: C:\Users\rdrag\Documents\Arduino\libraries\Adafruit_SSD1306
Using library SPI at version 1.0 in folder: C:\Users\rdrag\AppData\Local\Arduino15\packages\arduino\hardware\avr\1.8.3\libraries\SPI
Using library SparkFun_BME280_Arduino_Library-master at version 2.0.9 in folder: C:\Users\rdrag\Documents\Arduino\libraries\SparkFun_BME280_Arduino_Library-master
"C:\\Users\\rdrag\\AppData\\Local\\Arduino15\\packages\\arduino\\tools\\avr-gcc\\7.3.0-atmel3.6.1-arduino7/bin/avr-size" -A "C:\\Users\\rdrag\\AppData\\Local\\Temp\\arduino_build_258761/ECE554_ASP.ino.elf"
Sketch uses 28172 bytes (91%) of program storage space. Maximum is 30720 bytes.
Global variables use 1609 bytes (78%) of dynamic memory, leaving 439 bytes for local variables. Maximum is 2048 bytes.
Low memory available, stability problems may occur.

Define "failed to work". If the preprocessor sees a #define LISTSIZE before your file is included it would skip over your #define because it's been defined.

That was the goal. I'd want the earlier one (from the .ino) to override the one in the file.

I've added information. "Fails to work" means that it won't customize the array size. I misremembered the warning/error. Some sort of array mismatch complaint, but there isn't actually anything remotely array-related on that line...

the #define in ino will apply only for .h included in ino, not for the same .h included in other file. the #include directive makes the whole content of .h to be copied into the file with the directive

I was under the impression that the #define in the .ino file would override the .h file's default define entry for all items that included it, since it was the first use of it or something. That doesn't work?

Could you add more details about how the array is declared and defined? From your description, it sound like it is defined in the .h file. From the build output, it looks like it was declared in the .h and defined in a .cpp. Or maybe the .h was included in more than one source file.

The .h is included in two source files for this project IIRC - the .ino and the library's .cpp.  The array is a member of a class which is declared in the .h and populated by a member function that's defined in the .cpp. I believe the class itself is defined in the .cpp using extern.

I have heard that there's a way to set or reset the define statement inside the .ino file to customize this setting for some libraries, but I don't know how to do this myself

There are many ways to achieve what you want, you might not even need the #ifndef macro, use your library class construct to allow user to pass in the list size as an argument and but set the argument with a default value.
YourLibrary.h
class YourLibrary
{
private:
  size_t _userSize;
public:
  YourLibrary::YourLibrary(size_t listSize = 16) {
    _userSize = listSize;
  }
  ...
}

User's sketch .ino
#include <YourLibrary.h>

#define LIST_SIZE 32;

YourLibrary instance(LIST_SIZE);  // instance() would set the _listSize to 16

setup() {

}

loop() {

}

Doesn't that require allocating the item on the heap, though? It's setting the size of an array.

No it does not. Unless you use String object.

BTW, I read your updated post. There is no error as you mentioned regarding #ifndef, so what exactly is the problem and your question?

The problem listed in my post is that adding the #define in the root .ino file does not actually have any effect on the array size in the library. RE your answer, how does setting the variable inside the class as in your example create the array I need? I'm really trying not to dynamically allocate this table, so was that what you meant or is there some sort of magic I'm missing here?


text:
connecting a small motor to arduino using a transistor
I want to connect a small motor (water pump) to an arduino, and I am not sure about the circuit.
The pump is small, works with 3.3V, but consumes 0.1A so I decided to use a transistor. The one I have is BF547, an NPN type small transistor. It supports currents up to 100 mA.
I measured the hfe (beta) of the transistor, and it is 370. The Vcc is 3.3V, and the current through the motor is 0.1 A, therefore:
A. the Ib equals to Ic/hfe = 0.1A/370 giving Ib = 0,00027A
B. with the Vb at 3.3V(pin voltage) and Vbe at 0.7 (datasheet) the Rb = (Vb-Vbe)/Ib = 9558 Ohm (10kOhm)
My questions are:

Did I calculate the base resistance correctly?
Do I need any additional resistor for the collector, next to the pump? Is it possible that more current flows through the collector-emitter?
According to the datasheet of BF457 100mA is the max Ic it can take. Should I limit the pump by adding a small (10 Ohm) resistor to it (33 Ohm[motors resitance] + 10 Ohm for 3.3 V gives a current of 76 mA)

I am attaching the schematics (linear voltage regulator is there only to stabilise the Vcc provided by an old dc power source I found)
Thanks a lot for any suggestions!

use a MOSFET for switching loads; cooler, simpler, more powerful, etc.

I like your thought process (even though it might not be completely correct), I've seen how little thought were put in for such simple circuit design in the Arduino community, including from some Youtuber celebrity who teaching Arduino and claims to have an EE degree.
BF547 is an RF amplifier transistor, not for switching application, it would be better to use an NPN transistor such as 2N3904 which is designed for switching application and has a Ice of 200mA.
Your resistor value is too high. If your motor is designed to operate at 100mA 3.3v condition, you would want your driver to provide AT LEAST that current. Assuming your are driving the transistor with 5V out from an Arduino, a 1k bias resistor would limited the Ibe to (5 - 0.7Vbe)/1000=4.3mA, take a very conservative DC current gain of 30 (it typically in the range of 30 - 80 for switching transistor, and hfe could be in the range of 100 - 300 when frequency go up, but this will not be the case for Arduino even you drive the motor using PWM), which will capable to deliver Ice of 4.3 x 30 = 129mA. This should meet your Motor requirements.
You would need a protection diode connected between 3.3V and collector with its cathode connect to 3.3V and its anode connect to the collector of the transistor. An 1N4148 (max If=200mA) would be okay for this specific motor, or even better, use any Schottky diode with current and voltage limit higher than your application).

4.6V - 1.2V (2 diode drops of 0.7V) = 3.4V, close enough for the motor if you are using a MOSFET as a driver. You can use a UIS rated MOSFET with a Vgs of less than 4 and it will work perfectly. the transistor will give you an additional voltage drop of about 0.7 Volts and needs a base resistor. If you want to guarantee the motor will not start during reset and setup() add a 10K resistor from the port pin to ground.


text:
Read from lux hangs in bright light
I am using VMEL6040 sensors and occasionally under bright light the read can hang, rather than using a wdt to recover I would like to ask some questions about the library.
as for debugging the sensors run stabley (several days at reads every 250 ms) in low light, but over 6k lux they can crash.
I am using wire.h here
in the header
TwoWire *_i2cPort;

the read value calls the ReadRegister function:
uint16_t SparkFun_Ambient_Light::_readRegister(uint8_t _reg)
{

  uint16_t _regValue;

  _i2cPort->beginTransmission(_address);
  _i2cPort->write(_reg); // Moves pointer to register.
  _i2cPort->endTransmission(false); // 'False' here sends a restart message so that bus is not released
  _i2cPort->requestFrom(_address, static_cast<uint8_t>(2)); // Two reads for 16 bit registers
  _regValue = _i2cPort->read(); // LSB
  _regValue |= uint16_t(_i2cPort->read()) << 8; //MSB
  return(_regValue);

}

is there a reason they are not checking the return of the _i2cPort->endTransmission(false);call? I am wondering if I should check that and not call the requestFrom if it does, i.e.:
uint16_t SparkFun_Ambient_Light::_readRegister(uint8_t _reg)
{

  uint16_t _regValue;

  _i2cPort->beginTransmission(_address);
  _i2cPort->write(_reg); // Moves pointer to register.
  if (_i2cPort->endTransmission(false) == 0) { // 'False' here sends a restart message so that bus is not released
      _i2cPort->requestFrom(_address, static_cast<uint8_t>(2)); // Two reads for 16 bit registers
      _regValue = _i2cPort->read(); // LSB
      _regValue |= uint16_t(_i2cPort->read()) << 8; //MSB
      return(_regValue);
  }
  else
      return 0;
}

Or could my error be from the static casting do int?

I thought a static_cast was just a compile time cast; I don’t see how casting 2 to a byte would cause an error if that’s what the call expects (which IIRC it is).

static_cast<uint8_t>(2) is not necessary, if you read Wire source, you will see multiple overload functions to handle the type casting. 2) to cast a uint8_t1 to a uint16_t, it is (uint16_t) _i2cPort->read(), not uint16_t(_i2cPort->read() . 3) shouldn't uint16_t _regValue; ` be declared at your Class level? your code now declared it as a local variable, and you are returning a local variable's value, which may no longer exist (out of scope) when the program return from the function.

@hcheung: Returning a local variable's address would be an error. Returning it's value is perfectly fine.

the full library im using can be found here:
https://github.com/sparkfun/SparkFun_Ambient_Light_Sensor_Arduino_Library

I think i just figured it out _i2cPort->read(); returns a -1 on error duh

so I think I got it, the problem was that on a fail wire.read() returns an int -1
when that gets converted to a unint16 its a big number then it gets left shifted and overflows
the solution was:
uint16_t SparkFun_Ambient_Light::_readRegisterLight(uint8_t _reg)
{
    int lsb;
    int msb;

    _i2cPort->beginTransmission(_address);
    _i2cPort->write(_reg); // Moves pointer to register.
    if (_i2cPort->endTransmission(false) == 0) { // 'False' here sends a restart message so that bus is not released

        unsigned long tstamp = millis();
        while ((_i2cPort->available() < 2) && ((millis() - tstamp) < 10));

        if ((_i2cPort->available() < 2)) {
            _i2cPort->requestFrom(_address, 2); // Two reads for 16 bit registers
            lsb = _i2cPort->read(); // LSB
            msb = _i2cPort->read(); //MSB

            if ((lsb >= 0) && (lsb <= 256) && (msb >= 0) && (msb <= 256)) {
                _regValue = lsb + msb * 256;
            }
        }

        return(_regValue);
    }
    else
        return _regValue;//last read
}

This contains some extra error handling I added, but will leave in such as:

timeout on waiting for a response
checking on properly closing the bus in end transmission
checking for errors from the read

I didn't do error handling as I would need to rewrite the whole library, and for my application repeating the last reading is sufficient.


text:
How can I read the Timer direction in phase correct PWM?
I have had to use Timer0 with phase correct PWM and a prescaler of 1. This results in a 32khz PWM frequency and obviously impacts millis, delay and micros. (Timer1 and Timer 2 are also in use so changing to those is not an option)
millis() is trivial to work around - multiply by 32 as the TOV0 interrupt handler is called 32 times more frequently (subject to overflow of course)
micros() is somewhat trickier - as normally it is the Timer0 overflow count (as used in millis() though shifted in this case) plus the current value of TCNT0. That works great when TCNT0 is increasing only and resetting to 0 after MAX - but in phase correct PWM it could be going upwards or downwards.
I think what I need to do is find the direction the Timer is currently using - but pouring over the datasheet for the ATmega328P I can't seem to find a way to do so...
Is there a way of reading this, eg from a register I can interrogate for it?
Alternatively can anyone else think of a way to get microsecond (or close - 10 microsecond would be good enough) resolution when all timers are in phase correct mode?
I'm considering a fall-back of reading TCNT0 twice and deriving it from that - with a prescaler of 1I am assuming it is not possible to read it twice faster than it could change - however I'd prefer a neater solution if there is one.

I'm afraid that this not simple, or possible at all. Since every code to check for the direction takes some clocks, you need to count them and take them into account. Additionally, if you use interrupts, you would need to disable them in this critical part. -- Do you really need micros()?

Your fallback solution is the best one, and your assumption is correct: with the prescaler at one, you can't read the counter twice faster than it changes.

Maybe you can use the OC0x register. I don't have an atmega328p at hand now, but you can test it out. The relevant part in the datasheet: In non-inverting compare output mode, the output compare (OC0x) is cleared on the compare match between TCNT0 and OCR0x while upcounting, and set on the compare match while downcounting. In inverting output compare mode, the operation is inverted. (header 14.7.4 Phase Correct PWM Mode)

Use a flag to keep tabs on it

You could sidestep the problem and use _delay_us instead. The only downside is that _delay_us doesn't account for time spend inside ISRs, as it just does a bunch of NOP instructions.

@Swedgin, this question had been asked on another stackexchange site and I had the same thought.  Or same so far as I can tell.  I experimented with this idea yesterday, except using timer1 with prescaler 1024, because this gives about 4 seconds to a swing from one end of the range to the other.  For whatever reason it didn't seem to be setting output compare interrupt flags.  But, I got interrupted by something else before looking into why.

I decided to go with the inspect method and modified wiring.c accordingly - may not fit everyone's use case but solves mine (along with a couple of tweaks changing the #define's to volatile variables and adding a setter for them.
micros updated to:
unsigned long micros() {
  unsigned long m;
  uint8_t oldSREG = SREG, t1, t2;

  cli();
  m = timer0_overflow_count;
#if defined(TCNT0)
  t1 = TCNT0;
  t2 = TCNT0;
#elif defined(TCNT0L)
  t1 = TCNT0L;
  t2 = TCNT0L;
#else
  #error TIMER 0 not defined
#endif

#ifdef TIFR0
  if ((TIFR0 & _BV(TOV0)) && (t1 == timer0_phase_correct ? 0 : 255))
    m++;
#else
  if ((TIFR & _BV(TOV0)) && (t1 == timer0_phase_correct ? 0 : 255))
    m++;
#endif

  SREG = oldSREG;

  if (timer0_phase_correct && t1 > t2){
    t2 = 510 - t2;
  }

  return (m * us_per_timer0_overflow) + (clockCyclesToMicroseconds(timer0_prescale * t2));
}

Note: that won't work with just that change - but changing wiring.c is not a topic I want to go into discussion of and anyone capable of that can easily infer the other changes from what I've put above. Here be dragons.

Where is timer0_phase_correct defined?


text:
Playing stereo sound using AudioOutI2S and Splitting channels correctly
I have an Arduino MKR Zero with an UDA1334 I2S module, alongside 2 Speakers and I am trying to play Stereo sound. So far everything seems to work well, connections are also properly done, and i can play wav files. But i also want to be able to play sound either on the right channel only or sometimes only on the left channel. I tried to use audacity to make sounds only on the right channel for example, but when i play the .wav file, i still get the sound on both speakers. How can i fix this please? Is there any syntax to play sound only on the right channel? Thank you.
PS. TestR.wav is a only on the right channel.
#include <SD.h>
#include <ArduinoSound.h>

const char filename[] = "testR.wav";
SDWaveFile waveFile;

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

   Serial.print("Initializing SD card...");
   if (!SD.begin(28)) {
    Serial.println("SD card initialization failed!");
    return;
  }
  Serial.println("SD card is valid.");
  waveFile = SDWaveFile(filename);   // create a SDWaveFile
//  Serial.println(typeof(waveFile));
 if (!waveFile) {
    Serial.println("wave file is invalid!");
    while (1); // do nothing
  }

// print out some info. about the wave file

Serial.print("Bits per sample = ");
Serial.println(waveFile.bitsPerSample());
long channels = waveFile.channels();
Serial.print("Channels = ");
Serial.println(channels);
long sampleRate = waveFile.sampleRate();
Serial.print("Sample rate = ");
Serial.print(sampleRate);
Serial.println(" Hz");
long duration = waveFile.duration();
Serial.print("Duration = ");
Serial.print(duration);
Serial.println(" seconds");

AudioOutI2S.volume(100);

 if (!AudioOutI2S.canPlay(waveFile)) {
    Serial.println("unable to play wave file using I2S!");
    while (1); // do nothing
  }
 Serial.println("starting playback");
  AudioOutI2S.play(waveFile);
}

void loop() {
  if (!AudioOutI2S.isPlaying()) {
    Serial.println("playback stopped");
    while (1);
  }
}

Can you at least, at the very minimum, post your code?

Sure, there you go! @Swedgin.

I went throught that library and I doens't seem like there is functionality to do what you want. channels() returns hardcoded 2 lol (I think that's the left and right channel). You'll have to write your own function to split the two. I don't know how SDWaveFile looks like (how the data is presented), so can't help you with that.

Thank you @Swedgin


text:
Is there anything wrong with this code
Hi I'm pretty new to cpp.
Could someone review my code and explain any pitfalls or problems?
Below is the code and an example to read from a flow meter with a hall sensor.
Thanks in advance.
Greg
    /** example
    #include "flow.h"
    Flow f(3);
    Flow f2(4);
    volatile unsigned int counter;
    void flow_counter() // ISR
    {
          // Increment the pulse counter
          counter ++;
    }

    void setup()
    {
      f.start(); //using default ISR
      f2.assign_isr(&flow_counter);
      f2.assign_counter(&counter);
      f2.start();
    }

    void loop()
    {
     Serial.printf("flow rate on 3 = %f \n",f.rate());
     Serial.printf("flow total = %dml %f%% of 500ml \n",f.total_ml(),f.percent(500));
     Serial.printf("flow rate on 4 = %f \n",f2.rate());
     delay(1000);
    }

    */

    #include <math.h>
    #include "Arduino.h"

    volatile unsigned int flowPulseCounter;
    void flowCounter() // ISR
    {
          // Increment the pulse counter
          flowPulseCounter ++;
    }

    class Flow{
      public:
        Flow(uint8_t pin)
        {
          if(flowPin==254)
           flowPin = pin;
        }

        void assign_isr ( void (*isr)()){ this->flowISR = isr; };
        void assign_counter (volatile unsigned int * counter ){ this->counter = counter; };
        void assign_pin(uint8_t pin){ flowPin = pin; };

        void  set_calibration_factor( float factor ) { this->calibrationFactor = factor; };
        float get_calibration_factor( ) { return this->calibrationFactor; };

        uint8_t retrieve_pin(){ return flowPin; };

        void start()
        {
          detachInterrupt(digitalPinToInterrupt(this->flowPin));
          *this->counter = 0; // counter is a pointer so * assigns the value at that address to 0
          this->flowRate = 0;
          this->flowMillilitres = 0;
          this->flowMilliseconds = millis();
          pinMode(this->flowPin, INPUT_PULLUP);
          this->running = true;
          attachInterrupt(digitalPinToInterrupt(this->flowPin), this->flowISR, FALLING);
        }

        void calculate()
        {
          if(this->running)
          {
            this->flowRate = ((1000.0 / (millis() - this->flowMilliseconds)) * ( *this->counter )) / this->calibrationFactor;
            this->flowMilliseconds = millis();
            // convert to millilitres.
            this->flowMillilitres = (this->flowRate / 60) * 1000;
            // Add the millilitres to the cumulative total
            this->totalMillilitres += this->flowMillilitres;
          }
        }

        void stop()
        {
          detachInterrupt(digitalPinToInterrupt(flowPin));
          this->calculate();
          this->running = false;
          pinMode(this->flowPin, INPUT_PULLUP);
        }

        bool is_max( uint32_t millilitres )
        {
          this->calculate();
          return (this->totalMillilitres >= millilitres) ? true : false;
        }

        float percent( uint32_t millilitres )
        {
          this->calculate();
          return (float)((double) this->totalMillilitres / (double) millilitres)  * 100.0;
        }

        float rate ()
        {
          this->calculate();
          return this->flowRate;
        }

        uint32_t total_ml()
        {
          this->calculate();
          return this->totalMillilitres;
        }

      private:
        uint8_t flowPin=0;
        uint32_t flowMilliseconds = 0;
        float flowRate=0;
        uint32_t flowMillilitres = 0;
        uint32_t totalMillilitres = 0;
        float calibrationFactor = 4.5;
        bool running = false;
        void (*flowISR)() = &flowCounter;
        volatile unsigned int * counter = &flowPulseCounter;
    };

Why is the entire first section commented out?

@chrisl: It's a library. The comment block is an example of how to use it.

The only problem I can see is in your use of the counter variable. This is a volatile variable that is incremented in an interrupt routine and read from the main loop context.  The variable is "non atomic" in that it is made up of a number of smaller bytes (at least on 8 bit Arduinos it is) which means it takes multiple sequential instructions to read it from memory.
At any point during that sequence the interrupt could trigger and modify the value, corrupting your data.
You should always use a critical section around any accesses to variables that are modified inside interrupt routines, such as:
noInterrupts(); // Disable interrupts
uint32_t currentCount = this->counter; // Grab the current count
interrupts(); // Re-enable interrupts

// Do things with currentCount instead of this->counter

re:You should always use a critical section around any accesses to variables that are modified inside interrupt routines, such as:
As the variable is volatile and thus explicitly read every time why is this necessary. Killing the interrupts breaks so much other stuff.

Because, as I said, it is not atomic. That means that the variable can change while it is being read because it is not one single operation but a sequence of smaller operations.

And you always keep the critical section as short as possible so as to reduce the impact of temporarily disabling interrupts, which in this instance should be zero impact.

Sorry @Majenko I was rushing out to work and didn't read your comment properly.

Here is what I propose as a solution. I am happy to be wrong though.           uint32_t this_count = count;             uint32_t count_check = count;             if((this_count>>3)!=(count_check>>3)               return -0.0; // I like this return as it allows for valid 0 values to be returned as well              // valid read ie. all but the last 3 bits match allowing some advancement in the counter

While I understand your thinking I don't totally agree.
Yes it may be correct for an 8bit single thread environment as are many AVRs it is not always the case.
I don't like the idea of having an interrupt disable section hidden inside a class.
Working with the esp32 (ie. multiple cores and a very simple multi-thread system) the possibility of breaking many things increases.
Also if I run several instances of the class they could interrupt each others counters.

@Yardie: 1. If you publish a library that only works on the ESP32, you should document this limitation, and have a conditional #error directive in the header that prevents anyone from using it on another platform. 2. This critical section is so tiny it will have no impact. If the pulses come so fast that it does have an impact, your program will be unable to process them anyway.

@Yardie It's not "my" thinking: critical sections have been around since the dawn of computing. Nothing in your question says you want to use an ESP32, and since this is the Arduino site we have to assume, unless you tell us otherwise, that you are using an Arduino. And since the majority of Arduino boards are 8 bits it's safe to assume that a critical section will be required. If your do happen to want to use some other board then you have to take the action appropriate to that board. For a 32-bit board it may well be that the operation is atomic and no action ...

... is required. But of you want to publish your library for others to use you cannot assume that they will all want to use an ESP32. You will need to take appropriate steps to craft a suitable critical section for those boards that require them (all non-32 bit boards for sure, and maybe some 32-bit ones as well). For that defining your own macros that change depending on what is being compiled for will be useful. Also depending on the target architecture you may be able to use a more fine grained critical section whereby you only disable the interrupt that you are working with, rather ...

... that disabling them globally. But in general, to allay your fears about critical sections, when interrupts are disabled any interrupts that would occur would generally be deferred until the interrupts are re-enabled again, at which point they will then be handled. And if your critical section is only a handful of clock cycles long and interrupts only occur with thousands of clock cycles between them then the impact of the critical section is going to be non-existent.

Ok thanks guys.

Yes you are right however code for Arduino now needs to consider the ESP. I am working with both and write code primarily for myself. If I was to publish the code this post is the only place I would publish it. I have gained a lot from free software and like to put back when I can. That's all. I love my ATTinies and want to write something that works for both. I was simply trying to cover both possibilities. Stopping the whole interrupt system to read a variable has always bothered me. However reading your last comment Majenko that does allay this and clarify my misconception

I have investigated enough low level code to see some rather nasty assumptions and oversights. I wanted to avoid that in my code even if it is just for me.

Anyway thanks heaps everyone your help has been fantastic and very enlightening. Sorry if I have offended anyone in any way. It was never intended. No one was born with this knowledge and we all travel different paths. Thank you for sharing your knowledge

Edgar I could never publish this code anyway. It's basically your code now anyway. :) Thanks. I now have a simple library to easily add a flow meter to an attiny or an esp32. That's all I wanted. Oh and a deeper understanding of the issues involved as well.

Here are some random comments from looking at the code.
First issue, which is more about the example than the library itself:
there is no Serial.printf() in the standard Arduino cores. Yes, it is
provided by some alternate cores, and it is a shame it is not available
in the Arduino ones, but that's how it is.
In the constructor, there is if(flowPin==254). Why this condition?
flowPin is initialized to zero, so it would seem the condition should
always be false.
As a matter of style, you can remove all the this-> from the methods.
It is implicit anyway.
For the sake of naming consistency, I would rename retrieve_pin() as
get_pin(), and all the assign_*() method as set_*().
It is not useful to detachInterrupt() right before
attachInterrupt(), as the latter implies the former.
In calculate(), avoid calling millis() twice. You have no guarantee
that both calls will return the same value and, if they do not, the
timing calculations will be off. Also, this function will fail badly
(division by zero) if called twice within the same millisecond.
It makes no sense to convert a flow rate to milliliters. Do you mean
milliliters per minute? Per second? In any case, you here converting a
rate to another unit, but it is still a flow rate.
The computation of totalMillilitres is wrong: it is incremented by a
flow rate. It should instead be incremented by a product rate × time. Or
better yet: compute it from the pulse count, without going through the
rate. Otherwise you are computing a numerical derivative (to get the
rate) only to integrate it later (to get a total volume). This extra
computations serve no purpose other than accumulating rounding errors.

Edit: Thinking further about this program, I found a few more things
that I think could be improved. A couple of minor points an one not so
minor.
One of the minor points is that begin() would be a better name for
start(), for consistency with most other Arduino libraries.
Another one is that there are a couple of methods that have no business
being in the class: is_max() and percent(). They are trivial
calculations that are in no way related to handling a flow meter. As a
user of the library, I would rather write
if (flow.total_ml() >= threshold_volume) ...

than
if (flow.is_max(threshold_volume)) ...

as the former is way clearer and easy to understand.
The more serious point is about the handling of multiple flow meters.
The first one is completely handled by the library, which is nice.
However, for the second one, the user has to provide the lowest level
bricks. The user of a library should not have to handle himself such
low-level details. Thus, I think both the counter variable and the ISR
function should be handled by the library, as members of the Flow
class.
I am aware this creates some difficulties. In order to be attached to an
interrupt, the ISR should be a static method of the class. In order for
this method to access the counter, that counter should be a static
member. In order for each flow meter to have its own counter, we must
have a separate class for each one.
I found a solution that I think is elegant enough: have Flow be a
class template, parametrized by the pin number. This creates a
separate class for each flow meter. In order to avoid code duplication,
these classes could be almost empty shells that delegate as much as
possible to a handler which is a common, regular class.
Here is what that “handler” class could look like. It has everything
but the ISR:
class FlowMeterHandler {
    // Everything here is private, only accessible to the Flow class.
    template<uint8_t pin> friend class Flow;
private:
    void begin(uint8_t pin, void (*isr)()) {
        attachInterrupt(digitalPinToInterrupt(pin), isr, FALLING);
    }
    float flow_rate() {
        uint32_t now = millis();
        if (now - last_millis >= 10) {
            uint32_t this_count;
            noInterrupts();
            this_count = count;
            interrupts();
            last_flow = calibration * (this_count - last_count)
                                    / (now - last_millis);
            last_millis = now;
            last_count = this_count;
        }
        return last_flow;
    }
    // + other methods...
    volatile uint32_t count = 0;
    uint32_t last_count = 0;
    uint32_t last_millis = 0;
    float last_flow = 0;
    float calibration = 1e3 / 4.5;
};

I've written the methods inline, but you could also put the
implementations in a separate .cpp file.
And here is the template class. Save for the ISR, it forwards everything
to the handler.
template<uint8_t pin> class Flow {
public:
    static void begin() { handler.begin(pin, isr); }
    static float flow_rate() { return handler.flow_rate(); }
    // other methods also forwarded to the handler...
private:
    static FlowMeterHandler handler;
    static void isr() { handler.count++; };
};

template<uint8_t pin> FlowMeterHandler Flow<pin>::handler;

Note that the class has no instance data: everything in it is static.
Here is how this would be used:
Flow<3> f1;
Flow<4> f2;

void setup()
{
    f1.begin();
    f2.begin();
}

void loop()
{
    Serial.print(F("flow rate on 3 = "));
    Serial.println(f1.flow_rate());
    Serial.print(F("flow rate on 4 = "));
    Serial.println(f2.flow_rate());
    delay(1000);
}

Thank you I have to go to work now but will check this properly after. Thanks Edgar

Edgar this is gorgeous very elegant. I still don't like the
noInterrupts();
this_count = count;
interrupts();

the if(flowPin==254) was left over from an earlier attempt at multiple instances which I didn't finish fleshing out sorry that was a red herring

I also like your thinking withif (flow.total_ml() >= threshold_volume) makes everything very simple.

@Yardie: Re “I still don't like the noInterrupts(); ...”: avr-gcc has the ATOMIC_BLOCK() macro which encapsulates this interrupt masking in an arguably semantically clearer way. It is, however, AVR-specific, and thus not suitable in a wider Arduino context. AFAIK, the Arduino core provides nothing better than noInterrupts()/interrupts() for atomic access to variables.

Ok so if anyone is interested here is what I ended up with
/*
  this is yet to be varified but comes from the following links
  *
  https://www.bc-robotics.com/tutorials/using-a-flow-sensor-with-arduino/

  "These are not able to monitor a flow of less than 1 liter per minute or in excess of 30 liters per minute.
  The sensor is rated to a Maximum of 2.0MPa (290 PSI) "
  and
  every rotation means 2.25mL of fluid has passed the sensor

  another is

  https://diyhacking.com/projects/FlowMeterDIY.ino
  "// The hall-effect flow sensor outputs approximately 4.5 pulses per second per
   // litre/minute of flow.
  "

  then finally

  https://arduino.stackexchange.com/questions/84578/is-there-anything-wrong-with-this-code

  I make no personal claim to any of this code. It is simply my version of Edgar's version.
  Thanks Edgar
  *
  *
  *
  * I have used start and stop as they signify the start and stop of the process
  * the class begins when it starts and has no end the isr stays linked to the class for the duration
  * and start simply attaches the interrupt to the isr
  * stop simply calculates the total volume and detaches the interrupt.
  *
  * as flow rate related to time
  * just set your own start time
  * read the total_ml
  * then after your own predefined time
  * read the total_ml again
  * and work out the flow rate from that.
  */

class FlowMeterHandler {
  // Everything here is private, only accessible to the Flow class.
  template<uint8_t pin> friend class Flow;
private:

  void start(uint8_t pin, void (*isr)())
  {
    noInterrupts();
    count = 0;
    interrupts();
    attachInterrupt(digitalPinToInterrupt(pin), isr, FALLING);
  }

  void stop(uint8_t pin)
  {
    detachInterrupt(digitalPinToInterrupt(pin));
  }

  unsigned int count_is()
  {
    unsigned int this_count;
    noInterrupts();
    this_count = count;
    interrupts();
    return this_count;
  }

  volatile unsigned int count = 0;
  unsigned int ul_per_tick = 2250;

};

template<uint8_t pin> class Flow {
public:
    static void start() { handler.start(pin, isr); }
    static void stop() { handler.stop(pin); }
    static unsigned int total_ul() { return handler.count_is() * handler.ul_per_tick; }
    static unsigned int total_ml() { return ( handler.count_is() * handler.ul_per_tick ) / 1000 ; }
    static void set_ul_per_rotation( unsigned int ul) { handler.ul_per_tick = ul; }
private:
    static FlowMeterHandler handler;
    static void isr() { handler.count++; };
};

template<uint8_t pin> FlowMeterHandler Flow<pin>::handler;

the example ino looks like this
#include "flow.h"
Flow<3> f1;
Flow<4> f2;

void setup()
{
    f1.start();
    f2.start();
}

void loop()
{
    Serial.print(F("So far volume on 3 = "));
    Serial.println(f1.total_ml());
    Serial.print(F("and the volume on 4 = "));
    Serial.println(f2.total_ml());
    delay(1000);
}

Compiles cleanly on all my boards.
Runs ???
Any other suggestions will be gratefully received.
Thanks.
Greg

Note that it is not useful to store total_ml inside FlowMeterHandler, as it is only ever used right after being set. That could instead be a local variable of ml(), or even be removed altogether: float ml() { return count_is() * ml_per_tick; } Also, it is not useful to call ml() from stop().

Edgar thanks yep you are totally correct. They were unfinished/unnecessary ideas. Don't like redundant code either. I guess I've gotten sloppy self debugging for so long. These are the things I usually find months/years later. Why the hell did I do that? I have asked myself many times. Nice to have someone looking over my shoulder for a change. I changed the code tosuit.

probably could have just done return handler.count_is() * handler.ml_per_tick; in the template.

getting rid of the floats could speed it up a little. Using microlitres instead of ml.

It's hard to answer without any description of the actual problem.
On the top of my head, with that much code i'd consider starting off by creating a separate class declaration, and write your member definitions outside. It will make the code way more manageable, and easier to troubleshoot.
https://www.learncpp.com/cpp-tutorial/class-code-and-header-files/
Also, you have several include statements in at least two different places. They usually go first in a file, along with include guards. If your code consists of separate files, please make that clear to readers.

Re: the includes - I thought that at first too, until I noticed the first includes are inside a big comment.

I see it now. How do you make the snazzy color formatting, by the way?

You wrap it in something I can't type here ;) - backtick-backtick-backtick-c++ and backtick-backtick-backtick

I added the language specifier after the tripple-ticks in the question.  Seemed to have tripped enough people.  Sometimes without it the system doesn't syntax highlight or chooses the wrong language type.  You can see in the difference in the edit history.

```c++ [code]```

Excellent that is exactly the sort of answers I was after thankyou. The static ISR issue was particularly anoying to me.

@Erik sorry I thought the  /** example part and having it commented out would make it clear enough

Thank you @timemage for adding the language specifier. It certainly helps clarify the question


text:
LEDs not lighting up even though current is flowing through them, problem with ground?
I'm using a 74HC595N shift register to light up 8 LEDs but for some reason they won't turn on even though current is flowing through all of them. I provided an image of my circuit below, there is a test LED for checking current flow:

I am using a 9A103G resistor network to connect all the LEDs to a common ground. I have tried this with 8 individual 330 ohm resistors in the past but the result is the same, and every time the problem was with the ground wire, current is not flowing through it even though all the resistors I've used showed that current was flowing through them (see below):

The following image shows the same test LED not lighting up when connected to the common ground pin of the resistor network:

I could use some help fixing this issue because it is preventing me from using shift registers for future projects (this only happens when I use shift registers) - I would like to know what is causing this problem so I can avoid it later on. Thanks in advance!

You're short circuiting your LEDs with the breadboard. Rotate them 90°.

That was the problem!! Thank you so much! I forgot about the columns.

Good pictures by the way.

(Just to illustrate what Majenko is saying.)
This is the inside of a breadboard:

All your connections are on one side of that; you've tied everything to a single point.

Yes you're right, thank you


text:
Arduino with LCD Display does not reset/restart/start on connection to power
A friend and I have been working on an Arduino Sketch that does a request to a local API, parses that data and prints it out on an LCD Display.
When we upload the sketch to the Arduino it does exaclty what it should and shows the following on the LCD Display:

But when we disconnect the Arduino from the PC and reconnect it to the PC (or to any other power source), the following shows up on the LCD:

It seems as if the Arduino simply does not restart the Sketch and stays idle, while giving the LCD a weird output. When we open the Serial Monitor, in the Arduino IDE, the Arduino reboots and the correct information shows up again. Pressing the reset button on the Arduino itself did not work and seems to do nothing.
When trying other examples (e.g. Blink) it does restart on reconnecting to the PC, so it seems that the problem lies with our code.
Here is our full code:
#include <SPI.h>
#include <WiFiNINA.h>
#include <ArduinoJson.h> // Library to deserialize JSON
#include <Wire.h> // Library for I2C communication
#include <LiquidCrystal_I2C.h> // Library for LCD

LiquidCrystal_I2C lcd = LiquidCrystal_I2C(0x27, 20, 4);

char ssid[] = "WifiSSID";
char pass[] = "WifiPassword";
bool reading = false;

int refreshRate = 5000;

int status = WL_IDLE_STATUS;
IPAddress server(192,168,1,201);

WiFiClient client;

char json[512];
StaticJsonDocument<512> doc;

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

  memset(json, 0, sizeof json);

  lcd.init();
  lcd.backlight();

  lcd.setCursor(4, 1);
  lcd.print("CONNECTING..");
  status = WiFi.begin(ssid, pass);

  if (status != WL_CONNECTED) {
    while(status != WL_CONNECTED) {
      Serial.println("Retrying connection in two seconds...");
      delay(2000);
      status = WiFi.begin(ssid, pass);
    }
  }
  else {
    lcd.setCursor(0, 1);
    lcd.print("                    ");

    Serial.println("Connected to wifi");
    Serial.println("\nStarting connection...");
    sendRequest();
  }
}

void loop() {
  // if there are incoming bytes available
  // from the server, read them and print them:
  if (client.available()) {
    char c = client.read();
    if (c == '[') {
      reading = true;
      memset(json, 0, sizeof json);
    } else if (c == ']') {
      reading = false;
      printJson();
    } else if (reading) {
      int len = strlen(json);
      json[len] = c;
      json[len+1] = '\0';
    }
  }

  // if the server's disconnected, stop the client:
  if (!client.connected()) {
    client.stop();
    delay(refreshRate);
    sendRequest();
  }
}

void sendRequest() {
  if (client.connect(server, 80)) {
      Serial.println("Connected to server. Requesting data...");
      client.println("GET /api/v1/smartmeter?json=object&limit=1&round=on HTTP/1.0");
      client.println();
    }
}

void printJson() {
  DeserializationError error = deserializeJson(doc, json);

  if (error) {
    Serial.print(F("deserializeJson() failed: "));
    Serial.println(error.f_str());
    return;
  }

  int energy = doc["CONSUMPTION_W"];
  float gas = doc["CONSUMPTION_GAS_M3"];
  Serial.println(json);
  Serial.println(energy);
  Serial.println(gas);

  lcd.setCursor(0, 0);
  lcd.print("CONSUMPTION ENERGY:");
  lcd.setCursor(0, 1);
  lcd.print(energy);
  lcd.setCursor(8, 1);
  lcd.print("WATT");

  lcd.setCursor(0, 2);
  lcd.print("CONSUMPTION GAS:");
  lcd.setCursor(0, 3);
  lcd.print(gas);
  lcd.setCursor(8, 3);
  lcd.print("M3");
}

Would any of you maybe know why the Arduino refuses to restart on reconnecting to the PC or a power source, and how to fix it?
Thanks in advance!

You've tagged the question with both nano and arduino-nano-33-iot, but I'm guessing between the two you're using the latter, because on Arduinos with native USB (not a plain Arduino Nano) while (!Serial) continue; waits for a serial connection, e.g. Serial Monitor, to be connected.
This doesn't happen when you're on a power supply, or just connecting it to a machine without opening the port.
If you want blink an led inside this loop to see that it is in fact stuck there.

Hey mage! We removed the while (!Serial) continue; from the code and it works perfectly now! Thanks so much for the quick answer. Cheers!


text:
SPI synchronization with Arduino DUE and ADIS16364 IMU
I'm trying to use an Arduino Due to interface with an ADIS16364 IMU from Analog Devices (product info here) via SPI.
There are two modes for retrieving the measurements from this particular IMU (six 16 bit values, 3 acc, 3 gyros):

The first mode is, if I'm not wrong, the standard one with SPI, in which each successive transfer command retrieves the last data requested and indicates which one should be retrieved next.

The second possibility is a so called "burst mode". For this one you have to request the 0x3E00 register. After that, the IMU will burst out the six measurements (plus a few other bits of information like temperature and supply voltage). From the specs sheet:

The problem is, I can not manage to make the Arduino read the data using this burst mode. This is the code I'm using to test the communication:
#include <SPI.h>
#define SerialBT Serial2

short supply, xgyro, ygyro, zgyro, xacc, yacc, zacc, xtemp, ytemp, ztemp, aux;
volatile byte fDataIMUtoRead = 0;
int pauseBetweenTransfers;

void setup() {

  SerialBT.begin(230400);

  pinMode(52, OUTPUT);

  // Configure SPI
  SPI.begin(52);
  SPI.setClockDivider(52, 200); // 84e6/200 = 420kHz
  SPI.setDataMode(52, SPI_MODE3);
  SPI.setBitOrder(52, MSBFIRST);

  // Set sample rate
  float Fs = 1; // Target sampling frequency [Hz]
  float tb = 0.61035 * (Fs >= 12.7009) + 18.921 * (Fs < 12.7009);
  unsigned long tbsel = 0 * (Fs >= 12.7009) + 1 * (Fs < 12.7009);
  unsigned long Ns = (uint16_t) round((1000.0 - tb * Fs) / (tb * Fs));
  float Feff = 1000 / (tb * (Ns + 1));
  SerialBT.print("Selected freq: ");
  SerialBT.println(Feff, DEC);

  digitalWrite(52, LOW);  // Doesn't seem to be necessary
  SPI.transfer16(52, (0L << 15) | (0x36L << 8));                       delayMicroseconds(100);
  SPI.transfer16(52, (1L << 15) | (0x36L << 8) | (tbsel << 7) | Ns );  delayMicroseconds(100);
  SPI.transfer16(52, (0L << 15) | (0x36L << 8));                       delayMicroseconds(100);
  zgyro = SPI.transfer16(52, 0x00);
  digitalWrite(52, HIGH);

  SerialBT.print("SMPL_PRD = ");
  SerialBT.println(zgyro, HEX);

  attachInterrupt(3, availableIMUData, RISING);
}

void loop() {

if (fDataIMUtoRead) {

SerialBT.print("Loop... ");

// Read values (standard mode)
pauseBetweenTransfers = 100;
digitalWrite(52, LOW); // Doesn't seem to be necessary

        SPI.transfer16(52, 0x0400, SPI_CONTINUE); delayMicroseconds(pauseBetweenTransfers);
xgyro  = SPI.transfer16(52, 0x0600, SPI_CONTINUE); delayMicroseconds(pauseBetweenTransfers);
ygyro  = SPI.transfer16(52, 0x0800, SPI_CONTINUE); delayMicroseconds(pauseBetweenTransfers);
zgyro  = SPI.transfer16(52, 0x0A00, SPI_CONTINUE); delayMicroseconds(pauseBetweenTransfers);
xacc   = SPI.transfer16(52, 0x0C00, SPI_CONTINUE); delayMicroseconds(pauseBetweenTransfers);
yacc   = SPI.transfer16(52, 0x0E00, SPI_CONTINUE); delayMicroseconds(pauseBetweenTransfers);
zacc   = SPI.transfer16(52, 0x0000, SPI_CONTINUE);

digitalWrite(SS, HIGH);

/*
// Read values (burst mode)
pauseBetweenTransfers = 5;
digitalWrite(52, LOW);    // Doesn't seem to be necessary

         SPI.transfer16(52, 0x3E00);    delayMicroseconds(pauseBetweenTransfers);  // Request data burst
supply = SPI.transfer16(52, 0x0000, SPI_CONTINUE);  delayMicroseconds(pauseBetweenTransfers);
xgyro  = SPI.transfer16(52, 0x0000, SPI_CONTINUE);  delayMicroseconds(pauseBetweenTransfers);
ygyro  = SPI.transfer16(52, 0x0000, SPI_CONTINUE);  delayMicroseconds(pauseBetweenTransfers);
zgyro  = SPI.transfer16(52, 0x0000, SPI_CONTINUE);  delayMicroseconds(pauseBetweenTransfers);
xacc   = SPI.transfer16(52, 0x0000, SPI_CONTINUE);  delayMicroseconds(pauseBetweenTransfers);
yacc   = SPI.transfer16(52, 0x0000, SPI_CONTINUE);  delayMicroseconds(pauseBetweenTransfers);
zacc   = SPI.transfer16(52, 0x0000, SPI_CONTINUE);  delayMicroseconds(pauseBetweenTransfers);
xtemp  = SPI.transfer16(52, 0x0000, SPI_CONTINUE);  delayMicroseconds(pauseBetweenTransfers);
ytemp  = SPI.transfer16(52, 0x0000, SPI_CONTINUE);  delayMicroseconds(pauseBetweenTransfers);
ztemp  = SPI.transfer16(52, 0x0000);

digitalWrite(52, HIGH);
*/

SerialBT.println(zgyro, DEC); // Print the reading

fDataIMUtoRead = 0; // Reser the "there is new data"-flag

}

}
void availableIMUData() {
fDataIMUtoRead = 1; // Set the "there is new data"-flag
}
The standard way to communicate seems to work without any problem, provided that I set the right delays after each transfer16 command. But I'm not able to make the Arduino read the data in burst mode (commented in the code above).
So does anybody have any ideas on how to make the Arduino retrieve the readings in this burst mode? I understand this is a tricky unless you have (had) access to the same hardware, but any suggestion will be welcome.
Thanks a lot.

You seem to be correct about everything said, so far as I can tell.  I would put a scope on the signals and make sure they look okay.

Thanks timemage. Unfortunately I have no scope. Only a cheap logic analayzer, which wasn't of much help

First of all, this may not related to your question, but you are using old SPI methods setClockDivider(), setDataMode(), and setBitOrder() that has been deprecated since 2014. It is recommend to use use transactional SPI APIs which I have some explanation here.

Why I actually need those delays?

If you read page 6 of ADIS16364 datasheet, there is a tSTALL time between each data transmission that could be as long as 75uS (when operating on Low Power mode), this value can be much lower if you operate on Normal or Bust mode.

why this combination of delays with the 200 clock divider?

The clock divide set the clock used for the SPI SCLK rate, for Due a clock divide of 200 means 84,000,000 / 200 = 420,000Hz, Why this rate? again, you have to look into datasheet, on page 6 table 2, max fsck is 2MHz for Normal mode, and 1MHz for Bust mode, and only 300kHz at Low Power mode.

Shouldn't this be done automatically by the SPI library?

This is a wrong perception, SPI library do nothing than handling the communication. All the timing requirements are component/chip specific, and therefore if you want to communicate with the chip at SPI communication level, you will have to deal with all the timing requirements yourself. Most of the people in the Arduino community get used of using some pre-written library which was written by someone who care to read the datasheet and provide high level abstract API so that users don't need to deal with all the timing.

Any ideas on how to make the Arduino retrieve the readings in this burst mode?

Update
As suggested by the datasheet, "To start a burst read sequence, set DIN = 0x3E00", what this means is that you need to WRITE into the register 0x3E00 first to setup the burst mode. Fig 11. of the datasheet indicate that a WRITE operation would have a set most significant bit to 1, so you will need to send 0x3E00 | 0x8000 or 0xAE00 for writing into register 0x3E00. What you did is basically reading form 0x3E00, not writing into 0x3E00.
I re-read the datasheet and you are right, it should be okay to just send out 0x3E00. I never use an Arduino Due before, but I realised that the SPI.transfer16() might send out the 0x00 first instead of 0x3E. I modified the code to send out two bytes 0x3E and 0x00 separately using SPI.transfer()
I don't have the IMU, but I think the follow code should works for bust mode:
SPI.beginTransaction(SPISettings(1000000, MSBFIRST, SPI_MODE3));    //initialises SPI clock speed, mode and bit order
digitalWrite(SS, LOW);              // adjust this as per your chip select pin
SPI.transfer(0x3E);
SPI.transfer(0x00);
delayMicroseconds(1);               //bust mode only 1uS required as per datasheet
xgyro_out = SPI.transfer16(0x0000);
delayMicroseconds(1);
ygyro_out = SPI.transfer16(0x0000);
delayMicroseconds(1);
zgyro_out = SPI.transfer16(0x0000);
delayMicroseconds(1);
xaccl_out = SPI.transfer16(0x0000);
delayMicroseconds(1);
yaccl_out = SPI.transfer16(0x0000);
delayMicroseconds(1);
zaccl_out = SPI.transfer16(0x0000);
delayMicroseconds(1);
data16    = SPI.transfer16(0x0000);
delayMicroseconds(1);
data16    = SPI.transfer16(0x0000);
delayMicroseconds(1);
data16    = SPI.transfer16(0x0000);
delayMicroseconds(1);
data16    = SPI.transfer16(0x0000);
delayMicroseconds(1);
digitalWrite(SS, HIGH);   // deselect slave
SPI.endTransaction();

Thanks for you detailed reply, hcheung.
Your indication to WRITE to the 0x3e00 seemed to be the key, but it didn't solve the problem. After checking the specs sheet again, on page 12, end of first paragraph of the second column: "Reading the GLOB_CMD register (DIN = 0x3E00) starts the burst read sequence." So SPI.transfer16(0x3E00) should actually do the job, if I get it right.
Any other ideas?

I use the old syntax for SPI communication because I just wasn't able to make the new SPI.beginTransaction command work. No idea what I'm doing wrong. The old one seems to be working fine, though (unless you see any reason this should be preventing the burst mode to work)

I just discovered yesterday that with sample rates as high as 150 Hz the IMU still works in low-power mode, which explains the high delays needed, as you suggest.

You are right, it should be okay to just send a read cmd to 0x3E00. Please see my update answer and also the change of the code to send  out two bytes (0x3E, 0x00) separately. Please try, I think it should work.

The old APIs still work even though it is deprecated as long as your SPI bus do not have multiple SPI devices on it. The SPI.begintransaction is designed to allow multiple devices to operate with each has its own configuration settings.

I don't think you need to change the order of the two bytes, hcheung. I've tried, just in case, but it didn't have any effect. Reading in standard mode works fine with lines like {SPI.transfer16(52, 0x0A00, SPI_CONTINUE)}

I've edited the main question with the complete code I'm using for testing, with both standard and burst modes, just in case you can see anything wrong there.


text:
Water level switches / reed switches and Arduino Uno
How could I estimate the max number of switches that I could connect to an Arduino Uno?
I am questioning if Arduino has enough power to simultaneously operate an X number of switches with no issues.
I am using an external power adapter of 12 volt/2 amps (barrel).
Here is the hardware: https://m.hellasdigital.gr/el/products/tank-pool-water-level-liquid-sensor-float-switch

Count the number of digital-capable IO pins :) It's unclear what problem you're thinking you'll run in to. Are the switches, for example, really far away?

You can use up to (N/2)² switches where N is the number of IO pins you have.

Yes I am trying to find out why under some conditions the sensor does not trigger the Arduino. It is one in the hundreds but it happens often if you think that the sensor is triggered twice every five minutes continuously. The distance is under five metres. I will soon move the power cables away from the signal cables. Right now they are a bit close.

How are they connected? You might want to check out https://arduino.stackexchange.com/q/13072/8583 and similar; 5m isn't far-far, but it's far enough.

Yes indeed I forgot to write that I used 10 k pull up resistors and I do not use the Arduino internal. Maybe I should try the 1 K. Something else that may be relevant while I was reading the article is the fact that all buttons use the same ground cable. Maybe each one should have each own twisted and only at the end I should connect all ground together.

I liked the idea of using opto coupler isolation. First of all I have to put the cables in an order. For instance a separate twisted pair per switch and put them far away from the high voltage cables.

thank you a lot about your input it was very useful.
My source of issues was a faulty sensor. After I changed it things are smooth now.
I separated the power cables from the signal as well that is super important.
Thank you a lot about the valuable input!


text:
How to connect SIM7100A to Arduino?
I've been searching for how to connect a SIM7100A module to an Arduino (Uno or Mega), but I haven't been able to find any posts anywhere, nor videos nor any kind of documentation that shows how to do it. Does anyone here know how to connect it so I can send simple AT commands to the module from the Arduino? (I just want to make GET requests and get GPS coordinates)

user guide https://m.media-amazon.com/images/I/91alo3EgWaL.pdf

I would expect connect power, ground, TX and RX. Just like any other MODEM.

Got it to work, in part thanks to the documentation that @Juraj posted.
My pinout is the following, in case anyone needs it:
SIM7100A -> Arduino Mega
SUPPLY -> 5V (the SIM7100A's SUPPLY pin powers the actual board, it's different from the VDD pin which is only for the Serial communication)
GND (both lower & upper) -> GND
VDD -> 3.3V
TXD -> RXD2
RXD -> voltage divider (5V to 3.3V) -> TXD2
Once the module is powered (the PWR LED is on), you gotta press the module's reset button for about 3 seconds and then wait for the NET and STA LEDs to turn on, then you can start sending AT commands to it.
I don't know if this will be the case for everyone, but for me, the serial communication through the SIM's USB debug port is with 9600 bauds, but the communication through the TXD and RXD pins is with 115200 bauds.


text:
About Corrupted LM35 IC and Arduino port problem
I have one Arduino Uno which was working fine by below circuit(link):

But when I have connected the new bought the LM35 Ic by the below connection:

The Arduino UNO don't be recognized by the my Ubuntu OS as you can see below:

And by removing the LM35 connections, the Arduino don't be recognized again. I have damaged two Arduino Uno board by this mistake and ...
So I don't know why this happened and for repairing the damaged circuits I hope find out which part of the Arduino circuit are probably damaged?
Thanks.

Ttyusb? Sounds like you're using cheap Chinese clones. Good luck with that...

Can you be specific regarding which LM35 variant and which pin you connected it to? Have you tried a standalone circuit?

@Dave_Newton, I can see the ??cxz LM35 DZ on the IC which i don't know what is the two ?? character on the IC, but I googled it and i guess it is this kind, I found the all lm35 DZ types pins are the same and my circuit connections is right ( based of this datasheet).

@Dave_Newton,  For the third part of your question, I used the LM35 DZ type on the main circuit with this shematic (like the above)

@sosa FYI if you use @ somebody with something other than what the autocomplete provides there's no notification. This isn't a schematic--I can't tell what pin you've hooked the LM35 to. It's unlikely the issue is caused by the LM35 itself; have you tried a circuit with just the LM35 as a sanity check?


text:
how do i make stepper stop if both sensors are LOW ? im using a adafruit l293d motor shield
I've tried this code below but it doesn't stop it just rapidly switch direction that it looks like it's trembling I think because it always reads the void startF/R thats why it's trembling .
I need help on how to completely stop the stepper if it reads both sensor LOW
if (sensLval== LOW || sensRval == LOW){
     steppStop();
}

this is my void loop code below
    void startF()
  {
    motor1.step(10, FORWARD,SINGLE);

  }

    void startR()
  {
    motor1.step(10, BACKWARD,SINGLE);

  }

    void steppStop(){
  motor1.step(0, BACKWARD, SINGLE);

 motor1.step(0, FORWARD, SINGLE);
}

    void loop() {
  sensRval=digitalRead(sensR);

sensLval=digitalRead(sensL);

  if (sensLval == LOW)

{
    startF();
  }

if (sensLval== LOW && sensRval == LOW)

{
     steppStop();
  }

  if (sensRval == LOW)

{
    startR();
  }

}

Isolate your conditions.
You currently check for:

Both sensors LOW at the same time and
Either sensor LOW on its own

If both are low—don't check for either being LOW (which triggers startX.)
if (sensLval == LOW && sensRval == LOW) {
    steppStop();
} else if (sensLval == LOW) {
    startF();
} else if (sensRval == LOW) {
    startR();
}

There may be other considerations as well, but this is enough to get past that issue.

Unrelated, but consistent indentation goes a long way towards code readability and helping others be able to reason about code in general. When posting code it's a good idea to format your code as code, described here and when you are editing the question.

Im sorry bout the format , im still learning but i'll be sure to do well next time. The code works now thanks alot! I ddnt know u could code it  that way. That's cool!


text:
Simple GET request is failing silently
I'm trying to make a simple GET request to a server (which has a static IP but does not have a name). I'm using EtherCard library and a cheap ENC28J60 Ethernet Module. The basic configurations are OK (I can get DHCP assignment and DNS lookup), but when I try to make a simple GET request with the browseUrl method, nothing happens. I've tried to call the page from the browser and everything works fine, so it's not a server issue. The code is the following:
#include <EtherCard.h>

// ethernet interface mac address, must be unique on the LAN
byte mymac[] = { 0x54, 0x55, 0x58, 0x10, 0x00, 0x24 };

const char website[] PROGMEM = "http://10.10.10.10"; // my server
const char dnsLook[] PROGMEM = "google.com";

byte Ethernet::buffer[700];
uint32_t timer;
Stash stash;

// called when the client request is complete
static void requestCallback (byte status, word off, word len) {
  Serial.print(">>>");
  Serial.print(status);
  Serial.print("-");
  Serial.print(status);
  Serial.print("-");
  Serial.print(status);
  Serial.println("<<<");
}

void setup () {

  Serial.begin(9600);
  delay (10000);
  int res = ether.begin(sizeof Ethernet::buffer, mymac, 8);

  if (res == 0)
    Serial.println( "Cannot access ethernet interface");

  const static uint8_t ip[] = {192,168,1,117};
  const static uint8_t gw[] = {192,168,1,1};
  const static uint8_t dns[] = {8,8,8,8};

  if (!ether.staticSetup(ip, gw, dns))
  {
      Serial.println("Cannot set static parameters");
  }

  // manually set netmask
  ether.netmask[0] = 255;
  ether.netmask[1] = 255;
  ether.netmask[2] = 255;
  ether.netmask[3] = 0;

  // dns lookup
  if (!ether.dnsLookup(dnsLook))
    Serial.println("DNS failed");
}

void loop () {
  ether.packetLoop(ether.packetReceive());
  if (millis() > timer) {
    timer = millis() + 10000;
    ether.browseUrl(PSTR("/page.php?"), "var=value", website, requestCallback);
  }
}

run example code first

I recommend you to use my EthernetENC library

@Juraj I'll give a try

I made it by using EthernetENC library, as suggested by @Juraj.
To install the library, simply use the library manager and search for EthernetENC.
For those in need, below is a working code
#include <SPI.h>
#include <EthernetENC.h>

byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };  // ethernet module MAC address
IPAddress server(10,10,10,10);                        // server IP address, without DNS
//char server[] = "www.site.com";                     // if your server has a DNS name, use this variable for connection

// static configuration variables
IPAddress staticIp(192, 168, 1, 217);
IPAddress staticDnsServer(8, 8, 8, 8);

EthernetClient client;                                // ethernet client object

void setup() {
  // configure CS pin
  Ethernet.init(8);

  // begin serial connection
  Serial.begin(9600);

  // wait some seconds to let the module start
  delay(5000);

  // initialize ethernet module with static configuration
  Ethernet.begin(mac, staticIp, staticDnsServer);

  // wait to let the module properly initialize
  delay(1000);

  // connection to the server
  Serial.print("Connecting to: ");
  Serial.print(server);
  Serial.println("...");

  // notify successful connection
  if (client.connect(server, 80)) {

    Serial.print("Connected to ");
    Serial.println(client.remoteIP());

    // simple GET request
    client.println("GET /page.php?var=test HTTP/1.1");
    client.println("Host: 10.10.10.10");
    client.println("User-Agent: Arduino/1.0");
    client.println("Connection: close");
    client.println();

  } else {
    // connection failed notifiation
    Serial.println("Connection failed");
  }
}

void loop() {

  // if I got a response from the server, read and print to serial
  int len = client.available();
  if (len > 0) {
    byte buffer[80];
    if (len > 80) len = 80;
    client.read(buffer, len);
    Serial.write(buffer, len);
  }

  // disconnection
  if (!client.connected()) {

    Serial.println();
    Serial.println("Disconnected");
    client.stop();

    // stop execution
    while (true) {
      delay(1);
    }
  }
}

at this link, you can see how to properly connect this module to Arduino UNO.

you can lower the flash and memory usage with settings in utility/uipethernet-conf.h https://github.com/jandrassy/EthernetENC/wiki/Settings the most interesting setting is UIP_CONF_UDP