text:
USBasp problem: could not upload sketches to Arduino clone with PL2303 USB-to-UART chip
I'm trying to upload sketch to a Gizduino board (these boards have PL2303 chip for USB-to-Serial communication; other than that they are entirely similar with Arduino Uno).
I have installed the driver for it and can verify that the board associates to a COM Port whenever the board is connected to my PC (Win10) via USB. But everytime I try to upload a sketch, IDE (tried with 1.8.2 and 1.6.9) throws the error below, with or without the PL2303 driver installed on my PC.
avrdude: error: could not find USB device with vid=0x16c0 pid=0x5dc vendor='www.fischl.de' product='USBasp'

I'm certain that I have selected the right board from the Boards List.
So my intuition was that the PL2303 driver is not working the way it should be. I've been trying to get more information about avrdude and USBasp but so far was not able to find anything remotely similar to my case.
UPDATE: Realized that all I needed to do is install the driver for USBasp (whihch I'm having trouble doing); this post could be off-topic. But I'm urged to raise another question: Which programmer should I select from the programmer list? Currently its "AVRISP mkII". In fact it doesn't matter which one I use. Same error about USBasp occurs with any of them selected.

You told the IDE to upload through an USBASP, but apparently you are no using an USBASP, so avrdude complains it cannot find it.

Hi. I updated the post.

Really frustrating. Tried on 3 different pc's. same board. same problem. Found nothing related in the internet. Not even in stackexchange is there somebody who got any idea about this seemingly ubiquitous issue. at this point I'll just take it that my board is broken.

Do you have a USBasp plugged into the computer? if yes then you need to install USBasp driver else why don't you just use the bootloader option from the arduino IDE.


text:
add ID number to the feather m0 bootloader (flash)
I'm trying to add a serial number to the bootloader's flash area of Adafruit Feather m0 board. Seems like feather m0 0-0x2000 area on the flash is non writable by the arduino sketch. i wanted to add a serial number to address 0x2000 - 8 on the flash.
The idea is for the data to be included in the bootloader elf\bin so i can easily flash it on devices and later on access it using flash address  (0x2000 - 8) with NVMCTRL.
I've started out with this solution:
downloaded the code from samd21 arduino bootloader github directory and in ./bootloaders/zero edited the boololoader ld script, first the "Memory" section
FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 0x2000 /* First 8KB used by bootloader */
FLASHID (rx) : ORIGIN = 0x00002000 - 0x0008, LENGTH = 8

Then the 'sections' section:
.id_sec :
  {
    KEEP(*(.myid))
  } > FLASHID

This should have saved some room in the end of the flash for the id. now in the main.c file:
__attribute__ ((section(".myid"))) const unsigned long ID = 0xdead1234;

Which should have saved the 0xdead1234 hex value in the (0x2000-8) address.
The issue is this:
I compiled this code and linked it just fine, got .hex,.bin,.elf files.
If i'm correct (unless they are somehow compressed) i should be able to see the code 0xdead in the binary.
BUT i don't.
After objdump on the binary(any of them) i can't find the 0xde 0xad in any order anywhere.
The arm-none-eabi-size" --format=sysv -t -x build/.elf does not show the new section i added no where.
Also i do wonder, as i said the 0x2000 address on the flash is non writable once i flashed with atmel-ice \j-link even the bootloader code cannot write to it, i did define in the ld script that i want that memory region part of the flash so i do expect that the compiler + linker + jlink flasher will know to write that data to the right place but not sure.
Anyone got some experience with it ? did it before ?

instead of 0xde 0xad, look for 0xed 0xda ... maybe it is stored in little endian

Your question is amazingly hard to read. See How to ask a good question. Take a bit of time to make some paragraphs, spell "I" with a capital "I", and generally explain what you are trying to do.

@jsotola i did try that, well aware of the endianess. i basically tried just to use objdump and xxd and then grep it twice once for 'ed' and once for 'da' which should capture all possibilities.

Hi @NickGammon sorry , i see what u are talking about some parts slipped in from stackoverflow, i posted there too and copy-paste it and it needs some fixing, but in general i explain exactly what i wanted to achieve and what i did to achieve it, i was asking what can i do actually get it done.

Hey @NickGammon changed the question a bit i hope it's clearer now.

Cross-posted here. The question looks better, however see See Is cross-posting a question on multiple Stack Exchange sites permitted if the question is on-topic for each site? - you have to decide which site you want to ask on. Stack Exchange does not want you to ask your question over multiple of its sites.

Can understand them, though i think at times it's unjust as the question does fit nicely to any of them, stackoverflow is more generic and this is indeed a programming question, however it is in need of someone that also flashed a boot-loader or did a  certain procedure for embedded devices  in the past. which i guess i'll see mostly here.
In any case deleted it from stackoverflow and will repost if i don't get any answer here.

You know the samd21 already has a unique serial number that you can access.

This is quite an easy fix, actually.
The problem here is the compiler doesn't think the const is used for anything - so it (quite rightly) throws it away.
All you need to do is tell the compiler that it's used and all should be good:
__attribute__((section(".myid"),used)) const unsigned long ID = 0xdead1234;

And when you compile:
build/.elf  :
section             size         addr
.vectors            0x40          0x0
.text             0x18d4         0x40
.data               0x5c   0x20000000
.bss               0x34c   0x2000005c
.id_sec              0x4       0x1ff8
.ARM.attributes     0x28          0x0
.comment            0x80          0x0
.debug_frame        0x68          0x0
Total             0x1dd0

Properly, though, you should make some more changes to the linker script to properly isolate those 8 bytes of flash (though you don't have to).

You should reduce FLASH by 8 bytes.
You should include the FLASHID length in the __sketch_vectors_ptr calculation.

That's:
MEMORY
{
  FLASH   (rx) : ORIGIN = 0x00000000, LENGTH = 0x1FF8 /* First 8KB used by bootloader */
  FLASHID (rx) : ORIGIN = 0x00001FF8, LENGTH = 8
  RAM    (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00008000-0x0004 /* 4 bytes used by bootloader to keep data between resets */
}

And:
PROVIDE(__sketch_vectors_ptr = ORIGIN(FLASH) + LENGTH(FLASH) + LENGTH(FLASHID));

That way the compiled bootloader code can never be placed in the FLASHID area (not that it would at the moment, but if a new version of the bootloader were released that used 100% of the lower block of flash it would conflict).
Of course, if all you need is something unique to identify the board with, all AVR and SAMD devices that have built-in USB support have a unique ID number. This is intended to be used as the Serial Number for the USB, but could also be used for a MAC address for Ethernet (or for portions of it anyway) or other unique "node" addresses.

thanks! checking myself, if indeed i can see it i'll mark as the solution

@codeScriber note first the comment that the chip already has a unique ID.  Next, if you want to serialize like this, after setting a default from the compiler, in practice you'd probably want to directly overwrite the values in the binary to be flashed (dd or many other tools can write at an offset) rather than recompile for each unit.

I do something similar to set a unique USERID value on PIC32 chips when programming a bootloader from a HEX file. Allocate it from a database, then filter the HEX file changing the values that need changing and recalculating the checksums.

@ChrisStratton  thanks that's exactly what i planned to do though i planned to use python script to do that... but no, i didn't know it had a serial and i did look for it! are you sure it's unique ? i actually looked for arm m0 unique id and not samd21, probably my mistake was there...

@Majenko ineed it worked, if i xxd -g0 the .bin file i can see in the end :'00000000000000003412adde' ! marked your answer as the solution but maybe you should copy the remark about the fact that there is already a uniq id for samd21...

All the AVR parts with USB have a unique ID which is intended for use as the USB serial number. I'm not sure about the SAMD21 though - check the datasheet.

From the datasheet: "Each device has a unique 128-bit serial number....The uniqueness of the serial number is guaranteed only when using all 128 bits."

Excellent. I've not worked at a low level with these chips yet, though doing so is on the cards over the next few months, as well as the E70 series. Pretty soon I will be a world authority on them :(.

source: Stack Exchange

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

sort: votes


text:
No potential across output of H-bridge
I’m working on a robot with a club at my school. So far, our team has an H-bridge shield (https://www.freetronics.com.au/products/hbridge-dual-channel-h-bridge-motor-driver-shield#.WwI9omh_WEc) to drive motors in a toy tank. The H-bridge is powered by 6 AA batteries and the arduino is powered through the H-bridge shield with these batteries also.
 When everything is connected up and  code uploaded to make the motors run forward, nothing happens - the motors don’t run. So far to debug, I’ve used a multimeter to check the voltages being output to the H-bridge from the arduino controller. These are all as expected. I’ve touched the motors to the positive and negative terminals of the battery and they run as expected. Lastly, I’ve substituted the H-bridge shield for a known working one. This did not fix the problem. I disconnected the motors and tested the voltage being output, which measured as +6V for both terminals of the motor relative to the negative terminal of the battery as well as relative to the ground pin. I also disconnected the jumper powering the arduino from the H-bridge shield and instead powered the arduino from my laptop. This did not fix the problem either. This seems completely contradictory. Any ideas on what the problem could be? Thanks so much ❤❤

Do you have a separate power supply connected to the shield? If not did you connect the jumper to power the motor from the Arduinos Vcc?

Measure the current going to the motors when connected to the shield vs when directly connected to the battery. Either your supply breaks down or you don't have the supply connected (see @Gerben comment). It would help if you draw a schematic of your exact setup  (all conncections) using either pen&paper or the schematic tool when editing the question.

here is the schematic .... looks like you require jumpers in JP1 and JP2 for enabling the data pins

It sounds either (i) like your motor driver is broken or (ii) your code does not operate the H bridge properly.  Check which digital outputs pins of the Arduino control the H bridge and make sure that they do not short out the H bridge.
If you want to try another H bridge, this one is suitable for your application: https://www.pololu.com/product/2990 .  I have worked with this before and it's very easy to use.

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


text:
Question about memory allocation analysis
As I'm experiencing weird bugs in a rather lengthy project, I started analyzing my RAM usage on my ATMEGA328P with Arduino bootloader. At least I tried to and wrote the following piece of code. Consider the following written in Arduino IDE 1.8.5:
extern int __heap_start, *__brkval;

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

void loop() {
  // put your main code here, to run repeatedly:
  delay(500);
  f1();
  delay(500);
  freeRAM();
}

void f1() {
  int local = 0;
  local = 6;
  freeRAM();

}

void freeRAM() {
  int local = 0;
  local = 5;
  if (*__brkval == 0) {
    Serial.println("The break point is 0,...");
    Serial.println((int)&local - __heap_start);
  }
  else {
    Serial.println("The break point is not 0,...");
    Serial.println((int)&local - *__brkval);
  }
}

And the rather unexpected output:
The break point is not 0,...
2048
The break point is 0,...
2294
The break point is 0,...
2294
The break point is 0,...
2294
The break point is 0,...
2294
The break point is 0,...
2294
The break point is 0,...
2294
The break point is 0,...
2294

I was expecting 2 different values of free RAM because on the second call of freeFram(); the function call and local variables of f1() should already be popped from the stack. Perhaps i misused the external variables (__heap_start, __brkval) or I misinterpreted one of the links I read:
memories-of-an-arduino
Lecture 08: Memory Allocation and Program Memory Layout
Perhaps someone could elaborate on this.
EDIT:
@Gerben: Thx for the hint, didn't change anything though!
@Edgar:
Looking at a snippet of the objdump:
 76e:   0e 94 8e 01     call    0x31c   ; 0x31c <delay.constprop.3>
 772:   1a 82           std     Y+2, r1 ; 0x02
 774:   19 82           std     Y+1, r1 ; 0x01
 776:   1a 83           std     Y+2, r17        ; 0x02
 778:   09 83           std     Y+1, r16        ; 0x01
 77a:   0e 94 5a 02     call    0x4b4   ; 0x4b4 <_Z7freeRAMv>
 77e:   0e 94 8e 01     call    0x31c   ; 0x31c <delay.constprop.3>
 782:   0e 94 5a 02     call    0x4b4   ; 0x4b4 <_Z7freeRAMv>
 786:   0e 94 5f 01     call    0x2be   ; 0x2be <_Z14serialEventRunv>
 78a:   f1 cf           rjmp    .-30            ; 0x76e <main+0xfe>

I realized the compiler was indeed inlining the call to f1(). Changing f1() to:
__attribute__((noinline)) void f1() {
  volatile int local = 0;
  local = 6;
  freeRAM();

}

and results in the following objdump:
 784:   0e 94 8e 01     call    0x31c   ; 0x31c <delay.constprop.3>
 788:   0e 94 94 02     call    0x528   ; 0x528 <_Z2f1v>
 78c:   0e 94 8e 01     call    0x31c   ; 0x31c <delay.constprop.3>
 790:   0e 94 5a 02     call    0x4b4   ; 0x4b4 <_Z7freeRAMv>
 794:   0e 94 5f 01     call    0x2be   ; 0x2be <_Z14serialEventRunv>
 798:   f5 cf           rjmp    .-22            ; 0x784 <main+0xf0>

which therefore results in the desired behaviour:
The break point is 0,...
2294
The break point is 0,...
2288
The break point is 0,...
2294
The break point is 0,...
2288
The break point is 0,...
2294
The break point is 0,...
2288
The break point is 0,...
2294

Thanks a lot!
A question that's on my mind now: Looking at the values of freeRam, shouldn't the value be smaller than 2048? Am I calculating wrong?
EDIT #2: In the meantime it turned out that my "memory"-problem was actually some self induced pointer stupidity :/
But for the sake of completeness, and if someone is on the search for a method for memory analysis like I was, here are my 2 cents.
@Gerben: I'm sry, I realised that I have to declare the function noinline as well as declare some volatile variable in it to stop the compiler from inlining the call. So Edgar and you were both right at the beginning!!
@Edgar you were completly right again, with you and some reading from here:
Official freeRam() command #5289
I came up with the following code:
extern int __heap_start, *__brkval;

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

void loop() {
  // put your main code here, to run repeatedly:
  reportFreeRAM();
  delay(500);
  f1();
  delay(500);

}

__attribute__((noinline)) void f1() {
  //String s = "foobar";
  volatile char arr[7] = "foobar";
  reportFreeRAM();

}

void reportFreeRAM () {
  int v;
  Serial.println("-------RAM Report---------");
  Serial.print("__brkval = ");
  Serial.println((int)__brkval);
  Serial.print("FreeRAM: ");
  Serial.println((int) &v - (__brkval == 0 ? (int) &__heap_start : (int) __brkval));
}

which results in the following output:
-------RAM Report---------
__brkval = 0
FreeRAM: 1792
-------RAM Report---------
__brkval = 0
FreeRAM: 1781
-------RAM Report---------
__brkval = 0
FreeRAM: 1792
-------RAM Report---------
__brkval = 0
FreeRAM: 1781
-------RAM Report---------
__brkval = 0
FreeRAM: 1792

and if f1() is changed to:
__attribute__((noinline)) void f1() {
  String s = "foobar";
  //volatile char arr[7] = "foobar";
  reportFreeRAM();
}

we see the following result:
-------RAM Report---------
__brkval = 0
FreeRAM: 1786
-------RAM Report---------
__brkval = 519
FreeRAM: 1773
-------RAM Report---------
__brkval = 510
FreeRAM: 1786
-------RAM Report---------
__brkval = 519
FreeRAM: 1773
-------RAM Report---------
__brkval = 510
FreeRAM: 1786

which is rather interesting, because you see the break-point-pointer getting initialised with the first allocation for the String variable and after that the value jumping back and forth. Which is to my understanding the expected behaviour. For my application I wanted to check if I had allocated any memory dynamically, so I guess an easy check would be to check (int)__brkval for zero. Perhaps someone could elaborate if that is always a good idea or not.
So sry for the lengthy post, I just wanted to show what I found, in case someone stumbles over the same kind of question.
Thx @Gerben and @Edgar!

You simply forgot that the compiler optimizes your code. Looking at the generated assembly should be enlightening.

Try declaring the local variable as volatile

Yes, the amount of free memory can only be less than 2 KiB on the 328P. I think the problem is that you should use __brkval instead of *__brkval and &__heap_start instead of __heap_start.

__brkval may not return to zero once you do any allocation. If you want to know the size of the heap, try: (__brkval ? (int) __brkval - (int) &__heap_start : 0).


text:
OneButton with pins A6 and A7
I noticed that OneButton library does not work with pins A6 and A7 (with A1 and A2 it works good) on my Arduino Nano. Is it because A6 and A7 are Analog only? There is possibility to make them work properly?
sketch example is here https://github.com/mathertel/OneButton/blob/master/examples/TwoButtons/TwoButtons.ino

Is it because A6 and A7 are Analog? ... why would you would ask that?  A1 and A2 are also analog pins. .... please post the sketch that fails

A1 and A2 could be also digital, but A6 and A7 as I understand - no (see attached pinout schema)

that is not what you said in your question .... when it comes to technical questions, you have to be precise  .... change your statement to Is it because A6 and A7 are "analog only"?

Pins A6 and A7 are analog only pins. They have no digital functionality at all.

You can see that pins 19 and 22 only have ADCn on them - no Pxn for digital operation (ignore the colour scheme of those pins - that's an error in the datasheet).

That is what I thought... So is it possible to make OneButton with analog pins?

That is correct. You would have to adapt it to use analogRead() on those pins and compare the incoming values to threshold values for HIGH and LOW. Could be done, but clunky.

In the library, in the function tick, there is the digitalRead call. You could change that line to test if pin a6 or a7 is used and then use code with analogRead. Perhaps the author of the library is willing to add that. You could make an issue and ask for a feature request.

authors: Филипп Цветков


text:
Long freezes at the beginning of sd card transfer
I am creating an accelerometer data logger that writes data to sd card. After some sort of "warm-up" everything works perfectly for at least ~15 minutes (which is what I have tested so far).
However, during the first few seconds there are some pretty long freezes of the File.write() function (180 ms instead of 50us for normal writes!) which I can identify on an oscilloscope (see picture below, signal low after starting high indicates File.write() phases) and which I can also see in the data if I include in them a milis() timestamp.
Since RAM on the Atmega328 is limited, there is also tight limits to the amount of sensor data I can buffer (I am using an interrupt for transfer from the sensor, where I can store the data to a buffer and thus bridge the shorter sd card delays).

I stripped down my code to the absolute bare bones, just writing nonsense data instead of those from the accelerometer. What could be the reason for these freezes? The data rate is the same during the whole run. Isn't the sd card electrically or logically initialized after SD.begin()? It doesn't seem to be a problem with erasing flash memory blocks because it only occurs in the beginning. Even if I restart the application a second time (after staying electrically on all the time) it already shows no freezes anymore. Whereas if I unplug/plug power, the freezes in the beginning reappear.
And most importantly: how can I solve it?
Of course I could write the dummy data before receiving the start button. But how many? Does it depend on sd card type? Does it depend on cpu or spi clock frequency? I want a robust solution that doesn't break when I use another type of sd.
Code:
#include <SPI.h>
#include <SD.h>

const int chipSelect = 10; // chip select of the sd card
const int pushButton = 9; // this is where the start button is (on a pulldown resistor)
const int debugPin = 1; // a line used for displaying a debug bit on the oscilloscope

const int bufferSize = 14;
byte buffer[bufferSize] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14}; // for the test just dummy values

String fileName = "accellog.raw";

void setup()
{
  pinMode(pushButton, INPUT);
  pinMode(debugPin, OUTPUT);

  if (!SD.begin(chipSelect))
  {
    // on error stop execution
    for(;;);
  }
}

void loop()
{
  // wait for the start button to be pressed
  while (digitalRead(pushButton) == HIGH);
  delay(100); // debounce delay
  while (digitalRead(pushButton) == LOW);

  // remove old file on sd card
  if (SD.exists(fileName)) SD.remove(fileName);

  File dataFile = SD.open(fileName, FILE_WRITE);

  if (dataFile)
  {
    // Debugging: indicate start of whole data transfer on an oscilloscope
    digitalWrite(debugPin, HIGH);

    int lastMillis = millis();

    for (long i=0; i<10000; i++)
    {
      // wait until millis changes in order to get SD writes at
      // whole millisecond boundaries (some cycles may get lost,
      // however, during lengthy SD writes)
      int tempMillis = millis();
      while (tempMillis == lastMillis)
      {
        tempMillis = millis();
      }
      lastMillis = tempMillis;

      // Debugging: indicate file access times by sending 0 to the DSO
      digitalWrite(debugPin, LOW);

      dataFile.write(buffer,bufferSize);

      // Debugging: indicate end of file access on DSO
      digitalWrite(debugPin, HIGH);
    }

    // Debugging: indicate end of whole data transfer
    digitalWrite(debugPin, LOW);

    dataFile.close();
  }
  else
  {
    // on error stop execution
    for (;;);
  }
}

try to open file and then close it without any writes

@jsotola: unfortunately that didn't change anything. But I will see how far I get with writing some nonsense data in advance (in a different file).

I can't really reproduce that. On my SD card I get an initial delay (between the first and second write) of about 30 ms, followed by a batch of writes, then a 20 ms delay, then another batch and so on. The pauses are between about 512 bytes being written out which would be the buffer (in the SD library) actually being written to the SD card. My suggestion is to try a different card and see what happens. Maybe one with a fast write class (eg. the sort you use for taking videos).

@NickGammon: yeah, maybe it's the card. I took the cheapest 16 GB cards I could get. :-) I have also been thinking about data loss on the SPI lines as a cause, but the lines on my board are a lot shorter than what you have in a breadboard setting. Anyways, I have a workaround now, at least. I will have to check what happens with cards that have been written full once...

I don't think data loss would really do it. The data either arrives or it doesn't. I took the cheapest 16 GB cards I could get - it looks like you got what you paid for. :)

As a temporary workaround I have come to the following procedure:
I inserted a function that writes a certain amount of bytes into a dummy file, closes it and finally deletes it, all during setup().
This does indeed seem to cure the freezes if (in my scenario) I write at least 6 blocks (512 bytes each, i.e. total 3072 Bytes). Remarkably there were always exactly 6 freezes visible in my oscilloscope plots. I don't even remotely know what the meaning of this magic number 6 could be...
Just to have some additional safety in case I choose a different type of sd card (and this workaround becomes permanently temporary...), I have decided to write 16 kB into the dummy file. This is ~5 times as much as the empirical minimum value (3 kB) and is still pretty fast so that I don't notice any significant startup delay after power-up.
This empiric approach is still unsatisfactory though, and certainly a piece of mediocre engineering. So I won't mark my answer as accepted, to leave the chance for someone else to give a more well-founded answer.
void writeAndEraseDummyFileToEliminateFreeze()
{
  if (SD.exists("dummy")) SD.remove("dummy");
  File dummyFile = SD.open("dummy", FILE_WRITE);
  int n = 16384/recordSize+1; // write 16kB in chunks of recordSize (just because we have that buffer already
  for (int i=0; i<n; i++)
  {
    // buffer values are uninitialized, but who cares, we'll dispose of them anyway
    dummyFile.write(buffer,recordSize);
  }
  dummyFile.close();
  SD.remove("dummy");
}

void setup()
{
  // ...other things I have been already doing...

  writeAndEraseDummyFileToEliminateFreeze();
}

You could measure the time needed to do the write, and repeat as often as necessary, aborting when the number or time exceeds a decent limit.


text:
Timer frequency calculation for UNO/Atmega328
I must be overwrought or something... I just can't get the calculation of the timer frequency right. I have a 16 MHz crystal on the Atmega328. I want 1 kHz timer interrupt rate. So I chose prescaler = 64 and counter top = 249, that is
fTimer = fCPU/prescaler/(top+1) = 16 MHz/64/250 = 1 kHz
But my oscilloscope shows 2 kHz... !? Why?
I have read Timer2 Compare Interrupt not working as expected but the accepted answer doesn't make it better. There the frequency is half as high whereas mine is twice as high as expected.
Code:
const int signalLED = 1; //14;

void setup()
{
  pinMode(signalLED, OUTPUT);
  digitalWrite(signalLED, LOW);

  TCCR2A = 0; // set TCCR2A register to 0
  TCCR2B = 0; // set TCCR2B register to 0
  TCNT2  = 0; // reset counter
  OCR2A = 249; // top value in CTC mode
  TCCR2A |= (1 << WGM21); // enable timer2 CTC mode
  TCCR2B |= (1 << CS21) | (1 << CS20); // 1:64 prescaling for timer 2
  TIMSK2 |= (1 << OCIE2A); // enable timer2 compare interrupt
  sei(); // allow interrupts
}

ISR(TIMER2_COMPA_vect)
{
  // generate peak
  digitalWrite(signalLED, HIGH);
  digitalWrite(signalLED, LOW);
}

void loop()
{
}

Your comment:
TCCR2B |= (1 << CS21) | (1 << CS20); // 1:64 prescaling for timer 2

doesn't match the actual setting (= 1/32)
Also there are some issues with setting Timer2 CTC mode, it's better to set mode, then OCR2A + TCNT2 + interrupts and then Prescaler to start the timer. It behaves as there is OCR2A=0, so the frequency is much higher than expected.

That was the problem. I just mixed up the prescaler setting specs of Timer1 with those of Timer2. For Timer1 CS11|CS10 is 64. I knew that standing up too early wouldn't be good for me... ;-)


text:
Arduino IDE - Ubuntu Mono Font Name?
I know that you go to preferences.txt and there is editor.font= line setting, but I can't get what font name to type in there to use Ubuntu Mono. I would like to use that font please. I've tried:
Ubuntu_Mono
Ubuntu-Mono
Ubuntu Mono
Ubuntu+Mono
Ubuntu.Mono
UbuntuMono
Ubuntumono
ubuntumono
'Ubuntu Mono'
"Ubuntu Mono"
'UbuntuMono'
"UbuntuMono"
'Ubuntu-Mono'
"Ubuntu-Mono"
'Ubuntu_Mono'
"Ubuntu_Mono"

Thanks for answer :]
PS: Yes, I've restarted the studio every time, but some non-monotype/default font showed up.

You need to specify the font, style and size.  I think you want
editor.font=Ubuntu Mono,plain,12

I don't know the exact name you should use for the font but you must have all three fields separated by commas.
The second field can be "plain", "bold" or "italic".
The third field is the font size, I'm not sure the units.

Thanks for answer, but I googled that out yesterday and I'm just looking for the name.

Here are instructions for finding the font names available in java your platform: https://alvinalexander.com/blog/post/jfc-swing/swing-faq-list-fonts-current-platform


text:
Assigning Pointers to arrays - incorrect results?
I'm trying to build a transmission frame for a workshop library for the Arduino Uno. I have the byte frame inside an array, give it to another function that builds a bit frame and then want to transmit that bit frame.
When I try to print out the arrays using the serial monitor, I get the correct results for the entire byte array and correct results for the bit array up to a certain point. However, since my output (that I'm checking using a logic analyzer) had also more incorrect values when trying to print the values, I suspect it might have to do with timing issues from my transmission and Serial.print.
I thus tried to make another pointer (in the code below frameCheck) to print that out after I'm done transmitting my frame, which still leaves me with results that are different from what my logic analyzer tells me from a certain point onwards.
My byte array is as follows:
10100101  // Preamble
10000000  // First line of my image
00100000
00010000
01000000
00000000
00000000
00000000
00000000  // Last (8th) line of my image
11110000  // Checksum

These values are also represented in the bit array (before assignment to what in my code be called _frame as well as after that). However, when I read the values from the logic analyzer, the checksum is transmitted as 11111111 instead of 11110000.
Here is my code in the .cpp file:
Transmitter::Transmitter()
{
  [...]
  _frame = new uint8_t[90];
  frameCheck = _frame;
  [...]
}

[...]

int Transmitter::prepFrame(LEDBitmap image) {
  if(_busy) return -1; //no Data can be sent right now since the transmitter is already busy
  if(!_pin) return -2;
  /** construct the frame that is to be transmitted
    *
    * frame structure is
    * 1 byte preamble (0xA5) | 8 byte payload | checksum
    *
    * the image will be transmitted in rows
    * with one row being one byte
    *  1  2  3  4  5  6  7  8   <-- 1st byte
    *  9 10 11 12 13 14 15 16   <-- 2nd byte
    * 17 18 19 20 21 22 23 24   <-- 3rd byte
    * ...                           ...
    */
  uint8_t size = 10;
  uint8_t frame[size];
  uint8_t checksum = 0x00;

    for(uint8_t h = 0; h < image.getHeight(); h++) {
      uint8_t value = image.getBitmap()[h];
      checksum = (checksum + value) % 255;
      frame[h+1] = value;
    }

    for(uint8_t h = image.getHeight(); h < 8; h++) {
      frame[h+1] = 0x00;
    }

  // building the frame
  frame[0] = PREAMBLE;
  frame[size-1] = checksum;

//The byte frame "frame" is correct at this point

  _frame = buildBitFrame(frame, size);

//The frame built by this function (see below) as well as the bit frame "_frame" have the correct checksum

  frameCheck = _frame;  // <-- This is the checkFrame which I print in my .ino which gives me false results.

  // set the transmitter into busy mode so the idle pattern will no longer
  // be transmitted but instead the frame will be sent out.
  _busy = true;
  _pos = 0;

  return 1; //preperation was successful
}

uint8_t* Transmitter::buildBitFrame(uint8_t* frame, uint16_t size) {
  _frameSize = size*8;
  uint8_t bitFrame[_frameSize];
  int pos = 0;
    for (size_t byte = 0; byte < size; byte++) {
      for (size_t bit = 0; bit < 8; bit++) {
        bitFrame[pos] = (frame[byte] >> (7 - bit)) & 0x01;
        pos++;
      }
    }

  return bitFrame; // <-- This frame is correct as well.
}

void Transmitter::transmitBit() {
  if(_active) {
    // Preperation
    // only change the state when the manchester bit is completely transmitted.
    if(!_manHalf) {
      if(_busy) {
        // if there is currently a transmission running
        // read the next bit from the frame
        _state = _frame[_pos];
        if(_pos >= _frameSize) {
          _busy = false;
          _state = 0;
          _pos = 0;
        }
        _pos++;
      } else { // else transmit the idle pattern
        _state = 0;
      }
    }
    // Transmission
    if (!_manHalf) {
      digitalWrite(_pin, !_state);
    } else {
      digitalWrite(_pin, _state);
    }
    _manHalf = !_manHalf;
  } else {
    digitalWrite(_pin, HIGH);
  }
}

[...]

The corresponding, relevant lines in the header file are as follows:
[...]

class Transmitter
{
  public:
    Transmitter();

  public: //methods
    int sendData(LEDBitmap image);
    void transmitBit();
    [...]
    uint8_t* frameCheck;

  private: //members
    uint8_t _state;
    uint8_t* _frame;
    [...]

    int prepFrame(LEDBitmap image);
    uint8_t* buildBitFrame(uint8_t* frame, uint16_t size);
    [...]

};

[...]

The function transmitBit() is called every 1ms via a ISR.
Last but not least, here is my arduino sketch:
[...]

Transmitter transmitter;

[...]

int smallData[] = {1, 0, 0, 0,
                   0, 0, 1, 0,
                   0, 0, 0, 1,
                   0, 1, 0, 0};

LEDBitmap small(4, 4, smallData);

void setup() {
  Serial.begin(2000000);
  transmitter.setPin(4);
  transmitter.start();
  delay(200);
  pinMode(5, OUTPUT);
  digitalWrite(5, HIGH);
  transmitter.sendData(small);
  delay(1000);
  for(int a = 0; a < 88; a++) {
    Serial.println(transmitter.frameCheck[a]);
  }
}

The loop is currently empty.
Now onto the weird results I'm getting from printing checkFrame (which I have also already gotten when trying to print the full arrays inside my cpp). This is what it printed (already grouped in bytes):
1 0 1 0 0 1 0 1
1 0 0 0 0 0 0 0
0 0 1 0 0 0 0 0
0 0 0 1 0 0 0 0
0 1 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0        // Up to here everything is fine.
0 0 0 0 0 2 149 0      // On the logic analyzer this line reads 0x00 as it should
221 5 15 0 2 149 0 1   // On the logic analyzer this line reads 0xff instead
1 222 0 98 2 149 8 218 // This line is irrelevant as it is only a buffer I added to see if the problem lies within my array not having enough space

Now onto my questions!
Do you have an idea what could cause this? Did I do the array assignment wrong? Could this just be an issue with the timing of the Serial.prints and my transmitter going off every 1ms? But why does my logic analyzer say that the last line is 0xff then? Do you have any idea how to fix this?
I'd be super glad if you responded as quickly as possible.
Thanks in advance!
EDIT: After increasing the initial value of a in my sketch to 64, I found out that the 8th byte is still 00000000 as it says on the logic analyzer. However, the checksum still was a mess. This did also not improve a lot after increasing it to 72. It then was 1 1 2 149 8 218 5 15. These last few values did also not change when I increased a again to 74.

_frame only holds the bits. It is a uint8_t array since that's the smallest possible data size.

The first for loop is dangerous: You might write data beyond the boundaries of your 10 byte buffer if image.getHeight() is big enough

uint8_t* Transmitter::buildBitFrame(uint8_t* frame, uint16_t size) {
  _frameSize = size*8;
  uint8_t bitFrame[_frameSize];
  int pos = 0;
    for (size_t byte = 0; byte < size; byte++) {
      for (size_t bit = 0; bit < 8; bit++) {
        bitFrame[pos] = (frame[byte] >> (7 - bit)) & 0x01;
        pos++;
      }
    }

  return bitFrame; // <-- This frame is correct as well.
}

You are returning a pointer to a function-local array which was allocated on the stack. After the function exists the stack for that function gets de-allocated and the array becomes invalid.
It may be valid for a short time after the function exists, but as soon as new functions are called and variables are allocated on the stack, this gets overwritten.
See https://www.fayewilliams.com/2015/06/30/a-challenge-discussion-returning-pointers-to-local-variables/
In cases like these (especially with a constant maximum frame length), you should re-write your memory management to use statically allocated buffers within your class.
For example:
uint8_t* _frame;

to
#define SOME_MAX_SIZE 128
uint8_t _frame[SOME_MAX_SIZE];

And then re-write functions to write into these buffers instead of allocating new memory every time.
Dynamic memory allocation in general should be avoided at all costs on a microcontroller due to heap fragmentation.
If you really want to keep doing it you could also allocate a new frame of the required length and make sure to delete it after usage!
uint8_t* Transmitter::buildBitFrame(uint8_t* frame, uint16_t size) {
  _frameSize = size*8;
  uint8_t* bitFrame = new uint8_t[_frameSize];
  int pos = 0;
    for (size_t byte = 0; byte < size; byte++) {
      for (size_t bit = 0; bit < 8; bit++) {
        bitFrame[pos] = (frame[byte] >> (7 - bit)) & 0x01;
        pos++;
      }
    }

  return bitFrame; //return pointer to malloced array, okay now.
}

Thanks! I didn't think of that. That would explain the behavior! What'S the best way to fix this though?

@Lithimlin I've addressed that.

Hmm, I'm not quite sure when I could delete it, especially since bitFrame is defined within the local function. I mean, I can't just write delete [] bitFrame anywhere in my code, can I?

Or would a delete [] _frame inside the transmitBit() where I set _busy = false be enough?

The uint8_t* bitFrame = new uint8_t[_frameSize]; sure did the trick, but I still don'T know where to delete it again. Attempting to delete _frame inside transmitBit() resulted in the controller not doing anything anymore so I guess that's not how to do it.

@Lithimlin If you don't know when to delete the object that might indicate that the object needs to be always there and it made no sense to dynamically allocate it in the first place -- allocate it statically then. Or re-think the life-time of that object (maybe there is endTransmission() function that releases all memory?). There are multiple ways.

The way I understand it is the following:
Whenever the line uint8_t* bitFrame = new uint8_t[_frameSize]; is called, new memory gets allocated. This means if I call it 5 times without deleting in-between, I have space for 5 such arrays reserved and not usable. So wouldn't not deleting it quickly cause problems then?
Also I've already tried statically allocating them the way you suggested but I then get an error message telling me that there'S no definition on how to make a uint8_t[] from a uint8_t* (which is returned by my function)

@Lithimlin If you do a classMemberVariable = new uint8_t[someSize] 5 times while not deleting the pointer in between, you overwrite the old pointer reference to the allocated memory. Now you can never free that memory again because you don't have a pointer to it -- that's a memory leak. @static allocation: If you have a buffer inside as a class member, then you need to memcpy into it (or just write to it directly). If you upload a zip file with your project somwhere (googledrive, dropbox), I can have a look at it.

Let us continue this discussion in chat.


text:
TimerOne Library - Response time
I'm trying to write a library for (rather slow) communication with visible light and have recently tried to include the TimerOne library as a timer.
I want to send bits at 2kHz, so with a period of 500µs. I'm initializing the Timer1 with 500(µs) like this and then attach an interrupt to it to call my transmit function:
Timer1.initialize(500);
Timer1.attachInterrupt(transmitBit);

However, when I try to measure the period with a logic analyzer, it tells me that there is actually a period of 2,000µs. Could this be due to some overhead created by the library? Where else could the problem be?
If you need any other information just let me know and I'll try to provide it.
Thanks in advance for your feedback.
EDIT: I've just tried adding the period as a parameter to the attachInterrupt like so:
Timer1.attachInterrupt(transmitBit, 500);

And now I'm measuring a period of 30µs for whatever reason? Can anyone explain me what's going on?
EDIT: This is the rest of my (relevant) code:
Transmitter::Transmitter()
{
  [...]
  Timer1.initialize(500);
}

Transmitter* Transmitter::_instance;

void Transmitter::start() {
  _instance = this;
  Timer1.attachInterrupt(_transmitBit, 500);
  _active = true;
}

static void Transmitter::_transmitBit() {
  _instance->transmitBit();
}

void Transmitter::transmitBit() {
  if(_active) {
    //Preperation
    if(!_manHalf) { //only change the state when the manchester bit is completely transmitted.
      if(_busy) {
        //Serial.println("Transmitting!");
        /** if there is currently a transmission running
          * read the next bit from the frame
          */
        _state = *(_frame + _pos);
        if(_pos >= _frameSize) {
          _busy = false;
          _state = 0;
          _pos = 0;
        }
        _pos++;
      } else { //else transmit the idle pattern
        _state = 0;
      }
    }
    //Transmission
    if (!_manHalf) {
      digitalWrite(_pin, !_state);
    } else {
      digitalWrite(_pin, _state);
    }
    _manHalf = !_manHalf;
  } else {
    digitalWrite(_pin, HIGH);
  }
}

please post all the code

That's going to be a lot but alright

then post minimal code that demonstrates the problem.

Yes, that's what I did

@jsotola got any idea as to why it wouldn't work?

narrow down the area that is causing the problem by reducing the transmitBit() code to only digitalWrite() and some supporting code that alternates the bit value between 1 and 0

I've had it work before with a different timer but I can't use that anymore

Is there a question here?

Before using libraries, try to see whether you can manipulate the timer registers directly to achieve what you want.  You may find it is easier!
In the following example I assume you are using an ATmega328 chip.  The code may be slightly different for other microcontrollers.  In that case you can read the data sheets for both microcontrollers and work out what you need to change.
I also assume the data you want to transmit is stored in a byte array.  Initialize the data how you prefer.
e.g: byte my_data[10] = {0,0,0,0,0,0,0,0,0,0};
Next, you want to initialize timer1 in the main loop
TCCR1A=0;
TCCR1B=0;

To send data at 2000 bits per second, the following settings can be used
ICR1=124; // Timer counter resets to 0 after reaching 124
OCR1A=125;
OCR1B=125; // other counter match registers must be higher than ICR1
TCCR1A=B00000010; // waveform generation mode 14, fast PWM, ICR1=top
TCCR1B=B00011011; // clock scaler 64, 1 count = 4 us.  125*4 us = 500 us
TIFR1 |= (_BV(ICF1) | _BV(OCF1A) | _BV(OCF1B)); // Clear match flags

This will set the timer1 match register bit ICF1 every 500 us.  There are several ways of using the timer to send the data.  My preference would be to poll the match flag.  The timing precision is about as good as you can get - a couple of clock cycles:
loop_until_bit_is_set(TIFR1,ICF1); // wait until TCNT1=ICR1
TIFR1 |= (_BV(ICF1) | _BV(OCF1A) | _BV(OCF1B)); // clear match flags
// switch digital output high or low depending on data bit to be sent

One way is to run a state machine loop like this:
unsigned int state;

void setup(){
state=0;
}

void loop(){
switch (state){
case 0: // idle or receiving data to be sent
TCCR1A=0;
TCCR1B=0;
// insert other code here
// conditional function, when message data received, set state=1;
break;

case 1: // setup timer
ICR1=124; // Timer counter resets to 0 after reaching 124
OCR1A=125;
OCR1B=125; // other counter match registers must be higher than ICR1
TCCR1A=B00000010; // waveform generation mode 14, fast PWM, ICR1=top
TCCR1B=B00011011; // clock scaler 64, 1 count = 4 us.  125*4 us = 500 us
TIFR1 |= (_BV(ICF1) | _BV(OCF1A) | _BV(OCF1B)); // Clear match flags
state=2;
break;

case 2:
loop_until_bit_is_set(TIFR1,ICF1); // wait until TCNT1==ICR1
TIFR1 |= (_BV(ICF1) | _BV(OCF1A) | _BV(OCF1B)); // clear match flags
// switch digital output high or low depending on data bit to be sent

// add conditional function so that when you are finished sending data, reset to state=0;
break;

}
}

As always, please upvote if you find this helpful.


text:
Passing non-static member function using bind
I'm using the GxEPD2 library to communicate with an E-Paper display. I now wanted to use the drawPaged method of this library with an object display.
I also have written my own class from which I want to print stuff on the display.
Here's the relevant code for the MyClass.h:
class MyClass{
    //some variables and methods
    void drawClass(); //this is public
    void drawClassCallback(const void* v1); //this is private
    //    this is actually a uint8_t --^
}

And here's the MyClass.cpp:
void MyClass::drawClass(){
    //some display preparation
    uint8_t var; //A variable to pass information from the callback to this method since it is needed later
    display.drawPaged(std::bind(&MyClass::drawClassCallback, this, &var));
    //some code where I need var with info from the callback
}

I'm getting the following error:

no matching function for call to 'GxEPD2_BW::drawPaged(std::_Bind_helper::type)'
note: candidate: void GxEPD2_BW::drawPaged(void ()(const void), const void*) [with GxEPD2_Type = GxEPD2_290; short unsigned int page_height = 296u]
       void drawPaged(void (drawCallback)(const void), const void* pv)

I've also tried display.drawPaged(std::bind(&MyClass::drawClassCallback, this, std::placeholders::_1), &var) without success.
I've stumbled upon this post already, however the solution presented there (and the one used above) does not work in this case.
Why is that?

In your MyClass example, the drawPaged() call is given only a single argument, while according to the library, it needs two:
void drawPaged(void (*drawCallback)(const void*), const void* pv)

The first argument is the function pointer (or the one wrapped by std::bind!). The second argument seems to be some data that will be passed on to that function. (according to the [linked API)
The error actually explains it, it suspects that you are trying to call void GxEPD2_BW::drawPaged(void ()(const void), const void*). Hence it mentions this as a candidate.
What you need to do is something like this:
display.drawPaged(std::bind(&MyClass::drawClassCallback, this, std::placeholders::_1), &var);

std::placeholders::_1 is the placeholder that represents the var argument that will be passed on when it is called.


text:
Undocumented industrial servo with 8-wire encoder: how to read this encoder?
I have scavenged an industrial servo with its attached ballscrew linear actuator from an old large format scanner, and I am trying to figure out how to make a 'servo drive' aka 'servo driver' aka 'servo controller'.
I'm a total novice at arduino, and am mostly a copy/paste coder - so of course this makes my goal harder.
I can find a lot of information on how to read a simple AB offset encoder that needs four wires to work, but the encoder I have has eight wires:
A+, A-, B+, B-, Z+, Z-, +5v, 0v(aka GND)
With +5v supplied to it's wire and GND connected to 0v, rotating the motor shaft by hand, my meter reads:

A+: +3.97v as the 'high' and +.036v as 'low'
A-: same
B+: same
B-:    same
Z+: same - but only goes high at one location on the 360 degree
 rotation
Z-: same - but only goes high at one location on the 360 degree
rotation - the same location as Z+

NOTE: Both Z pulses coincide with pulses on A+, B+, and B- ... but those are NOT coincident on A-. So maybe A- has the Z+/- trigger in it's place? I don't know. It was VERY challenging to stop rotating the shaft AT a pulse because of the tiny size of the divisions.
All voltages seen by my digital multimeter were positive voltages.
I do not understand how to properly use the encoder with so many wires. I can sort of understand that the positive and negative are probably opposite signals from each other, sort of error protection or something? I know that the Z= and Z- are roattion counters at either 90, 180, or some other offset angle to allow ticking full rotations. But am unsure about this all and am reading a lot of material that is beyond me. I'm stumped.
I can install the following code on an UNO and the UNO reads the encoder just fine off the A+ and B+ lines, with increasing count for one direction of rotation and decreasing count for the other direction. So it is reflecting the movement as it should...
BUT- I am getting 8000 pulses per shaft revolution rather than the 2000 pulses per revolution in the documentation. So something's not right here. I should see 2000 pulses per revolution... is this because of the lack of use of the other wires? Or something else?
Code i'm using for just A+ and B+:
    /*
*Quadrature Decoder
*/
#include "Arduino.h"
#include <digitalWriteFast.h>

// Quadrature encoders
// Left encoder
#define c_LeftEncoderInterruptA 0
#define c_LeftEncoderInterruptB 1
#define c_LeftEncoderPinA 2
#define c_LeftEncoderPinB 3
#define LeftEncoderIsReversed

volatile bool _LeftEncoderASet;
volatile bool _LeftEncoderBSet;
volatile bool _LeftEncoderAPrev;
volatile bool _LeftEncoderBPrev;
volatile long _LeftEncoderTicks = 0;

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

  // Quadrature encoders
  // Left encoder
  pinMode(c_LeftEncoderPinA, INPUT);      // sets pin A as input
  digitalWrite(c_LeftEncoderPinA, LOW);  // turn on pullup resistors
  pinMode(c_LeftEncoderPinB, INPUT);      // sets pin B as input
  digitalWrite(c_LeftEncoderPinB, LOW);  // turn on pullup resistors
  attachInterrupt(c_LeftEncoderInterruptA, HandleLeftMotorInterruptA, CHANGE);
  attachInterrupt(c_LeftEncoderInterruptB, HandleLeftMotorInterruptB, CHANGE);
}

void loop()
{
  Serial.print("Encoder Ticks: ");
  Serial.print(_LeftEncoderTicks);
  Serial.print("  Revolutions: ");
  Serial.print(_LeftEncoderTicks/2000.0); //2000 Counts Per Revolution, per the engineering manual
  Serial.print("\n");
}

// Interrupt service routines for the left motor's quadrature encoder
void HandleLeftMotorInterruptA(){
  _LeftEncoderBSet = digitalReadFast(c_LeftEncoderPinB);
  _LeftEncoderASet = digitalReadFast(c_LeftEncoderPinA);

  _LeftEncoderTicks+=ParseEncoder();

  _LeftEncoderAPrev = _LeftEncoderASet;
  _LeftEncoderBPrev = _LeftEncoderBSet;
}

// Interrupt service routines for the right motor's quadrature encoder
void HandleLeftMotorInterruptB(){
  // Test transition;
  _LeftEncoderBSet = digitalReadFast(c_LeftEncoderPinB);
  _LeftEncoderASet = digitalReadFast(c_LeftEncoderPinA);

  _LeftEncoderTicks+=ParseEncoder();

  _LeftEncoderAPrev = _LeftEncoderASet;
  _LeftEncoderBPrev = _LeftEncoderBSet;
}

int ParseEncoder(){
  if(_LeftEncoderAPrev && _LeftEncoderBPrev){
    if(!_LeftEncoderASet && _LeftEncoderBSet) return 1;
    if(_LeftEncoderASet && !_LeftEncoderBSet) return -1;
  }else if(!_LeftEncoderAPrev && _LeftEncoderBPrev){
    if(!_LeftEncoderASet && !_LeftEncoderBSet) return 1;
    if(_LeftEncoderASet && _LeftEncoderBSet) return -1;
  }else if(!_LeftEncoderAPrev && !_LeftEncoderBPrev){
    if(_LeftEncoderASet && !_LeftEncoderBSet) return 1;
    if(!_LeftEncoderASet && _LeftEncoderBSet) return -1;
  }else if(_LeftEncoderAPrev && !_LeftEncoderBPrev){
    if(_LeftEncoderASet && _LeftEncoderBSet) return 1;
    if(!_LeftEncoderASet && !_LeftEncoderBSet) return -1;
  }
}

.
.
.
Can someone explain the function of, and how to use, all eight wires? Explain why I'm getting 4X the counts that I should with that code above? PLEASE?
.
.
.
I'm posting images of the pages from the machine's engineering handbook that have info about the servo and encoder. The info there shows that it was more or less controlled like an RC servo from the mainboard's perspective - just PWM. But it had the drive/driver/controller parts right on the mainboard of the machine.
If it will be of use I can post pictures of the encoder board itself, but at this point I did not think that necessary.

connect +5V and GND to the encoder ... use a voltmeter to monitor one output pin ... turn servo slowly by hand

Wire identity is already established. See picture posted of pinout table.

if that is true, then why does your post have the following statement? ... positive and negative are probably opposite signals from each other, sort of error protection or something

I put that in my post because I have read a few web pages that say that this is how some encoders work. And you didn't quote the question mark immediately following the word 'something". I have added voltage readings for all wires to the question.

I had some trouble figuring this out too.
I did some more googling and found this site below via an Arduino forum post:
8 wire connection for quadrature encoder, differential wiring
Here is what they say:

"These terms refer not to the waveforms of signals, but instead to the way the signals are wired.
Single-ended wiring uses one signal wire per channel and all signals are referenced to a common ground.
TTL and Open Collector are types of single-ended wiring.
Differential wiring uses two wires per channel that are referenced to each other. The signals on these wires are always 180 electrical degrees out of phase, or exact opposites. This wiring is useful for higher noise immunity, at the cost of having more electrical connections. Differential wiring is often employed in longer wire runs as any noise picked up on the wiring is common mode rejected."

So basically we have our Power supply wire and ground, and 2 wires per signal (A+/A-, B+/B-, Z+/Z-).
2 + 6 wires = 8 wires
Now all I have to figure out is how to connect those 6 wires to an Arduino. I get how to connect the A+, B+, Z+ signals on 3 interrupt pins, now I'm just wondering if the other 3 (A-, B-, Z-) should be connected to 3 more interrupt pins.

The differential signals should be connected to a differential amplifier or an instrumentation amplifier. The amplifier will give a single output that can be connected to the Arduino via galvanic isolation.

You have already found out, how the encoder works (basically like any other rotary encoder, only with more outputs for different angle values). That is great work.
You get a value 4 times as big because of 2 little mistakes:

When you use attachInterrupt(), you set it to trigger on a CHANGE of the line. One pulse consists of 2 changes (for example LOW to HIGH and then HIGH to LOW). So the interrupt get's triggered twice per encoder pulse. That's a factor of 2 for the resulting value.
You attach an interrupt to both of the lines, but both lines output one pulse per one encoder tick. So the value get's incremented twice per tick, what means another factor of 2. You only need an interrupt on one of the lines. The other line is only there to indicate the direction of the rotation. When the interrupt for the first line triggers, you should check the value of the second line. If it is HIGH, the encoder is rotating in one direction. If it is LOW, it rotates in the oposite direction. The lines are internally connected to little buttons/switches, that are fixed to the casing with a little offset between then. They get activated by little nubs, that are connected to the axis. Depending on from which direction the nub comes during a rotation, the first or the second button/switch will get activated first. A little after that, also the second switch will activate. So you can monitor one line, and if a pulse starts on it, you check if there already is a pulse on the other line. If yes, the other line was activated first.

So all in all this results in the factor 4 in the encoder results.

Note, that your ParseEncoder() function is a little redundant and overcomplicated. In the inner if statements you check for some values, that cannot happen in there because of the outer if statement. But this function will reduce itself to simply one if statement (or less, if you use the value directly without if), since with the above, you only need to check the value of 1 line.

OK - learning that quadrature encoding can be read as 1x, 2x, or 4x per rotor mark is not the same as learning how this particular encoder works. Using A+ and B+ I count all four possible ticks as a rotor mark passes. Z+ would theoretically let me count full rotations and serve as a check against missed triggers by the A+ interrupt - if I could figure out how to interrupt interrupts because Z+ rises at the same time that A+ rises. Got it. But A- and B- and Z- remain unexplained/not understood. Not that I MUST use them, but I do want to understand what they are there for if I can.

Unfortunately I cannot help you with undocumented hardware, as I cannot test it myself. You yourself have to analyse how the outputs behave. If you make a diagram, how exactly the outputs behave, I can try to guess the function, but not more.

Fair enough. My assumption (and reason for posting) was that someone here in the stack would read "8 wire encoder" and then read my reported voltages .. and be familiar with similar encoders enough to illuminate me on what the other wires are for and maybe even how to use them. I still have a sneaking suspicion they are a redundancy to error-check with but can't be sure with my almost non-existent knowledge of these things.

Still hoping someone will explain the other three wires: A-, B-, and Z-. Can't mark this answer as the answer without having the first part of the question addressed.


text:
ESP8266 Stops Working After A While (Unknown Problem)
have an esp8266.
i'm trying to create a DDNS updater.
it has to wait 5 min then do a GET request to a URL.
Here's my code:
/* Code For DNS Updater.*/

#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>

#define LOOP_TIME 300000

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

const String address="http://dynamicdns.park-your-domain.com";
const String path="update";
const String pathHost="host";
const String pathPassword="password";
const String pathDomain="domain";

const String dnsName="my-example-host.com";
const String ddnsPassword="my-example-password";
const String updateHosts[]={
    "@",
    "subdomain1",
    "subdomain2",
  };

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

long nextUpdate=0;

void loop() {
  if(nextUpdate<millis()){
    if (WiFi.status() == WL_CONNECTED) {
    updateDNS();
    }else{
      connectWiFi();
    }
    nextUpdate=millis()+LOOP_TIME;
  }
}

void updateDNS(){
  Serial.println("Updating Hosts:");
  for(int host=0;host<(sizeof(updateHosts)/sizeof(String));host++){
    Serial.print(updateHosts[host]+": ");
    String assembledURL=address+"/"+path+"?"+pathHost+"="+updateHosts[host]+"&"+pathDomain+"="+dnsName+"&"+pathPassword+"="+ddnsPassword;
//    Serial.println("Host: "+updateHosts[host]+" URL: "+assembledURL);
    HTTPClient http;
    http.begin(assembledURL);
    http.GET();
    http.end();
    Serial.println("Done");
  }
}

void connectWiFi(){
  WiFi.begin(ssid, password);

  Serial.print("Connecting To ");
  Serial.println(ssid);
  Serial.print("Password: ");
  Serial.println(password);
  Serial.print("Connecting");
  while (WiFi.status() != WL_CONNECTED) {

    delay(500);
    Serial.print(".");

  }
  Serial.println();
  Serial.print("Connected To ");
  Serial.println(ssid);
}

and it stops after a couple of hours - which isnt good for a DDNS updater.
EDIT: maybe it has something to do with my timer. will try an unsigned long instead.

Hi @NadavTasher and welcome to the Arduino Stack Exchange community.  Unfortunately your question doesn't meet our quality standards.Your question is rather terse.  Please edit and improve it. See [ask] and How to ask a good question for Arduino Stack Exchange.

what version of esp8266 arduino package?

shouldn't if(nextUpdate<millis()){ be if(nextUpdate>millis()){, as in the timeout is past the current time?

no, cause if nextUpdate is for example 5000 and millis is 4000 we dont yet wanna run the update.

I have had the "stops after a while" too and it turned out to be heap memory consumption and fragmentation that caused not having enough stack and heap space any more.
My solution: check the heap from time to time (in loop) and reboot the node when it comes down to a practical limit.
Alternate: avoid using the String type and other Heap usages.


text:
Difference between char array and unsigned char array
I have written a small test code for Arduino Uno which is as follows:
unsigned char tes[4];
char testing[4];

void setup() {
    Serial.begin(9600);
    for (int i = 0; i < 4; i++) {
        testing[i] = i;
        tes[i] = i;
    }
    for (int i = 0; i < 4; i++) {
        Serial.print("unsigned char is: ");
        Serial.println(tes[i]);
        Serial.print("char is: ");
        Serial.println(testing[i]);
    }
}

void loop() {
}

and the output which I get is as follows
unsigned char is: 0
char is:
unsigned char is: 1
char is:
unsigned char is: 2
char is:
unsigned char is: 3
char is:

Can someone help me out why is the difference in output.

Why is this off-topic? Isn't the observed behaviour based on how the Arduino library in particular implements different type overloads and produces different outputs for char and unsigned char? Unlike e.g. what standard iostream seems to do: both unsigned char uc = 0x41; cout << uc << endl; and char c = 0x41; cout << c << endl; output A.

tl;dr : Since unsigned char is represented as a byte value, the output to the serial is the byte representation, not the char
I re-wrote the code you had for reference:
#define CHARS 255
#define BAUD 115200

unsigned char unsChar[CHARS];
char sinChar[CHARS];

void setup() {
  Serial.begin(BAUD);
  Serial.println("~~Setup~~");
  for(int i = 0; i < CHARS; i++) {
    unsChar[i] = (unsigned char)i;
    sinChar[i] = (char)i;
  }
}

void loop() {
  Serial.println("~~Loop~~");
  for(int i = 0; i < CHARS; i++) {
    Serial.print("INDEX        : ");
    Serial.println(i);
    Serial.print("unsigned char: ");
    Serial.println(unsChar[i]);
    Serial.print("         char: ");
    Serial.println(sinChar[i]);
    Serial.println("---------------------");
  }
  delay(10000);
}

When you run this you'll see the unsigned char is simply printed to the serial like any other byte value but the char value is printed as a character according to the ASCII chart.
If you compare the documentation for unsigned char

An unsigned data type that occupies 1 byte of memory. Same as the byte datatype.

The unsigned char datatype encodes numbers from 0 to 255.

For consistency of Arduino programming style, the byte data type is to be preferred.

versus a normal (signed) char:

A data type used to store a character value. Character literals are written in single quotes, like this: 'A' (for multiple characters - strings - use double quotes: "ABC").Characters are stored as numbers however. You can see the specific encoding in the ASCII chart. This means that it is possible to do arithmetic on characters, in which the ASCII value of the character is used (e.g. 'A' + 1 has the value 66, since the ASCII value of the capital letter A is 65). See Serial.println reference for more on how characters are translated to numbers.The size of the char datatype is at least 8 bits. It’s recommended to only use char for storing characters. For an unsigned, one-byte (8 bit) data type, use the byte data type.

So size wise an array of chars and unsigned chars are going to be the same. It's more about the representation of the underlying number (byte) and what works best for your use case.

An unsigned char is treated as a number, and a signed char as a character.
See the https://simple.wikipedia.org/wiki/ASCII table for the result.

This is not quite right. In C++, "char", "signed char" and "unsigned char" are THREE different types, not two. Of course in some sense "char" must be the same as one of the other two types, but  which two types are the same is implementation-dependent. Only "char" is interpreted as character data by default.

@alephzero thanks for the addition. Mostly it's better to cast to be sure.


text:
Connect multiple Arduinos to ESP32's RTC?

Depending on usage frequency, may get the occasional collision where
both test for availability at the same time - if occurring too
frequently, maybe add something simple like one arduino only does time
updates on even seconds, the other on odd seconds.

https://forum.arduino.cc/index.php?topic=64049.0
I need events executed in the multiple receiving Arduino's to occur in sync (simultaneously). Is there a library or something, probably using the ESP32's RTC, to ensure events occur in sync?
Example system:

ESP32 sender/master
Arduino1 receiver controlling LEDs (Christmas lights)
Arduino2 receiver controlling stepper motors (Mary figure)
Arduino3 receiver controlling stepper motors (Joseph figure)

The issue is that they are sent data at different times by the user.
Say, the user selects settings for Mary. That data is sent to the ESP32, and then that data is sent to all the Arduinos, but only "gets into" the MaryArduino.
Then, the user selects settings for the lights. That data is sent to the ESP32, and then data is sent to all the Arduinos, but only "gets into the LightsAruino.
Etc.
However, I need everything to start at the same time.
The data is not simultaneously sent. It is sent one after the other, as slow as the user selects their settings. However, the sequence of events must simultaneously occur.

moving an actuator, turning on a light, running a stepper motor a number of steps, etc.

why do the light and actuator have to be synchronized? ... what is their purpose?

Events need to happen at specific times: Think of a light show synchronized to music.

I said, "events executed in the receiving Arduino_>>'s<<_" but I edited the post with multiple in again (beside already being in the title).

You state: "I need events executed in the multiple receiving Arduino's to occur in sync". What is the tolerance you can allow, this will have a big impact on the plausibility and cost of the design. Is your software designed to be that way and do you know how many clock cycles each remote will do before performing the task, they must be the same to be fully in sync. If not how do you compensate for this difference and how do you detect an error.

light synchronized to music is not an example of simultaneous events, as far as the microcontroller is concerned  ... it only has to look synchronized to a human ... a microcontroller can go on vacation between two events and the two events would still look simultaneous to a human

Lights synchronized to music IS an example of simultaneous events since they are both done by different Arduino's (as that's how it's meaningfully related to the question asked).

@Gil No software has been designed. That's why I'm looking into this question. The idea is to use the ESP32's RTC connected to multiple receiving Arduinos. The ESP is the sender. Say three are connected. All three would be going off the ESP32's RTC.

it is unckear what the overall system consists of .... perhaps the simplest solution is to have a hardware clock signal that connects all of the arduinos

So gather the data from the sender, and hold until a digital signal is sent? E.g., lights get song, figure1 gets sequence of movements, then figure2 gets sequence of movements. Once the last event happens, wait part of a second and send a digital HIGH signal. And just have a simple if-statement waiting for that signal?

use serial, the ESP32 has 3 of them, and capability to do many more. the AVRs do stuff when told to over serial. the ESP32 tells them what to do over serial. Even though on a microscopic level the messages will be staggered by microseconds, it won't make a hill of beans difference to a light show, or even most scientific experiments.

I'm using one serial connection to send the commands to all the Arduinos (10-30). @dandavis Are you suggesting that same serial connection be used OR 10-30 additional serial out? The latter isn't really possible as you know.

@adamaero You can connect serial in parallel, ironically. if your high-level protocol allows all nodes to get the same broadcast, typically by each having an ID/tag it's "interested" in ala wifi/i2c, there's no real limit. If each line has to transmit different messages, then you can still easily do a dozen or two with an ESP32, since you only need TXs and it has a whole dang bunch of pins ;)

Yes, I have each Arduino addressed already: if(charArr1[0] == motionHead) strcpy(str2, charArr1); They are all being sent the same data, but only each one is receiving their specific data.

then just wire all the slave RXs together to the master's TX, and then send away. With a message format like "MARY=1;RED=1", at 57k baud, mary and the red light will turn on at the same time (fraction of a ms), even to a high-speed camera, much less a human.

Let us continue this discussion in chat.

Try this link for a paper by Autosar Specification of Time Synchronization over CAN: https://www.autosar.org/fileadmin/user_upload/standards/classic/4-3/AUTOSAR_SWS_TimeSyncOverCAN.pdf It has a lot of good information.

Give the master a single signal wire that is connected to all of the slaves and that signal LOW while the master sends commands to each slave. Let each of the slave Arduinos simply store its message but not act on it while the signal wire is LOW.
When the slaves are supposed to start, raise the signal level to HIGH. Each slave Arduino now executes whatever command it had been sent. The RTC now only needs to be connected to the Master, which controls all of the timing.


text:
Simple ESP to ESP reading blink program not reading input voltage
One ESP32's 3v3 is connected to GPIO 26 of another ESP32.
The program is uploaded. The built-in LED lights for two seconds as expected. Then, it turns off. No matter what GPIO pin the 3v3 is connected to (besides 2), the LED remains off.
/*
 * ON Board LED GPIO 2
 */

#define LED 2
#define inPin 26

void setup()
{
  Serial.begin(9600);
  // Pins 34, 35, 36, 39 are input only
  pinMode(LED, OUTPUT);

  // Sanity check LED works
  digitalWrite(LED, HIGH);
  delay(2000);
}

void loop()
{
  Serial.println(digitalRead(inPin));
  digitalWrite(LED, digitalRead(inPin));
}

Any reason this is happening? Grounds are connected. Simply trying to turn LED on/off if external voltage occurs at any GPIO pin (e.g., 26).

are you saying that you are attempting to power one ESP32 from the GPIO pin of another ESP32?

Have you connected the GND pins of the two ESP?

@jsotola .....no

@PeterPaulKiefer yes

you have a serial.println() statement in your code ... please add the resuling printout to your post

"0" ad infinitum

Arduino GPIO automatically set as inputs, so I assumed the same for ESP32. Once the pinMode of the input pin was set, it worked:
#define LED 2 // ON Board LED GPIO 2
#define inPin 26

void setup()
{
  Serial.begin(9600);
  // Pins 34, 35, 36, 39 are input only
  pinMode(LED, OUTPUT);
  pinMode(inPin, INPUT); // <----------
}

void loop()
{
  Serial.println(digitalRead(inPin));
  digitalWrite(LED, digitalRead(inPin));
}


text:
What is the most simple sketch to confirm the DAC works for audio on a speaker with it's own amplifier for an ESP32?
I have a PC speaker with it's owner power supply (no amplifier needed). It just uses a standard AUX jack.
Most examples sketches use an amplifier like the MAX98357A. I have explored some libraries too, such as ESP8266Audio.
I just want to find a simple example that emits audio (not just noise). This is my setup:

I thought an audio program would use the internal DAC to create the CODEC? Or am I not understanding something?
const int  DAC_CH1 = 25; // or 26

void setup()
{
//    dacWrite(DAC_CH1, 255); // ~3v3
//  dacWrite(DAC_CH1, 192); // ~2.5
//  dacWrite(DAC_CH1, 128); // ~1.7
}

void loop(){}

Edit
I found the PlayMODFromPROGMEMToDAC example, which uses pin 25 DAC:
#include <Arduino.h>
#include "AudioFileSourcePROGMEM.h"
#include "AudioGeneratorMOD.h"
#include "AudioOutputI2S.h"
#if defined(ARDUINO_ARCH_RP2040)
    #define WIFI_OFF
    class __x { public: __x() {}; void mode() {}; };
    __x WiFi;
#elif defined(ESP32)
    #include <WiFi.h>
#else
    #include <ESP8266WiFi.h>
#endif

// enigma.mod sample from the mod archive: https://modarchive.org/index.php?request=view_by_moduleid&query=42146
#include "enigma.h"

AudioGeneratorMOD *mod;
AudioFileSourcePROGMEM *file;
AudioOutputI2S *out;

void setup()
{
  WiFi.mode(WIFI_OFF); //WiFi.forceSleepBegin();
  Serial.begin(115200);
  delay(1000);

  audioLogger = &Serial;
  file = new AudioFileSourcePROGMEM( enigma_mod, sizeof(enigma_mod) );

   /* HERE! */
   // ↓
   // ↓
   out = new AudioOutputI2S(0, 1); //Uncomment this line, comment the next one to use the internal DAC channel 1 (pin25) on ESP32
   // ↑
   // ↑
//  out = new AudioOutputI2S();
  mod = new AudioGeneratorMOD();
  mod->SetBufferSize(3*1024);
  mod->SetSampleRate(44100);
  mod->SetStereoSeparation(32);
  mod->begin(file, out);
}

void loop()
{
  if (mod->isRunning()) {
    if (!mod->loop()) mod->stop();
  } else {
    Serial.printf("MOD done\n");
    delay(1000);
  }
}

Although, still no sound (besides noise) can be heard.

no need for DAC ... toggle a digital pin

What do you mean by "audio not just noise"? Can't you simply toggle the pins? An alternative would be to use the sin() function to generate a "clean" note.

Ideally something like talkMIDI(0xC0, instrument, 0) as found here: https://www.sparkfun.com/tutorials/302


text:
How to create minimal web server example with a dropdown menu?
I want to create a three-item menu: Verizon, T-Mobile, AT&T. Since the example uses LEDs, I'll do the same--except with a dropdown menu to select among the three.
I'm trying to combine these two examples:

https://randomnerdtutorials.com/esp8266-web-server
https://www.w3schools.com/html/tryit.asp?filename=tryhtml_elem_select

Except with phone carriers instead of cars:

I'm struggling on the polyglot part of the programming, combining the HTML and Arduino program in the middle:
        // Web Page Heading
        client.println("<form action='/action_page.php'>");
        client.println("  <select id='providor' name='providor'>");
        client.println("    <option value='verizon'>Verizon</option>");
        client.println("    <option value='tmobile'>T-Mobile</option>");
        client.println("    <option value='atnt'>AT&T</option>");
        client.println("  </select>");
        client.println("  <input type='submit'>");
        client.println("</form>");

        if (providor==verizon)
          client.println("
Provider Selected: Verizon
");
        else if (providor==tmobile)
          client.println("
Provider Selected: T-Mobile
");
        else if (providor==atnt)
          client.println("
Provider Selected: AT&T
");

Here is the rest of the program:
/*

Based from
https://randomnerdtutorials.com/esp8266-web-server

HTML tool
https://www.w3schools.com/html/tryit.asp?filename=tryhtml_elem_select
*/

#include <ESP8266WiFi.h>

// Replace with your network credentials
const char* ssid     = "REPLACE_WITH_YOUR_SSID";
const char* password = "REPLACE_WITH_YOUR_PASSWORD";

// Set web server port number to 80
WiFiServer server(80);

// Variable to store the HTTP request
String header;

// Auxiliar variables to store the current output state
//String output5State = "off";
//String output4State = "off";

// Assign output variables to GPIO pins
const int output5 = 14;    // D5 verizon
const int output6 = 12;    // D6 tmobile
const int output7 = 13;    // D7 atnt

// Current time
unsigned long currentTime = millis();
// Previous time
unsigned long previousTime = 0;
// Define timeout time in milliseconds (example: 2000ms = 2s)
const long timeoutTime = 2000;

void setup() {
  Serial.begin(115200);
  // Initialize the output variables as outputs
  pinMode(output5, OUTPUT);
  pinMode(output6, OUTPUT);
  pinMode(output7, OUTPUT);
  // Set outputs to LOW
  digitalWrite(output5, LOW);
  digitalWrite(output6, LOW);
  digitalWrite(output7, LOW);

  // Connect to Wi-Fi network with SSID and password
  Serial.print("Connecting to ");
  Serial.println(ssid);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  // Print local IP address and start web server
  Serial.println("");
  Serial.println("WiFi connected.");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
  server.begin();
}

void loop()
{
  WiFiClient client = server.available();   // Listen for incoming clients

  if (client) {                             // If a new client connects,
    Serial.println("New Client.");          // print a message out in the serial port
    String currentLine = "";                // make a String to hold incoming data from the client
    currentTime = millis();
    previousTime = currentTime;
    while (client.connected() && currentTime - previousTime <= timeoutTime) { // loop while the client's connected
      currentTime = millis();
      if (client.available()) {             // if there's bytes to read from the client,
        char c = client.read();             // read a byte, then
        Serial.write(c);                    // print it out the serial monitor
        header += c;
        if (c == '\n') {                    // if the byte is a newline character
          // if the current line is blank, you got two newline characters in a row.
          // that's the end of the client HTTP request, so send a response:
          if (currentLine.length() == 0) {
            // HTTP headers always start with a response code (e.g. HTTP/1.1 200 OK)
            // and a content-type so the client knows what's coming, then a blank line:
            client.println("HTTP/1.1 200 OK");
            client.println("Content-type:text/html");
            client.println("Connection: close");
            client.println();

            // turns the GPIOs on and off
            if (header.indexOf("GET /5/on") >= 0)
            {
              Serial.println("D5 on");
              output5State = "on";
              digitalWrite(output5, HIGH);
            }
            else if (header.indexOf("GET /5/off") >= 0)
            {
              Serial.println("D5 off");
              output5State = "off";
              digitalWrite(output5, LOW);
            }
            else if (header.indexOf("GET /6/on") >= 0)
            {
              Serial.println("D6 on");
              output4State = "on";
              digitalWrite(output6, HIGH);
            }
            else if (header.indexOf("GET /6/off") >= 0)
            {
              Serial.println("D6 off");
              output4State = "off";
              digitalWrite(output6, LOW);
            }
            else if (header.indexOf("GET /7/on") >= 0)
            {
              Serial.println("D7 on");
              output4State = "on";
              digitalWrite(output7, HIGH);
            }
            else if (header.indexOf("GET /7/off") >= 0)
            {
              Serial.println("D7 off");
              output4State = "off";
              digitalWrite(output7, LOW);
            }
            // Display the HTML web page
            client.println("<!DOCTYPE html>");
            client.println("<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">");
            client.println("<link rel=\"icon\" href=\"data:,\">");
            // CSS to style the on/off buttons
            // Feel free to change the background-color and font-size attributes to fit your preferences
            client.println("");

            // HERE
            // ↓
            // ↓
            // ↓
            // ↓

            // Web Page Heading
            client.println("<form action='/action_page.php'>");
            client.println("  <select id='provider' name='providor'>");
            client.println("    <option value='verizon'>Verizon</option>");
            client.println("    <option value='tmobile'>T-Mobile</option>");
            client.println("    <option value='atnt'>AT&T</option>");
            client.println("  </select>");
            client.println("  <input type='submit'>");
            client.println("</form>");

            if (providor==verizon)
              client.println("
Provider Selected: Verizon
");
            else if (providor==tmobile)
              client.println("
Provider Selected: T-Mobile
");
            else if (providor==atnt)
              client.println("
Provider Selected: AT&T
");

            // ↑
            // ↑
            // ↑
            // ↑

            client.println("");

            // The HTTP response ends with another blank line
            client.println();
            // Break out of the while loop
            break;
          } else { // if you got a newline, then clear currentLine
            currentLine = "";
          }
        } else if (c != '\r') {  // if you got anything else but a carriage return character,
          currentLine += c;      // add it to the end of the currentLine
        }
      }
    }
    // Clear the header variable
    header = "";
    // Close the connection
    client.stop();
    Serial.println("Client disconnected.");
    Serial.println("");
  }
}

Any suggestions or solutions on how to change or the correct code?

what do you expect the drop down menu to do?

Change a "provider" variable to whichever is selected. And in this case, turn on the LED corresponding to it (one of three LEDs should be on).

put the HTML code for the drop down menu right after the second button

I use

Look at the code in your post. It is syntax-highlighted, i.e. color-coded according to the grammar of the C++ language. Don't you see something weird with the colors around “HERE”? That's the syntax-highlighter showing you your syntax error.

And, further up in the first code block. Your quotes are not matching, all over the place.

First thing: be careful with matching your quotes. Every string literal
should be written as "bla, bla, bla", with no unescaped double-quotes
in between. Do use the syntax highlighting: it is here precisely for
helping you spot this kind of trivial programming mistakes. Also, for
writing very long constant strings, use the C++ “raw string literal”
feature: it just makes this easier.
Second thing, you should understand how a form submission works at the
HTTP level. You should be able to find the info on the Web but, to make
it short, when the user clicks on your form, the browser will send a
request looking like
GET /action_page.php?providor=verizon HTTP/1.1
Some-Header-Name: some header value
Other-Header-Name: other header value
...

You should parse this to find the actual provider between the '='
character and the following space. Also, get rid of action_page.php,
it is useless here.
Then a few random remarks:

Do not write “providor”: the correct spelling is “provider” (although
you may prefer “carrier” in this context).

Within an HTML document, the ampersand should be written &.

The HTML page needs a <title> element to be valid.

Remove the whole section of the code titled “turns the GPIOs on and
off”: it does not make sense in your context.

Now, to illustrate these points, here is how I would code parsing the
request:
// Find the provider in the URL.
String provider;
const String provider_before = "GET /?provider=";
int request_begin = header.indexOf(provider_before);
if (request_begin < 0) {
    provider = "unknown";
} else {
    int provider_begin = request_begin + provider_before.length();
    int provider_end = header.indexOf(' ', provider_begin);
    provider = header.substring(provider_begin, provider_end);
}

And here is how I would send the page to the client:
// At the beginning of the sketch (in global context).
const char page_before_provider[] = R"rawstr(<!DOCTYPE html>

<title>Phone carrier selection</title>
[...]

Provider Selected: )rawstr";
const char page_after_provider[] = "
\n\n\n";

// At the place where the page has to be sent.
client.print(page_before_provider);
if (provider == "verizon")
    client.print("Verizon");
else if (provider == "tmobile")
    client.print("T-Mobile");
else if (provider == "atnt")
    client.print("AT&T");
else
    client.print(provider);
client.print(page_after_provider);

For the global const char stuff, I am confused. Is that a function I should create? Tried putting some of that in, but pretty confused: https://github.com/adamaero/WebServer/blob/main/polyglot/ESP8266dropDownMenu/ESP8266dropDownMenu.ino

@adamaero: No, not in a function. “Global context” means outside any function. It's a constant declaration, just like ssid, to put at the beginning of the program. PS: do not worry about this until after you fix the first, most important issue: get your quotes matched.

Quotes were matched.

Since all the current answers are not clear to me, I'll try to come up with my own with `const char page_before_provider[] = R"rawstr(
)rawstr";`

@adamaero: 1. Do you believe quotes are matches in client.println("
carrier Selected: T-Mobile"
 ");? 2. If something is not clear in this answer, please tell what exactly you do not understand, so I can elaborate on that specific point.

Ok, now the quotes are matched... in the pseudo code that doesn't do anything to begin with.

Apart from the syntax errors (you aren't matching double quotes in multiple places) web pages don't work like that.
To do something like your form you:

Send the form, more-or-less like you have.

   if (providor==verizon)
       client.println("
Providor Selected: Verizon
");

You can't test the providor (provider?) right there. Do you mean if (providor=="verizon")?

The form has to be sent to the client, the user has to fill it in, and send it back. Thus you can't test for what they filled in a line or so under sending the form.

So, testing for what they entered is a subsequent step. It's a little hard to explain without taking dozens of paragraphs. I suggest reading up on how web forms work.

Here's an analogy:
Say you want to write to a company and apply for a job. You fill in a form and send it off. You do not, a moment later, check to see if you got the job. The form has to go to the company. Someone has to process it. Then they make a reply. The reply might say "in reference to your job application of 11 September 2023 you were/were not successful."
It's like that with HTML. The form, which the user fills in, is the initial step. Then the user fills it in. That might be an hour later. Then they press Send and the reply comes back to you. That's when you process the reply.


text:
Stepper motor micros (millis) non-blocking delay simple example?
I am trying to get a simple non-blocking replacement for:
digitalWrite(stepPinX, HIGH);
delayMicroseconds(500);
digitalWrite(stepPinX, LOW);
delayMicroseconds(500);

This is what I tried, and the stepper motor stays still:
const int dirPinX = 0;
const int stepPinX = 2;

unsigned long startMicros = micros();
unsigned long currentMicros;
const unsigned long period = 500;

void setup()
{
  pinMode(stepPinX, OUTPUT);
  pinMode(dirPinX, OUTPUT);

  digitalWrite(dirPinX, HIGH);
}

void loop()
{
  stepX();
}

void stepX()
{
  currentMicros = micros();  //get the current "time" (time since program start)

  if (currentMicros - startMicros >= period)  //test whether period elapsed
  {
    digitalWrite(stepPinX, HIGH);
  }
  if ((currentMicros - startMicros >= period) && (currentMicros - startMicros <= period*2))
  {
    digitalWrite(stepPinX, LOW);
  }

  startMicros = currentMicros;
}

Any suggestions on how to correct this? (I do not want to use a library like Accelstepper. I want to use millis/micros.)

the second if statement will execute only very infrequently ... why have a separate if statement for the two output states?

edited question and program

do only one if (currentMicros - startMicros >= period) ... keep track of stepPinX state

Your stepX() function looks like this:
void stepX()
{
  currentMicros = micros();
  // conditionally do some stuff..
  startMicros = currentMicros;
}

Since there is nothing that can block it, it will always execute very
fast. This means that, by the time the function returns, startMicros
will be very close to the current time. Then, on the following call,
currentMicros - startMicros will be very small, way smaller than
period, and the conditional code will never execute.
The solution is to change the meaning of startMicros: instead of
representing the time of the last call to stepX(), let it represent
the time when the last step started. For this, you have to reset it only
when finishing a step:
void stepX()
{
  currentMicros = micros();
  if (currentMicros - startMicros < period) {           // 1st phase
    digitalWrite(stepPinX, HIGH);
  } else if (currentMicros - startMicros < 2*period) {  // 2nd phase
    digitalWrite(stepPinX, LOW);
  } else {                                              // complete cycle
    startMicros = currentMicros;
  }
}

  {
    digitalWrite(stepPinX, LOW);
    startMicros = currentMicros;
  }```

Like that? Same result as before.

@adamaero: Oops! Indeed, I did not notice that the logic of the if conditions was wrong. Edited the answer.

Looks like startMicros and currentMicros values always stay close to each other because of using micros() before and after the conditional block. Since the conditional block executes faster than 500 micros, resulting in never entering the conditional block.
From here you can take two approaches,

Approach 01: Play with your code variables and debug in realtime to see what's wrong and where. Then tweak,debug, repeat until you reach the desired result
Approach 02: Rethink w.r.t the code execution and simplify your code right from entry to exit in sequential steps.

Since your action can be simplified to a toggle operation every 500 microseconds, we can refactor code similar to what I have written,
bool toggle_flag = false;
unsigned long last_toggle;
const unsigned long period = 500;

void setup() {
    last_toggle = micros();
    pinMode(stepPinX, OUTPUT);
}

void loop() {
  // Check to see if time elapsed
  if (micros() - last_toggle >= period ) {

      // Step 01: reset the last_toggle with current time
      last_toggle = micros();

      // Step 02: check toggle flag and perform the toggle action
      (toggle_flag) ? digitalWrite(stepPinX, HIGH) : digitalWrite(stepPinX, LOW);

      // Step 03: toggle the toggle flag variable after our action
      toggle_flag = !toggle_flag;

  }

}

Hope this answer helps.


text:
How much power should I supply to L293d shield to run 4 tt gear dc motors and 1 servo sg90?
I'm new to Arduino. I am trying to making an obstacle avoiding car using Arduino Uno and L293d motor driver shield.
Four tt gear dc motors and 1 servo motor were connected. How much power should I supply or which batteries and how much should I use? Also, how do I increase the speed of the motor? It's max is 255 in shield but that it is slow.

The motors require the voltage that they require, whatever that is. You have to provide enough current to cover the peak consumption of your whole setup, plus ideally a bit more for "headroom".

What is tt? What's a "tt gear dc motor"?

The 255 only mean 100% duty cycle, so fully on motor. When that is too slow, you need to check, if younare operating the motor at its specified voltage and current. You can only get the max speed and force from a motor, when you are powering it woth the right voltage and provide enough current for it. We cannot know, what motor you exactly have. Look for the maximum current (stall current, as the motor draw max, when it cannot move) and the correct operaring voltage in the datasheet or product site of your motor. You should be able to get it from your vendor, where you bought the motor

Also check, if the motor driver can handle the voltage and current, that you need for the motor

Tt gear motor means BO gear motor yellow coloured

I had supplied power from my laptop so it is enough for motors

Also my motors are not working at initialI have to give some force then it works automatically

So may be problem is in shield


text:
I connected a bipolar stepper motor with an HC-SRO4 distance sensor but the motor doesn't work
I connected a bipolar stepper motor with an L293D motor driver and a HC-SR04 distance sensor.
Here's the code:
#include<AFMotor.h>
int stepsperrevolution=200;
AF_Stepper motor(stepsperrevolution,1);
int echopin=11;
int trigpin=9;
int dt=2000;
int sensorval;
void setup() {
  Serial.begin(9600);
  motor.setSpeed(10);
  pinMode(echopin,INPUT);
  pinMode(trigpin,OUTPUT);

}

void loop() {

 digitalWrite(trigpin,LOW);
 delayMicroseconds(10);
 digitalWrite(trigpin,HIGH);
 delayMicroseconds(10);
 digitalWrite(trigpin,LOW);
 delayMicroseconds(10);
 sensorval=pulseIn(echopin,HIGH);
 Serial.println(sensorval);

if(sensorval<500){
 motor.step(stepsperrevolution,FORWARD,SINGLE);
  delay(dt);
   }

}

The code works.Although, every time the sersorval prints in the serial monitor, it stops when the value is less than 500, and the stepper doesn't move.

What happens if you decrease delay(dt) ? I'm not sure how much 1 step is, but if there is just one step every 2 seconds it might look like not moving.

I decreased it already but nothing's changed the motor still doesn't move.

Has it ever moved (with an example sketch if it exists for your stepper motor) ? To rule out any circuit/programming error.

put the motor.step(stepsperrevolution,FORWARD,SINGLE); outside of the if block

@MichelKeijzers. Yes the stepper motor moved with an example sketch.

@jsotola I put it outside of the if block but the senorval reads slowly in the serial monitor

did the motor run?


text:
Convert 1-5V to 4-20mA using Arduino
I am trying to convert 1-5V to 0-20mA which is then used to drive VFD.
Actually, I want 1-5V Variable output from Arduino. I am using PWM but its output 0V or 5V depending upon the duty cycle.
Is their any method to obtain any voltage between 1-5V using Arduino or any other module/controller?

Also asked on EE yesterday: https://electronics.stackexchange.com/questions/501845/4-20ma-output-from-arduino-nano

By tuning R4 and C1 and using an appropriate PWM frequency and duty cycle, you already have a (simple and slow) D/A converter that can generate voltages between 0 and 5V, but this might not fit your needs. How fast does it need to be? There are many DACs available to be interfaced with Arduinos.

@VE7JRO, to be fair, that question was about a 4-20mA output. Now they need to generate a 1-5V input for the same circuit and already added an RC filter to try to accomplish that.

@StarCat - The first sentence in the OP's question on EE is "To convert 1-5V to 0-20mA:". Their first sentence here on Ard.SE is very similar. The OP's question on EE has not received any answers, so maybe someone here has the answer. The 741 OP Amp part of the question is better suited for EE because it's off topic for our network, and the OP may want to read this first before choosing that OP Amp: https://electronics.stackexchange.com/questions/304521/reasons-not-to-use-a-741-op-amp

Make C1 ten times bigger.

just use a low pass filter to convert pwm to analog voltage. if you need responsiveness, a 2-stage filter will respond quicker at the same ripple level than a single RC filter. You will likely need an op-amp unity gain amp (aka buffer) after the filter to allow the needed current (RC filters will severely restrict current). To convert the 0-5v to 0-20ma, you can just drive a 250 ohm resistor. If you want 4-20ma, use the map() function to scale.

One cannot use an Arduino to convert 1..5V to 4..20mA.