# Question
Title: Updating SPI transfer16 to create Transfer24
It might be a bit out there, but for a project that I am working on, my word size default is 24bits (3x8-bit), of which the first 8-bits are data and the next 16-bits are data. I would like to transfer it out of the system as fast as possible with minimal calls to the sub-routines. For this I am trying to reduce the number of calls, I have managed to reduce it from 3 to 2, Can I possibly make it 1 call.

1. My first attempt was to use 3x SPI.transfer() Second was to use 1x
2. SPI.transfer() and 1x SPI.transfer16()

I would like to know what would be the ideal way to write a SPI.transfer24 function.

# Answer
> 2 votes
You can't. The teensy 4.0 has hardware support for 8-bit, 16-bit and 32-bit transfers. Not 24-bit transfers.

But at 600MHz the overhead of making a function call is negligible anyway - certainly compared to the speed of SPI which is at best about 30x slower than the CPU operates at.

If you want high throughput you won't be wanting to use the SPI library anyway, instead you'd be using DMA to transfer your data with minimal CPU intervention.

---
Tags: spi, teensy
---


# Question
Title: Conflicting pins between the PCM library and speaker and the NRF24L01
The PCM library uses pin 11 and the NRF24L01 also uses pin 11. I am using an Arduino nano, and don't know if there is any way to change the pins of either the speaker or the transceiver. https://github.com/damellis/PCM

# Answer
No, you can't just change pins. Both systems use hardware that is specific to pin 11.

The best you could achieve would be to use a software SPI implementation on other pins to drive the nRF24L01, but that would mean changes to the library you are using to remove the SPI library usage and replace it with your own software SPI implementation.
> 1 votes

---
Tags: arduino-nano, pins, speaker
---


# Question
Title: Sending 4 analog values from one arduino to another with I2C
I have modded a cheap drone controller to output its joystick values to an Arduino Nano.

I made it to output its 4 pot values using I2C to another Arduino don't ask why. So my problem is that I need to send 4 values but I can send only 1. Help me please.

I don't have a time limit or something so I don't need this quick or now!

I am also using a 16x2 LCD without I2C to show the live values and sometime I want to make a menu there or stuff like that.

I would like if you wrote the code for me but its ok if you cant. Also I'm kind of a noob at arduino programming.

Master(a.k.a the nano in the controller):

```
int pot1 = A0;
int pot2 = A1;
int pot3 = A2;
int pot4 = A3;

int potValue1 = 0;
int potValue2 = 0;
int potValue3 = 0;
int potValue4 = 0;

int led = 10;
int button = 8;

int lastButtonState;    // the previous state of button
int currentButtonState; // the current state of button

int output1 = A4;
int output2 = A5;
int output3 = A6;
int output4 = A7;

#include <Wire.h>
#include <LiquidCrystal.h> // includes the LiquidCrystal Library

LiquidCrystal lcd(2, 3, 4, 5, 6, 7); // Creates an LC object. Parameters: (rs, enable, d4, d5, d6, d7)

#define SLAVE_ADDR 9

void setup() {
  pinMode(led, OUTPUT);
  pinMode(button, INPUT_PULLUP);

  // Open serial communications and wait for port to open:
  Wire.begin();

  lcd.begin(16, 2);
  lcd.print("   ArduinoTX");
  digitalWrite(led, HIGH);
  delay(600);
  digitalWrite(led, LOW);
  delay(600);
  digitalWrite(led, HIGH);
  delay(600);
  digitalWrite(led, LOW);
  delay(600);
  digitalWrite(led, HIGH);
  delay(600);
  delay(3000);
  lcd.clear();
}

void loop() {
  currentButtonState = digitalRead(button);
  potValue1 = analogRead(pot1);
  potValue2 = analogRead(pot2);
  potValue3 = analogRead(pot3);
  potValue4 = analogRead(pot4);

  int sendValue = map(potValue4, 1, 1023, 1, 255);  //converting to values 255 max
  int sendValue2 = map(potValue3, 1, 1023, 1, 255);
  int sendValue3 = map(potValue2, 1, 1023, 1, 255);
  int sendValue4 = map(potValue1, 1, 1023, 1, 255);

  Wire.beginTransmission(SLAVE_ADDR); //sending only one pot value
  Wire.write(sendValue);
  Wire.endTransmission();

  lastButtonState  = currentButtonState;      // save the last state
  currentButtonState = digitalRead(button); // read new state

  if (lastButtonState == LOW && currentButtonState == LOW) { //dont worry about this
    lcd.print(potValue4);
    lcd.print("        ");
    lcd.print(potValue2);
    delay(delayTime);
    lcd.clear();
    lcd.setCursor(0, 2);
    lcd.print(potValue3);
    lcd.print("        ");
    lcd.print(potValue1);
    delay(delayTime);
    lcd.clear();
  }
}

```

Slave(or an uno who receives the values):

```
int rd;
int br;

#include <Wire.h>

#define SLAVE_ADDR 9

void setup() {
  // put your setup code here, to run once:
  Wire.begin(SLAVE_ADDR);

  // Function to run when data received from master
  Wire.onReceive(receiveEvent);

  // Setup Serial Monitor
  Serial.begin(9600);
}

void receiveEvent() {
  // read one character from the I2C
  rd = Wire.read();
  Serial.println(rd);
}

void loop() {
  delay(50);
}

```

Thanks!

# Answer
> 1 votes
Why are you limited to sending one value? You can have multiple `Wire.write()` calls in one transmission.

The slave side just needs to know to expect multiple values in order to accommodate. The best way to do this would be to read in values as long as the master is sending them (check out https://www.arduino.cc/en/Reference/WireRead).

Then your master changes from

```
Wire.beginTransmission(SLAVE_ADDR);
Wire.write(sendValue);
Wire.endTransmission();

```

to

```
Wire.beginTransmission(SLAVE_ADDR);
Wire.write(sendValue);
Wire.write(sendValue2);
Wire.write(sendValue3);
Wire.write(sendValue4);
Wire.endTransmission();

```

And the slave `receiveEvent()` becomes

```
int receiveValue;
int receiveValue2;
int receiveValue3;
int receiveValue4;
int index = 0;
while(Wire.available()){
    if(index == 0){ receiveValue = Wire.read(); }
    else if(index == 1) {receiveValue2 = Wire.read(); }
    else if(index == 2) {receiveValue3 = Wire.read(); }
    else if(index == 3) {receiveValue4 = Wire.read(); }
    index++;
}

```

I would also consider using arrays as a way to clean up some of your variables, but making the above changes should accomplish what you want if not as cleanly.

---
Tags: arduino-uno, arduino-nano, i2c, communication
---


# Question
Title: How do I control the onboard LEDs of my Arduino Nano 33 BLE Sense?
I picked up my Arduino Nano 33 BLE Sense for the first time in a while and ran the classic "Blink" sketch to make sure it was alright. After slight usage, I wanted to play with the onboard LEDs. When I run the following code, the onboard LED does not turn on:

```
#define RED 22

void setup() {
    pinMode(RED, OUTPUT);
}

void loop() {
    digitalWrite(RED, HIGH);
}

```

However, when I run the following code, the onboard LED does turn on and stays on - it doesn't blink:

```
#define RED 22

void setup() {
    pinMode(RED, OUTPUT);
}

void loop() {
    digitalWrite(RED, LOW);
    delay(1000);
    digitalWrite(RED, HIGH);
}

```

What's happening? Is my Nano busted?

# Answer
There are 3 LEDS on the Nano 33 BLE:

* A power LED on pin 25 (yes, you can turn off the power LED programmatically);
* A built-in LED on pin 13;
* An RGB LED with red on pin 22, green on pin 23, and blue on pin 24.

In the variant file, they are given names:

```
#define PIN_LED     (13u)
#define LED_BUILTIN PIN_LED
#define LEDR        (22u)
#define LEDG        (23u)
#define LEDB        (24u)
#define LED_PWR     (25u)

```

The power LED and the built-in LED are active-high, i.e. you need to set their pin to `HIGH` to turn these LEDs on. **The three LEDs in the RGB LED, however, are active-low.**

This isn't well-documented as far as I know, and some example code snippets have it wrong too. A quick look at the schematic helps.

Also, as StarCat mentioned, you need two `delay()`s to make an LED blink.
> 6 votes

---
Tags: arduino-nano, led, rgb-led, arduino-nano-ble
---


title: Arduino LED lamp circuit

text:
# Question
Title: Arduino LED lamp circuit
I am working on a RGB LED lamp project and this is the schematic for the circuit I managed to come up with.

I am planning to integrate a 27V power supply that powers both the Arduino and a Bluetooth HC-05 module, so I calculated the required resistor values as seen on the schematic. Would this design work? Is 27V too much for the Arduino or does the LED setup balance everything out?

EDIT:

I made an attempt to fix my mistakes based on the answers I received here and this is the new schematic:

This new model would use a 5V power supply instead. Would this fix all issues?

# Answer
No. You will destroy the Arduino and the bluetooth module.

Firstly the Arduino needs no more than 20V absolute maximum - recommended no more than 16V.

Secondly a resistor is not a voltage regulator. It can only drop a fixed voltage when you have a fixed current. It only works with LEDs because they are themselves a fixed voltage.

Thirdly an Arduino output cannot power 6 LEDs in series. You get 5V out, but the combined forward voltage of 6 LEDs is between 12 and 18 volts depending on the colour.
> 1 votes

---
Tags: led
---


# Question
Title: How to connect D1 mini and ATTINY85 over data wire
I’m trying to connect my D1 mini module and attiny85 USB module together over a data wire, but I don’t know how to do it.

Basically, what I want to do is have the D1 broadcast a hotspot with a web page that when a button is pressed, it sends a signal to the attiny85. The D1 is connected via power wires to the attiny85.

I have the sending signal and web server setup on the D1 but I don’t know how to let the attiny85 receive it.

If it helps, I’m using the wire.h library on the D1

(edit: sorry for inactivity, just haven’t been able to test it)

# Answer
> 2 votes
ATTinyCore seems to come with a Wire library implementation presenting the same interface as you find in other Arduino board packages. The damellis package doesn't, so if you've been trying to use that one, I'd suggest switching to ATTinyCore.

To get started you should be able to use the ESP8266-Arduino Wire library's Master Writer example with ATTinyCore Wire library's Slave Receiver example. To be clear, you don't need to get them from github, they should be available in the File/Examples menu. Because the interface is the same, you may find that it doesn't matter which board from which you take the example.

I don't know that I've ever used this Wire library in ATTinyCore; my only memory of using I2C slave no an ATTiny85 was coding it directly myself, but I expect it works fine. I may try myself to confirm though.

On the ATTiny85 you'll be using DIP/SOIC pin 7 (PB2) for the SCL signal. And DIP/SOIC pin 5 (PB0) for the SDA signal.

If I try it myself later I'll update this with more details.

## More details

I don't have a D1 mini. I do have this NodeMCU clone though. According to the pin maps, the D1 mini's D1 and D2 pins are same as on the NodeMCU, that is GPIO5 an GPIO4 respectively. I wired it together as shown here:

I've drawn some lines on the lower part of the image where the camera angle is bad. The smaller inset images are just for showing a better angle there. The yellow and white leads carrying I2C "Wire" data are doctored simply because they went out of frame.

Don't take the "5V" on the ISP cable breakout too literally, that line is at 3.3V (from the NodeMCU 3.3V pin).

ATTiny85 had the following code loaded onto it. It is just the ATTinyCore slave receiver example with unnecessary comments removed and code to set the LED based on whether it receives a non-zero byte in the I2C ("Wire") transaction:

```
#include <Wire.h>

static const int LED_PIN = 4;
static const int SLAVE_ADDRESS = 0x08;

void setup() {
  Wire.begin(SLAVE_ADDRESS);
  Wire.onReceive(wire_receive);
  Serial.begin(9600);
  pinMode(LED_PIN, OUTPUT);
}

void loop() {}

void wire_receive(int howMany) {
  if (Wire.available()) {
    digitalWrite(LED_PIN, Wire.read());
  }
}

```

The following was loaded onto the NodeMCU board. Likewise derived from the ESP8266 Arduino Wire master-writer example. Set the local ESP8266 led when it sends the state over to the ATTiny85. The result is that the ATTiny85 and ESP8266 change their LEDs every 1 second together. The NodeMCU module is wired to light the LED on a LOW, the ATTiny85 to light on a HIGH, so when one is lit the other is not.

```
#include <Wire.h>
#include <PolledTimeout.h>

#define SDA_PIN 4
#define SCL_PIN 5
const int16_t I2C_SLAVE_ADDRESS  = 0x08;

void setup() {
  pinMode(LED_BUILTIN, OUTPUT);
  Wire.begin(SDA_PIN, SCL_PIN);
}

void toggle_led() {
    static bool led_state;

    led_state = !led_state;
    digitalWrite(LED_BUILTIN, led_state);
    Wire.beginTransmission(I2C_SLAVE_ADDRESS);
    Wire.write(led_state);
    Wire.endTransmission();
}

void loop() {
  using periodic = esp8266::polledTimeout::periodicMs;
  static periodic nextPing(1000);

  if (nextPing) {
    toggle_led();
  }
}

```

---
Tags: attiny85
---


# Question
Title: How to put together an HKT30 optical rotary encoder?
I'm working on a project involving stepper motors. It is important for this project to track the position of these motors, so I decided to buy an optical rotary encoder, specifically an HKT30(HKT3005-C03G-1000B-5E) pictured here. I've found it difficult to find resources on how to put this together. I've found datasheets, like this one, but it does not seem to be made up of the same components I have. I think I've basically gotten the gist of how one puts this together from google images, but I would like to be pointed in the way of an explicit resource in case I damage my parts.

Additionally, I was hoping for an explanation on the 5 wires (red, green, black, white, and gray), their purpose and how to set one up on a board.

If any clarification or images are needed, I would be happy to provide.

Thank you!

# Answer
It's not hard...

* The sensor screws into the screw holes.
* The disc slots into the gap in the sensor
* The case clips on the outside

As to what the wires are, only the datasheet / manual / manufacturer can tell you that. Maybe if you trace them on the sensor board you can work out what is what.
> 1 votes

---
Tags: arduino-uno, robotics, rotary-encoder, stepper-motor
---


title: Can't stop SG90 spinning

text:
# Question
Title: Can't stop SG90 spinning
I have a SG90. I just want it to spin 360° and stop, that's about it. This seems impossible.

I have tried the sweep example:

```
 by BARRAGAN <http://barraganstudio.com>
 This example code is in the public domain.

 modified 8 Nov 2013
 by Scott Fitzgerald
 http://www.arduino.cc/en/Tutorial/Sweep
*/

#include <Servo.h>

Servo myservo;  // create servo object to control a servo
// twelve servo objects can be created on most boards

int pos = 0;    // variable to store the servo position

void setup() {
  myservo.attach(9);  // attaches the servo on pin 9 to the servo object
}

void loop() {
  for (pos = 0; pos <= 180; pos += 1) { // goes from 0 degrees to 180 degrees
    // in steps of 1 degree
    myservo.write(pos);              // tell servo to go to position in variable 'pos'
    delay(15);                       // waits 15ms for the servo to reach the position
  }
  for (pos = 180; pos >= 0; pos -= 1) { // goes from 180 degrees to 0 degrees
    myservo.write(pos);              // tell servo to go to position in variable 'pos'
    delay(15);                       // waits 15ms for the servo to reach the position
  }
}

```

This works fine.

I read somewhere that for 360 motors the variable in `myservo.write()` is actually just the speed. So I tried:

```
void loop() {
    myservo.write(0);              // tell servo to go to position in variable 'pos'
    delay(2000);                       // waits 15ms for the servo to reach the position
    myservo.write(180);              // tell servo to go to position in variable 'pos'
    delay(2000);
    myservo.write(0);              // tell servo to go to position in variable 'pos'
}

```

The motor rotates several times then spins the other direction and repeats doing this.

What do I need to do to make it complete 1 rotation and stop?

# Answer
TL;DR: *Can't be done.*

On a servo modified for continuous rotation, the signal you send sets direction and speed, *not* rotation angle. You *can* stop it, but you *can't* set an angle.

The sweep example will turn a continuous rotation servo in both directions, but I doubt it hits the angles you send it; it will just adjust speed and direction.

Without external hardware and feedback, like a limit switch, or a rotary encoder, there is no way of knowing what angle the servo is at, and no way to rotate to exactly 360° other than experimenting and "guessing" based on time and rotation speed.

You can then stop it by setting it to the PWM value for 90° or center position, which should set the rotation speed to 0.

On a servo, you can't have both continuous rotation with a set speed, and a set angle of rotation, without extra hardware.

Maybe a stepper motor would be a better choice for your application, or a "normal" servo with a gear that gives you the required rotation range.
> 1 votes

# Answer
A value near 90 will make your rotating servo stop. Try 89, 91 etc. until you find it.

If you are running an auger, use a microswitch that pulses once per revolution. Starting at the point where the switch makes contact, run the servo until the switch opens and closes again then stop. You have made one revolution.
> 0 votes

---
Tags: esp8266, servo
---


# Question
Title: rfm69 on M0 Express... init() doesn't work
I have already connected succesfully the rfm69 on my Feather M0 Express... but I cannot do it again.

The connections are (in the order of the rfm69):

```
Vin -> 3V
Gnd -> Gnd
En  -> (nothing)
G0  -> 9
SCK -> SCK
MISO -> MI
MOSI -> MO
CS  -> 10
RST -> 6

```

The code of the setup is

```
#include <SPI.h>
#include <RH_RF69.h>

#define RFM69_CS      10
#define RFM69_INT     9
#define RFM69_RST     6
#define LED           13

// Singleton instance of the radio driver
RH_RF69 rf69(RFM69_CS, RFM69_INT);

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

  Serial.println("Feather RFM69 RX Test!");
  Serial.println();

  // manual reset
  digitalWrite(RFM69_RST, HIGH);
  delay(10);
  digitalWrite(RFM69_RST, LOW);
  delay(10);

  if (!rf69.init())
    //***********************************
    Serial.println("init failed");
  else
    Serial.println("init ok");

  // Defaults after init are 434.0MHz, modulation GFSK_Rb250Fd250, +13dbM (for low power module)
  // No encryption
  if (!rf69.setFrequency(434.0))
    Serial.println("setFrequency failed");
  else
    Serial.println("setFrequency ok");

  // If you are using a high power RF69 eg RFM69HW, you *must* set a Tx power with the
  // ishighpowermodule flag set like this:
  //rf69.setTxPower(14, true);

  // The encryption key has to be the same as the one in the client
  uint8_t key[] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
                    0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08};
  rf69.setEncryptionKey(key);

#if 0
  // For compat with RFM69 Struct_send
  rf69.setModemConfig(RH_RF69::GFSK_Rb250Fd250);
  rf69.setPreambleLength(3);
  uint8_t syncwords[] = { 0x2d, 0x64 };
  rf69.setSyncWords(syncwords, sizeof(syncwords));
  rf69.setEncryptionKey((uint8_t*)"thisIsEncryptKey");
#endif
  Serial.println("Fin du Setup");
}

```

But during the execution, the program stops at `//**************************` I do not understand.

Can somebody help me?

Thanks a lot and merry Xmas

# Answer
> 1 votes
The "init failed" do not appear. Everything stops at "//\******". I have compared to another RFM69 program. I have added a line " digitalWrite(RFM69\_RST, LOW);" at the begining of the "//manual reset" and it works now. the sequence digitalWrite(RFM69\_RST, LOW); digitalWrite(RFM69\_RST, HIGH); delay(10); digitalWrite(RFM69\_RST, LOW); seems to be more efficient. ... it remains a few mysteriuos for me.

Thank you

---
Tags: c++, wireless, feather
---


# Question
Title: Programming an Arduino using Python, rather than C/C++
I am not very skilled with the C Language and I was wondering if there is a way in which python could be used to program an Arduino. This would most likely require a different IDE in order to be able to debug the scripts them self.

# Answer
> 27 votes
It's going to be extremely difficult to get any kind of Python script running directly on the Arduino. The reason is that it's an interpreted language, so you would need the interpreter on-board in addition to the plain text script. There's probably not going to be enough memory for all of that.

Your best bet would probably be finding a way to compile a Python script to native machine code (which is how C/C++ works). I believe there are projects around to do something like that for other platforms, but (as far as I know) none which does it successfully for Arduino yet.

You might find some more useful information on this question at Stack Overflow: Is there a way to "compile" Python code onto an Arduino (Uno).

# Answer
> 17 votes
Yes, it is (somewhat) possible to program the Arduino using Python. One such project on Github is the Python Arduino Prototyping API v2. It provides very basic functionality such as digital I/O and analog I/O.

This can be used for very simple projects.

---

\*This project is a bit of a hack at "programming" the board using the serial connection. It passes the commands over the serial connection to a sketch running on the board which then "executes" the Python command.

# Answer
> 9 votes
There is a project which brings a Python virtual machine to micro-controllers, including the Arduino Mega.

Here's a quote from the Ardunio Mega README, which gives a feel for what this could be like (though, I've not tested this!):

> The following is an example session using ipm::
>
> ```
> ipm> import avr, sys
> ipm> avr.ddrA(0xff)
> ipm> avr.portA(0)       # Pins 22-29 all at 0 V
> ipm> avr.portA(0xa5)
> ipm> sys.heap()
> (2622, 7424)
>
> ```

# Answer
> 4 votes
I have used pyserial with great success in controlling the pins on the arduino. Your workstation (laptop, etc) runs a python script that then communicates in real time to the arduino.

It's not quite the same as running the script directly on the arduino but I was doing quite a bit more than I thought the arduino could handle (some music analysis, hitting a REST api, etc).

# Answer
> 2 votes
Another option to consider is the Arduino Yun. In addition to the AVR chip which most Arduinos have, it also includes a MIPS chip running Linux. Since it's linux, you can easily run python code, and any pure-python package can be easily installed.

However, all the interesting input/output capability is on the AVR chip, not on the MIPS chip. Projects such as Autobahn and LininoIO solve this problem by running a special program on the AVR chip which performs I/O operations under instruction from the MIPS chip.

# Answer
> 2 votes
Yes,its possible with the recent new ArduinoPro H7 which has abilities to upload a written programme in Python and JavaScript and its a dual core,32bit.

# Answer
> 1 votes
We know this is an open issue in Arduino programming and in the embedded world in general. There are various solutions available on the market like MicroPython but most of them are dedicated to specific boards and don't allow to keep the system real-time. We are working on a solution! VIPER is a Python Virtual Machine for Arduino DUE and all ARM 32 bit architectures that runs on top of a real-time operating system. This means that you can develop Python scripts that can be exexuted by Arduino DUE, UDOO, Spark (all boards) and also on the new ST nucleo boards. Moreover if you need high performances and you re skilled in C you can develop real-time modules for VIPER that can be called and managed by the Python scripts.

You can see VIPER in action here http://bit.ly/kickviper

# Answer
> 1 votes
Yes. Python can be used to program an Arduino, simply by importing pyfirmata, which can interface the arduino with Python.

# Answer
> 1 votes
You could learn from C (AVR) how sensors work but it needs much more time. Arduino IDE Code and Python Code for Arduino use C Code functions to make things simple. Python and Arduino IDE if use Firmata they use serial communication and you think you code self.

# Answer
> 0 votes
You gotta use pyfirmata because that's the only way to make your son a PRO engineer who makes robots. Also, python can do more advanced stuff so use pyfirmata.

---
Tags: programming, python
---


# Question
Title: Can i connect in pin of relay module to Analog pins of arduino instead of digital pin?
Im a complete beginner

Im making a project using relay modules and arduino. but all the digital pins of my arduino are filled. I wanted to ask if i can use the analog pins to connect my relay module to my arduino? If yes can anyone give me the statements to write high and low using analog.

# Answer
> 3 votes
Yes, you can use the analog pins as digital pins. Quoting this Arduino tutorial:

```
pinMode(A0, OUTPUT);
digitalWrite(A0, HIGH);

```

**EDIT:**
Here is the code snippet for digital input:

```
pinMode(A0, INPUT);
digitalRead(A0);

```

---
Tags: arduino-uno, relay, electronics, analogwrite, electricity
---


# Question
Title: Always HIGHT line on Oscilloscope when UNO's Fast PWM TOP ICR1
I have been trying to get an answer my question for a 2 days *already. It's good for knowledge collecting and playing with different things, but there haven't been a solution so far.*

I'm trying to leverage the `HXT500` Servo with the `Fast PWM with a TOP ICR1`

I'm using the `DFRobot DFRduino UNO v3.0 (R3)` analog of the `Arduino UNO`. Based on the `Atmega 328P-PU`

I have an `Oscilloscope till 5 MHz` as additional tool

## Question

1. Why the `Fast PWM, TOP ISC1` always has the HIGHT only on a oscilloscope
2. Why the Clock `Prescaler` doesn't work

## My investigations & observations

I activated the `PWM with TOP ICR1` but on my oscilloscope showed only a `5V straight line`, I checked different diapasons (horizontal bases) `(1a)`. Connected to `pins 10 or 9`. I assumed that my UNO works on `1 MHz` (9.2.1 Default Clock Source on Page 37) and calculated ICR1, OCR1A:B for 0 and 180 degree.

```
     void setup() {
      // all as Ports (for outputs)
        DDRB=0xFF;
        DDRC=0xFF;
        DDRD=0xFF;

      // Table 16-4 on Page 141
      // Fast PWM TOP is ICR1
      TCCR1A|=(0<<WGM10)|(1<<WGM11);
      TCCR1B|=(1<<WGM13)|(1<<WGM12);
      ICR1=2499;

      // Table 16-2 on Page 140
      // Clear OC1A/OC1B on Compare Match, set OC1A/OC1B at BOTTOM (non-inverting mode)
      TCCR1A|=(1<<COM1A1)|(1<<COM1B1);

      // Table 16-5 on Page 143
      // clkI/O/8
      TCCR1B|=(0<<CS12)|(1<<CS11)|(0<<CS10); // (2a)
    }

    void loop() {
      digitalWrite(LED_BUILTIN, HIGH);
        // 90 degree
        OCR1A=299;
        OCR1B=299;
      delay(1000);
      digitalWrite(LED_BUILTIN, LOW);
        // 0 degree
        OCR1A=49;
        OCR1B=49;
      delay(1000);
    }

```

There I noticed the following issues:

* I tried different `Prescale`s - there weren't any differences `(2a)`
* I tried 1 MHz, 8 MHz, 16 MHz - straight HIGHT line

What I have tried next:

* To use an Example for Servo leveraging from Arduino IDE. It worked but as I understood it worked via Interrupts, not a Hardware solution
* To use Fast PWM, 9 & 10-bit. `(2a) Prescale`s didn't work - I had movement
* To use Fast PWM, 8-bit (with code adjustment and wrong angles). `(2a) Prescaler`s didn't work - I had movement

# Answer
> 0 votes
You might want to set the `TCCR1A` and `TCCR1B` registers to `0` before your code as the Arduino library sets the WGM10 bit. Or change the first `|=` to a `=`. By leaving the WGM10 bit set, you get fast PWM mode, with TOP set to OCR1A. Combined with your other code, this would result in both pins having a 100% duty cycle.

So use

```
TCCR1A=(0<<WGM10)|(1<<WGM11);
TCCR1B=(1<<WGM13)|(1<<WGM12);

```

or

```
TCCR1A=0;
TCCR1B=0;
TCCR1A|=(0<<WGM10)|(1<<WGM11);
TCCR1B|=(1<<WGM13)|(1<<WGM12);

```

Other than that, you code looks fine, and should give you a 800Hz signal.

PS `"I assumed that my UNO works on 1 MHz"`; no, the UNO runs at 16Mhz.

---
Tags: arduino-uno, servo, pwm
---


# Question
Title: Can anyone help be get readings off of my potentiometer with a push of a button?
Hi I'm trying to get my Arduino Uno code to work with a in a specific way where if I push a button, the Arduino will read the raw potentiometer value once and if I don't push it nothing happens.

https://i.stack.imgur.com/uCHkR.jpg

```
int switchState = 0
int switchPin = 2
int potPin = A0;

void setup() {
pinMode (potPin, OUTPUT);
pinMode (switchPin, INPUT);
Serial.begin (9600);

}

void loop() {
switchState = digitalRead(2);
if (switchState == High) {
Potval = analogRead(potPin);
Serial.print("potval:");
Serial.Println(Potval);
delay(200);
}

else {
(switchState == LOW);
while (Potval);
}
}

```

# Answer
> 1 votes
I had a very similar issue an it is that you aren't setting up your button as an INPUT\_PULLUP. When you press the button, you are sending 5V or ground through it depending on your circuit. But then it won't reset on release. That is why either you can put a physical resistor as the schematic shows here:

or you can simply change the button initialization to INPUT\_PULLUP.

# Answer
> 1 votes
There were several issues with your code:

* It would not compile due to some missing semi-colons (lines 1 & 2);
* The 'else' clause in your loop() function didn't do anything useful;
* If your code didn't get trapped in the loop within the 'else' clause (it probably would!), it would print repeatedly as long as you were NOT pressing the button, since you wired the button to read LOW when pressed (which is perfectly fine, buy your code has to take that into account).
* Buttons appear to bounce (electrically) when you press or release them. They don't switch once and stay that way. They switch multiple times before they settle down, due to the rough contact surfaces sliding over one another. The code has to allow for this as well.
* An analog pin has to not be set to OUTPUT if you want to read analog with it.

Here is a revised version of your code, compiled and tested. You'll find notations in the comments where I made changes:

```
int switchState = 0;            // (';' was missing)
int switchPin = 2;          // (';' was missing)
int potPin = A0;
int Potval = 0;             // (this declaration was missing)
bool didPrint = false;      // true if we printed on this button-push
// prevents multi-printing while button stays high

void getSwitch();               // declare the new function

void setup() {
  //  pinMode (potPin, OUTPUT);  // not OUTPUT for analog read
  pinMode (switchPin, INPUT_PULLUP);  // needs pullup or reads may be unreliable
  pinMode (13, OUTPUT); digitalWrite(13, LOW); //DEBUG
  Serial.begin (9600);

}

void loop() {
  getSwitch();
  if (switchState == LOW ) {        // pressed == LOW the way you've wired it

    if (!didPrint) {
      Potval = analogRead(potPin);
      Serial.print("potval:");
      Serial.println(Potval);

      didPrint = true;      // prevent printing again til button has been released
    }
  }
  else if  (switchState == HIGH) {
    didPrint = false;       // printing allowed on next button push
  }
}

void getSwitch() {
  switchState = digitalRead(switchPin);
  delay(30);                // waits for button to settle - may need to tweak this
}

```

---
Tags: arduino-uno, button, potentiometer
---


# Question
Title: How do I make two (or more) pins available on my server url?
I have a webserver configured on my esp8266 with is set to fire off electrical relay0 on my 8 port relay board. The device initializes relay0 perfectly and without errors. But when I configure the second relay1, i get no response from my second url.

```
//note, when you write to low, you turn the switchport on. It's backwards for some reason
#include <ESP8266WiFi.h>
#define statusLed 2   // built-in led for the ESP8266-12

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

int switchPin0 = 16;
int switchPin1 = 5;
int switch0;
int switch1;

WiFiServer server(80);

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

  pinMode(statusLed, OUTPUT);
  pinMode(switchPin0, OUTPUT);
  digitalWrite(switchPin0, HIGH);

  // Connect to WiFi network
  Serial.println();
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);

  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  digitalWrite(statusLed, HIGH);
  Serial.println("");
  Serial.println("WiFi connected");

  // Start the server
  server.begin();
  Serial.println("Server started");

  // Print the IP address
  Serial.print("Use this URL : ");
  Serial.print("http://");
  Serial.print(WiFi.localIP());
  Serial.println("/");

}

void loop() {
  // Check if a client has connected
  WiFiClient client = server.available();
  if (!client) {
    return;
  }

  // Wait until the client sends some data
  Serial.println("new client");
  while(!client.available()){
    delay(1);
  }

  // Read the first line of the request
  String request = client.readStringUntil('\r');
  Serial.println(request);

  client.flush();

  // Match the request

  int value = HIGH;
  if (request.indexOf("/SWITCH=0") != -1){
    digitalWrite(switchPin0, LOW);
    digitalWrite(statusLed, LOW);   // blink led
    delay(1);
    digitalWrite(statusLed, HIGH);
    //set water pump time here
    delay(8000);
    digitalWrite(switchPin0, HIGH);
    value = HIGH;
    ++switch0;
  } else if (request.indexOf("/SWITCH=1") != -1){
    digitalWrite(switchPin1, LOW);
    digitalWrite(statusLed, LOW);   // blink led
    delay(1);
    digitalWrite(statusLed, HIGH);
    //set water pump time here
    delay(8000);
    digitalWrite(switchPin1, HIGH);
    value = HIGH;
    ++switch1;
  } else {

    }

  // Return the response
  client.println("HTTP/1.1 200 OK");
  client.println("Content-Type: text/html");
  client.println(""); //  do not forget this one
  client.println("<!DOCTYPE HTML>");
  client.println("<html>");

  client.print("Switch pin is now: ");

  if(value == HIGH) {
    client.print("Off");
  } else {
    client.print("On");
  }
  client.println("<br><br>");
  client.println("Switch 0");
  client.println("Click <a href=\"/SWITCH=0\">here</a>  to send a measured amount<br>");
  client.println("Number of times plant 0 has been fed is ");
  client.println(switch0);
  client.println("<br><br>");
  client.println("Switch 1");
  client.println("Click <a href=\"/SWITCH=1\">here</a>  to send a measured amount<br>");
  client.println("Number of times plant 1 has been fed is ");
  client.println(switch1);
  client.println("</html>");

  delay(1);
  Serial.println("Client disconnected");
  Serial.println("");
  digitalWrite(statusLed, LOW);   // blink led
  delay(1);
  digitalWrite(statusLed, HIGH);

}

```

my counter will update, but the relay pin never fires for relay1. relay0 works fine. I can swap the ports and then the second relay will work and not the first. I just can't manage both.

How do I get a second (or more) relay ports to initialize via webpage?

# Answer
It looks like you forgot to initialize `switchPin1` to be an output.

Add the following to your `setup()` (for example, right after the corresponding initialization commands for `switchPin0`):

```
void setup() {
    ....
    pinMode(switchPin1, OUTPUT);
    digitalWrite(switchPin1, HIGH);
    ....
}

```
> 3 votes

---
Tags: wifi, web-server, networking
---


# Question
Title: Using a Encoder Feedback to control a 360 degree servo
I pieced together a sketch to control a servo that turns an encoder. Eventually I plan to build this up to a DMX input, so I have the input range from 0 - 255. Basically, it's supposed to ask you to input range from 0 to 255 and then it changes that value to 0 -180 for servo control. Then it's supposed to compare that to the encoder and rotate the correct direction until the encoder value and requested values match. I'm just learning arduino so I'm sure I've made some mistake. Here is the code:

```
// Rotary Encoder Inputs
#define inputCLK 22
#define inputDT 24

#include <Servo.h>

Servo myservo;
int pos = 90;
int counter = 90;
int currentStateCLK;
// Setup Serial Monitor

// Read the initial state of inputCLK
// Assign to previousStateCLK variable
int previousStateCLK;

String encdir ="";

void setup() {
  Serial.begin (9600);
  previousStateCLK = digitalRead(inputCLK);
  // Set encoder pins as inputs
  pinMode (inputCLK,INPUT);
  pinMode (inputDT,INPUT);
  myservo.attach(9);

void loop() {
  Serial.println("Enter a number from 0 to 255");
  while (Serial.available() == 0); {}
  int val = Serial.parseInt(); // read int or parseFloat for ..float...
  long Pos = val;
  Pos = Pos * 180 / 255;
  Serial.println(val);
  Serial.println(Pos);
  if (Pos > Counter) {
    myservo.write 0;
  }
  if (Pos < Counter) {
    myservo.write 180;
  }
  if (Pos = Counter) {
    myservo.write 90;
  }

  // Read the current state of inputCLK
  currentStateCLK = digitalRead(inputCLK);

  // If the previous and the current state of the inputCLK are different then a pulse has occured
  if (currentStateCLK != previousStateCLK) {
    // If the inputDT state is different than the inputCLK state then
    // the encoder is rotating counterclockwise
    if (digitalRead(inputDT) != currentStateCLK) {
      counter --;
      encdir ="CCW";
    } else {
      // Encoder is rotating clockwise
      counter ++;
      encdir ="CW";
    }
    Serial.print("Direction: ");
    Serial.print(encdir);
    Serial.print(" -- Value: ");
    Serial.println(counter);
  }
  // Update previousStateCLK with the current state
  previousStateCLK = currentStateCLK;
}

```

So when I run the program, I'm not getting any movement on the servo.

Thanks.

# Answer
Your initial problem is here:

```
  if (Pos = Counter) {

```

If the result (fall through) of assigning Counter to Pos is non-zero then stop.

That's not right. You're assigning, not comparing. In C `==` is comparison and `=` is assignment. Instead it should read:

```
  if (Pos == Counter) {

```

However there is another, more sneaky, problem with your code - the usage of `Serial.parseInt()`.

If you send the string `56\r\n` as you typically would (with the CR+LF line ending typical of serial communication) then `parseInt` will read the first portion of the string up to and including the first non-digit character and parse it as a number. That is, the `56\r` and return the value 56. Then on the next pass it will see there is still data in the serial buffer and parse it, up to and including the first non-digit character - which is just `\n`. So it will return 0.

That means the first pass through `loop()` you get 56, and then immediately after in the next pass through `loop()` you get 0.

And then, looking at your code a third time, there is another bigger problem: you block waiting for serial input, and your `Pos` variable is local and will be lost each iteration. I think you meant to use `pos`, which is a global variable, and not create a new `long Pos` variable each iteration. And where is `Counter` defined? That surely should be the global `counter` variable?

If you're blocking waiting for serial input then how can you be controlling the servo to get it to the desired location?

So, in short, there are so many errors and problems with your code that you need to go back to basics and re-think / re-write many portions of it.
> 0 votes

---
Tags: servo, rotary-encoder
---


# Question
Title: Is there a limitation of how many instances of the `String` class?
Platform

* Attiny85 with AttinyCores
* 1306 OLED i2c with Tiny4KDisplay

Goal

* using a joystick for menu navigation
    + up/down choose
    + left enter (not finished yet)
    + right back (not finished yet)
    + inverse display the chosen item.

I come from python word which is why I am using a linked list for menu navigation. I found a weird bug that stops me from displaying some of the long text. I found that if the defined Nodes over a certain amount of number, item text over 5 chars will not display. I don't know why this is related to the number of instances. I managed to narrow down the range of the bug. In the code. if those 3 lines are commented, all the items are displayed correct, if not, only up to `ccccc` but not `dddddd`.

The flash and RAM consumption of the failure situation is

```
Sketch uses 5180 bytes (63%) of program storage space. Maximum is 8192 bytes.
Global variables use 280 bytes (54%) of dynamic memory, leaving 232 bytes for local variables. Maximum is 512 bytes.

```

My code is as below. I broke it into parts to highlighted the problem. But it is a continuous file actually.

Thank you for any insight.

PS: I know there are methods that avoid oop, but I think this weird bug is so close to being fixed, (or proved to be an actual bug in the package/compiler). So I would like to pursue an answer to this question.

Update:

I tried to use another method that uses a List of Strings instead of a class to achieve the same function. The Bug is still there. I guess it is because there are too many instances of String. The question is not changed: "Is there a limitation of how many instances of the `String` class?".

```

#include <Tiny4kOLED.h>

// input setup
int x = 512;
int y = 512;
int lastx = 512;
int lasty = 512;

bool left = false;
bool right = false;
bool up = false;
bool down = false;

char input() {
  x = analogRead(A2);
  y = analogRead(A3);
  if( (lastx > 256) & (x <= 256) ){
    left = true;
  }
  if( (lastx < 768) & (x >= 768) ){
    right = true;
  }
  if( (lasty > 256) & (y <= 256) ){
    down = true;
  }
  if( (lasty < 768) & (y >= 768) ){
    up = true;
  }
  lastx = x;
  lasty = y;
}

// item data
class Node
{
  public:
    String text;
    uint8_t id;
    Node * next;
    Node * previous;
    Node * parent;
    Node * child;
    Node(String s, int n){
      text = s;
      id = n;
      next = NULL;
      previous = NULL;
      parent = NULL;
      child = NULL;
    }
    void append_next(Node * other){
      this->next = other;
      other->previous = this;
      other->parent = this->parent;
    }
    void append_child(Node * other){
      this->child = other;
      other->parent = this;
    }
};

Node main_0("aaa", 1);
Node main_1("bbbb", 2);
Node main_2("ccccc", 3);
Node main_3("dddddd", 4);
Node main_4("eeeeeee", 5);
Node main_5("ffffffff", 6);

```

# This is how the error can be repeated.

```
/* Uncomment The following 3 lines will cause the problem*/
//Node item_0_0("aaa", 7);
//Node item_0_1("bbb", 8);
//Node item_0_2("ccc", 9);

```

```
Node * current_sel = (&main_0);
Node * screen_top = (&main_0);

void setup() {
  // oled setup
  oled.begin(0,0);
  oled.enableChargePump();
  oled.setRotation(1);
  // oled.setInternalIref(true);
  oled.enableZoomIn();
  oled.setFont(FONT6X8);
  oled.clear();
  oled.switchRenderFrame();
  oled.clear();
  oled.switchFrame();
  oled.on();
  // oled setup end

  // input setup
  pinMode(A2, INPUT); // X
  pinMode(A3, INPUT); // Y
  // input setup end

  // data
  main_0.append_next(&main_1);
  main_1.append_next(&main_2);
  main_2.append_next(&main_3);
  main_3.append_next(&main_4);
  main_4.append_next(&main_5);
}

void loop() {
  // input read
  input();

  // move current;
  if(up){
    up = false;
    if(current_sel->previous != NULL){
      if(screen_top == current_sel){
        screen_top = screen_top->previous;
      }
      current_sel = current_sel->previous;
    }
  }

  if(down){
    down = false;
    if(current_sel->next != NULL){
      if(screen_top->next->next->next == current_sel){
        screen_top = screen_top->next;
      }
      current_sel = current_sel->next;
    }
  }

  // oled update
  oled.clear();

  oled.setCursor(64, 0);
  oled.print(current_sel->text);

  Node * current_draw = screen_top;
  int i = 0;
  while(true){

    oled.setCursor(0,i);
    if(current_draw == current_sel){
      oled.invertOutput(true);
    }
    oled.print(current_draw->text);
    oled.invertOutput(false);

    if(current_draw->next == NULL){
      break;
    }

    current_draw = current_draw->next;
    i++;
    if(i >= 4){
      break;
    }
  }

  oled.switchFrame();
  delay(50);
}

```

# Answer
Each instance of your class uses RAM to store its data. There is *always* a limit to the number of instances; not a fixed number, but a limit imposed by the quantity of RAM available. What Majenko wrote about `String`s applies equally to class instances, if instances are constructed and destroyed during the run.

A fixed number of global instances, as you have used, is more efficient but there is still only room for so many. Complicating this is the fact that RAM is a shared resource. Static variables like globals, including global class-instances, are assigned from the bottom of RAM, upward, after all of the compilations are done and before uploading to the chip. The program's run-time stack, which includes each function's automatic local data, builds from the top of RAM, downward, during the run. Stack memory is assigned and released as each function is entered and exited. But when a function calls a function which calls a function, which calls ..., the stack has to keep growing until the final call returns and the previous calls may then return.

If you attempted to define a large number of instances with a small amount of RAM available, the IDE (actually the linker, which puts together all of your code and the libraries you use) would catch the problem before your program gets uploaded.

But in the case where there all of the RAM didn't get assigned at compile- or link-time, then at run time, your stack could still possibly grow downward until it collides with the global- and fixed-data at the bottom of RAM, with (unfortunately) unpredictable results, but definitely unexpected and improper operation.

Update: I did gloss over some details, as two commenters were kind enough to point out. Yes, the heap - memory allocated dynamically at run-time - occupies the space just above the globals and other static memory allocations. Heap space can grow, the more it is used to allocate and de-allocate memory, and being low in memory, would have to grow upward, toward the stack. It is the heap where String data is allocated and re-allocated and is one of the reason's behind Majenko's warning against using the String type - especially if the strings will be edited at run time, which results in re-allocation that may not be obvious.

It is also worth noting that any class uses memory, whether Strings or user defined classes such as the OP's nodes. They are both classes and their instances will be handled similarly.

Also in OP's case, note that the class instances are allocated 'statically' - all instances are known and allocated during the run setup and not altered during the run. In 'quotes', because the allocation actually does happen during run-time, but at the very start of the run, and prior to the user sketch receiving control.
> 1 votes

# Answer
**Do not** use `String`. Ever. Especially not on a chip with such a tiny amount of RAM.

`String` uses dynamic allocation to store the string data in RAM. This is very inefficient, especially when you are working with string literals.

Those literals must be stored in flash, not RAM, so you need to be working with `const char *` and `PROGMEM`, along with the `F()` macro.

When using a chip with only a few hundred bytes of RAM you *need* to be as efficient as you possibly can. You *need* to account for each and every byte you use - and you just can't do that with `String`.

---

As an example, let's look at what this does:

```
Node main_5("ffffffff", 6);

```

You have a string of 8 characters plus a NULL terminating character. That's 9 bytes. Those 9 bytes are copied into RAM at boot time. Current total 9 bytes. You then convert that to a `String` and copy the character data into that temporary object - that's now 18 bytes plus the size of the `String` object. Then:

```
text = s;

```

You allocate 9 bytes inside the `text` `String` object and copy the data in. You're now at 27 bytes plus two `String` objects (one of which you created earlier in your class). A little over 5% of your entire memory just to move text around the place. A third of that you claw back from your heap as the objects leave scope, but then you have a hole in your heap. And this is the last set of operations after you've already made a complete mess of your heap with the earlier ones.

Whereas

```
const char main_5[] PROGMEM = "ffffffff";

```

uses just 2 bytes of RAM to store the pointer and nothing else.
> 2 votes

---
Tags: string, class, attiny85, oled
---


# Question
Title: formatting of IPAddress via printf(...) family similar to Serial Object
I am trying to use an sprintf with an IPAddress and I am not sure why Serial.print() is able to convert IPAddress to a reasonable human readable representation. I mean, presumably it uses an overloaded function that detects what type the parameter is. I want to somehow leverage that functionality ina printf or sprintf.

What I know:

```
IPAddress ip = WiFi.localIP();
Serial.println(ip);

```

works great and outputs "192.168.4.1".

```
char *buf = malloc(128);
sprintf(buf,"%s",String(ip).c_str());

```

generates buf as "17082560" which isn't wrong, but its not the usual format for an IP address.

I could write a function to output it the way I want, but I figured there must be some relatively simple way to utilize the functionality that Serial.print() provides but somehow channel it to an sprintf() call. Or any other simple way to provide a formatted IP output would be appreciated.

# Answer
Whereas KIIV's answer solves your problem, it does not address some very interesting parts of your original question:

> I am not sure why Serial.print() is able to convert IPAddress to a reasonable human readable representation

This works thanks to a couple of abstract classes in the Arduino library called `Print` and `Printable`. A Print object is anything that can output text, like a serial port, a network connection or an LCD. A Printable object is anything that can be converted to a text representation and sent through a Print object.

From Print.h:

```
class Print
{
    // ...
    virtual size_t write(uint8_t) = 0;
    // ...
    size_t print(const String &);
    size_t print(const char[]);
    size_t print(unsigned int, int = DEC);
    size_t print(const Printable&);
    // ...
    size_t println(const String &s);
    // ...
};

```

In other words, in order to create a Print, you only have to implement `write(uint8_t)`, which should output a single character. Then you get all the `print()` and `println()` methods.

From Printable.h:

```
class Printable
{
  public:
    virtual size_t printTo(Print& p) const = 0;
};

```

This means you can make any object Printable by implementing `printTo(Print&)`.

From IPAddress.h:

```
class IPAddress : public Printable {
    // ...
};

```

This means IPAddress objects are Printable: they know how to print themselves into any Print. You can find the implementation of `IPAddress::printTo(Print&)` at the end of IPAddress.cpp.

Thus, to answer your question, `Serial.print()` does not really know how to create a textual representation of the IPAddress, but IPAddress knows how to send itself through `Serial`, or any other Print object.

> I want to somehow leverage that functionality \[...\] there must be some relatively simple way to utilize the functionality that Serial.print() provides but somehow channel it to an sprintf() call.

The functionality is not provided by `Serial.print()`: it's the fact that the IPAddress is Printable. In order to leverage that, you have to create a Print object. You cannot use `sprintf()` for that, but you can create a Print object which behaves like `sprintf()` and writes into a C string:

```
// Write into a C string (a char array), a la sprintf().
// Warning: there is no check for buffer overflow.
class StringPrinter : public Print
{
public:
    StringPrinter(char *buffer) : buf(buffer), pos(0) {}
    virtual size_t write(uint8_t c)
    {
        buf[pos++] = c;  // add the character to the string
        buf[pos] = 0;    // null perminator
        return 1;        // one character written
    }
private:
    char *buf;
    size_t pos;
};

```

which could be used like this:

```
char buf[16];
StringPrinter(buf).print(ip);

```

For the sake of simplicity, I would generally prefer the straight `sprintf()` solution. However, if you are short on flash, the code above is likely to be smaller, as `sprintf()` is large and you are very likely to be already using `Print` in your program.
> 2 votes

# Answer
In short: `hex(17082560) = 0x0104A8C0` where: `0x01 = 1`, `0x04 = 4`, `0xA8 = 168` and `0xC0 = 192`. See the pattern? It's printed as a single `uint32_t`.

Of course endianness is reversed as platform is little endian but IP Adresses are in network byte order (big endian)

And because you didn't understand this answer, there is also whole code:

```
uint32_t ip = (uint32_t) WiFi.localIP();
sprintf(buf, "%u.%u.%u.%u", ip & 0xFF, (ip>>8) & 0xFF, (ip>>16) & 0xFF, (ip>>24) & 0xFF);

```

Maybe even better:

```
IPAddress ip = WiFi.localIP();
sprintf(buf, "%u.%u.%u.%u", ip[0], ip[1], ip[2], ip[3]);

```
> 3 votes

# Answer
There is also a one-line solution just as you wish. Instead of `String(ip)` use `ip.toString()`.

```
IPAddress ip = WiFi.localIP();
char *buf = malloc(128);
sprintf(buf, "%s", ip.toString().c_str());

```

Background: The function `Serial.println(ip);` calls `Print::print(const Printable& x)`, which in turn calls `IPAddress::printTo(Print& p)`.

```
size_t Print::print(const Printable& x) {
    return x.printTo(*this);
}

```

Alternatively, `String IPAddress::toString()` creates the desired string and reserves just the needed amount of memory (code from ESP8266 2.7.4)

```
String IPAddress::toString() const
{
    StreamString sstr;
#if LWIP_IPV6
    if (isV6())
        sstr.reserve(40); // 8 shorts x 4 chars each + 7 colons + nullterm
    else
#endif
        sstr.reserve(16); // 4 bytes with 3 chars max + 3 dots + nullterm, or '(IP unset)'
    printTo(sstr);
    return sstr;
}

```
> 2 votes

---
Tags: printf
---


# Question
Title: How to make motors start when pressing a button, and then go through a cycle with a specific motor order?
I'm very new to arduino and have to work on a project for school. We have connected 3 motors (Servo, Stepper (180 degrees) and a DC motor) to an Arduino Uno, Adafruit motorshield and a pcb. With the pcb we were able to record values of the motors individually and use these values to create a playback motion. The code which we got for the playback motion is below (I've already filled in my values for the 3 motors).

This is what I want to do with the motors:

When I press a button I want to 'start' the cycle of motor motions

1. first the dc motor starts doing the motion based on the chosen values
2. When this stops after 5 seconds I want the servo motor to do it's motion
3. When the servo motor is done, I want the stepper motor to start doing the motion based on the chosen values for 5 seconds and then stop.

We were told not to use a delay and someone suggested to use millis() instead of delay() but since I am a beginner I have no idea where to start.

This is the code:

```
// With this code it is possible to play back recorded motion paths for for motors connected to the Adafruit motorshield

#include <AccelStepper.h>
#include <Wire.h>
#include <Adafruit_MotorShield.h>
#include <Servo.h> // this is a library that allows you to drive servo's.

// variables
int modeChoice = 0;

int buttons = A2;  // the three buttons share an analog pin, resitors provide different levels that point to which button is pressed
int slide = A1;    // the slide is read through one analog pin, resitors provide different levels that point to which slide position is current
int rotation = A0; // the pin for the potentiometer

int buttonPressed = 0; // a variable to remember which button is pressed, it is used to control leds and motion memory position management

int buttonValRaw = 0; // a variable to store the raw analog reading of the buttons pin
int slideValRaw = 0;  // a variable to sore the raw analog reading of the slide pin
int valButton = 0;    // a variable to store the interpreted value, the exact pointer to a button
int valSlide = 0;     // a variable to store the interpreted value, the exact pointer to a slide position
int idleState = 0;    // a variable to toggle the servo idle behavior
int resetMotion = 0;  // a variable to return the arrayPosition to 0 if a button is pushed so that the behaviour starts at the beginning
int motionVar1;       // a variable to hold a motion position
int motionVar2;       // another variable to hold a motion position

int mySensorArray[20];  // an array with 20 slots to store raw potentiometer readings (for filtering)
int sensorArrayPos = 0; // the array position of interest.

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

int servoMotionArray_B1[50] = {95, 95, 95, 95, 65, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; // paste your 50 values in between the brackets

int DCMotionArray_B1[50] = {-85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85};

//recorded motions for position implementation
int StepperMotionArray_B1[50] = {-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200};

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

int arrayPosition = 0;

unsigned long mainTimer = 0; // a variable to time recording and playback
int timeBetweenSamples = 100; // the time between samples.

unsigned long debounceTimer = 0; // a variable to control a timer interval for debouncing of the buttons
int lastValButton = 0; // a variable to help debouncing of the buttons
int debounceFlag = 0; // another variabel to help debouncing of the buttons

// Setup motors
// Create the motor shield object with the default I2C address
Adafruit_MotorShield AFMS = Adafruit_MotorShield();
// Connect a stepper motor with 16 steps per revolution (2048 positions) to motor port #1 (M1 and M2) -- you need to change this if your stepper is on port #2
Adafruit_StepperMotor *myStepper = AFMS.getStepper(16, 1);
// And connect a DC motor to port M3 -- you need to change this if your DC is on a different port
Adafruit_DCMotor *myMotor = AFMS.getMotor(3);

Servo myservo1;   // servo object (employs the servo library that was included above)

// these are dedicated functions to make the steppermotor move
void forwardstep1() {
  myStepper->onestep(FORWARD, SINGLE);
}
void backwardstep1() {
  myStepper->onestep(BACKWARD, SINGLE);
}

//create aStepper object
AccelStepper aStepper(forwardstep1, backwardstep1); // use functions to step

// setup
void setup() {
  Serial.begin(9600); // start serial communication with 9600 baud rate

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

  myservo1.attach(9); // attach servo object to pin 9

  // turn on motor M3
  myMotor->setSpeed(0);
  myMotor->run(RELEASE);

  // setup the stepper
  aStepper.setSpeed(0); // this is used in the 'speed' implementation

  aStepper.setMaxSpeed(200.0); // these are used in the 'position' implementation
  aStepper.setAcceleration(100.0);
  aStepper.moveTo(0);

  // synchronize the first timer cycle -- because the timer is starting at zero it generates negative values in the first 100 miliseconds after starting up when going through the timer cycle, creating potential erratic bahaviour-- giving it a delay at the end of the setup loop will eradicate this behaviour
  delay(1000);
}

void doButtons() {
  if (buttonPressed != 0) {
    return;
  }
  else {
    buttonValRaw = analogRead(buttons);
    valButton = map (buttonValRaw, 49, 605, 0, 5);
    int localButtonVal = valButton;

    if (valButton > 7) {
      return;
    }

    if (debounceFlag == 0) {
      debounceTimer = millis();
      debounceFlag = 1;
    }

    if (debounceTimer < millis() - 20) {

      buttonValRaw = analogRead(buttons);
      valButton = map (buttonValRaw, 49, 605, 0, 5);

      if (valButton == localButtonVal) {
        debounceFlag = 0;

        switch (valButton) {
          case 1:
            buttonPressed = 1;
            break;
          case 2:
            buttonPressed = 2;
            break;
          case 3:
            buttonPressed = 3;
            break;
          default:
            buttonPressed = 0;
            break;
        }
      }
    }
  }
}

void loop() {
  doButtons(); // this uses the buttons from the PCB, if you use your own implementation you need to reprogram this function

  if (mainTimer < millis() - timeBetweenSamples) { // sampling only once per interval.
    mainTimer = millis(); // time is rewritten to current millis starting a new interval.

    if (buttonPressed == 0) { //'idle play'
      if (idleState == 0) {
        motionVar1 = servoMotionArray_B1[arrayPosition];
      }
      else if (idleState == 1){
        motionVar1 = servoMotionArray_B1[arrayPosition];
      }
      motionVar2 = DCMotionArray_B1[arrayPosition];
      myservo1.write(motionVar1);
      if (motionVar2 < 0) {
        myMotor->run(BACKWARD);
        myMotor->setSpeed(abs(motionVar2));
      }
      else if (motionVar2 >= 0) {
        myMotor->run(FORWARD);
        myMotor->setSpeed(motionVar2);
      }
      arrayPosition++;
      if (arrayPosition > 49) {
        arrayPosition = 0;
        idleState = !idleState;
      }
    }

    if (buttonPressed == 1) { //2nd behaviour
      if (resetMotion == 0) {
        arrayPosition = 0;
        resetMotion = 1;
        myMotor->run(RELEASE); // release the DC motor, otherwise it will continue spinning at the last known RPM
      }
      motionVar1 = servoMotionArray_B3[arrayPosition];
      motionVar2 = StepperMotionArray_B1[arrayPosition];
      myservo1.write(motionVar1);
      aStepper.moveTo(motionVar2);
      arrayPosition++;
      if (arrayPosition > 49) {
        arrayPosition = 0;
        buttonPressed = 0;
        resetMotion = 0;
      }
    }
  }

  // one of these needs to be called to make the stepper motor work, comment out the one you do not need (position or speed)
  //aStepper.run(); //stepper position implementation
  aStepper.runSpeed(); //stepper speed implementation

}

```

# Answer
You're almost correct already:

```
if (millis() - mainTimer >= timeBetweenSamples) {
  mainTimer = millis();
  // executing only once per interval.

  ... the action for current arrayPosition ...

  arrayPosition++;
  if (arrayPosition > 49) {
     arrayPosition = 0;
     buttonPressed = 0; // Show ends
  }
}

```
> 1 votes

---
Tags: servo, arduino-motor-shield, stepper
---


# Question
Title: Programming Servo How To Get -90 Degrees
as the question title states, how will I go about turning the servo opposite of 90 degrees?

I have written my code as such;

```
  // Turn servo to the right
  if(x > 520 && y < 510 && y > 490){
  servo.write(0);
  delay(50);

  //Turn left
  }else if(x < 490 && y < 510 && y > 490){
    servo.write(180);
    delay(50);

 //Turn backwards
} else if(y < 490 && x < 520 && x > 490){
  servo.write(-90);
  delay(50);

```

Obviously -90 isn't an actual degree on the servo, and it will only turn between 0 and 180. I was therefore wondering if there was any other way to code it?

The servo is connected to a joystick, and the plan is to built a 360 degrees vertical and 180 degrees horizontal turret of sorts. Every other command works, and when I replace -90 with 90 degrees, it works as well. So it is wired correctly.

Of course I would have to add another joystick and another servo later on, but at this stage I am simply testing my own coding skills.

# Answer
> 1 votes
Normal servos only have a range of 180°. You can give yourself an "offset", so you have -90° to 90°, but you only ever get 180° range. You can't go -90° to 180°.

Using mechanics (outside the scope of this site) you can multiply your movement (think gears) so that your range is bigger.

# Answer
> 1 votes
You say "The servo is connected to a joystick, and the plan is to built a 360 degrees vertical and 180 degrees horizontal turret of sorts. "

That doesn't make sense. How could a joystick rotate 360° in one dimension and 180° in the other dimension?

A joystick does not need an angle greater than 180°. It's mounted to a flat surface, and can only move 180° in two different dimensions, X and Y. (And actually probably more like 120° in each dimension.)

Use two 180 degree servos, one for the X axis and one for the Y axis.

Set the "neutral" position to 0

You can map the range 0 - 1320 to -90 to 90 using a map statement. (or adjust as needed since the range of motion of the joystick is probably less than 180 degrees - more like 120°, like chrisl said in their comment.)

See **this article** for info on how a 2-axis joystick works. Specifically look at the section titled "Gimbal Mechanism" a little ways down in the article.

# Answer
> 1 votes
If I understand correctly, you only need to move your servo through 180 degrees total, from one limit to the other, but you want -90 to represent one of the limits and +90 to represent the opposite limit? If so, just add 90 to the servo angle before you send it:

```
servo.write(angle+90);

```

This turns -90 into 0, 0 into 90, and 90 into 180. You get to use the coordinates that you like (-90 - +90) and the servo sees the coordinates it needs (0 - 180).

This is a simple case of mapping; there is a map() function that can do this for you for all mapping all kinds of ranges, one into another. Mapping (-90 - 90) into (0 - 180) is so straightforward that the map function really doesn't add anything, but in other cases it's handy to know about.

---
Tags: programming, servo
---


# Question
Title: 3v3 ESP one way communication with 5 V Arduino?
Perhaps I'm not fully understanding a difference between logic level and the function of the TX and RX pins? I'm just wondering if an ESP can send, one-way, data to an Arduino. (I found that two-way communication would need a logic level converter.)

ESP32 Datasheet  https://www.espressif.com/sites/default/files/documentation/esp32\_datasheet\_en.pdf#page=42

---

Arduino datasheets do not appear to specify logic level tolerances. It appears from this Arduino Forum post, it would work.

Is it universally assumed that 3v3 will be in tolerance for logic high?  https://learn.sparkfun.com/tutorials/logic-levels/all

# Answer
> 2 votes
Yes, it will work, but only just. It's borderline.

The ESP32 gives out at most 3.3V as a HIGH signal. The Arduino accepts "above 0.6Vcc" as a HIGH signal. That means that it needs to see a voltage that is at least 60% of the voltage on the Vcc pin (5V pin) of the Arduino.

If the Arduino has exactly 5V then 60% of that is 3V. Since 3.3V is higher than 3V it sees it has a HIGH.

However if the Arduino is being powered by a slightly higher voltage than 5V (some USB ports can give out 5.2V and it's still in spec) and if the ESP32 is being powered slightly below 3.3V, then that 0.3v margin of error gets narrower and narrower. Eventually it disappears and HIGH can no longer be detected.

For example if the Arduino has 5.2V and the ESP32 has 3.1V then the Arduino expects at least 3.12V and the ESP32 gives out no more than 3.1V.

So in most circumstances it does work, but there are factors that can stop it from working. Those factors can be mitigated by using logic level translation.

---
Tags: arduino-uno, esp8266, esp32
---


title: ADC register always returning high

text:
# Question
Title: ADC register always returning high
Regardless of whatever voltage at A0, the software is always returning high (1023)

```
volatile unsigned char* ADmux = (unsigned char*) 0x7C;
volatile unsigned char* ADCSRa = (unsigned char*) 0x7A;
volatile unsigned char* ADCSRb = (unsigned char*) 0x7B;
volatile unsigned char* ADCh = (unsigned char*) 0x79;
volatile unsigned char* ADCl = (unsigned char*) 0x78;
int Voltage;

void adc_init()
{
  *ADmux = 0x00; // setting entire register to 0's notably setting Refs1 and refs0 to 0's meaning reference voltage is AREF
  *ADCSRa = 0b10000111; //Sets most significant bit to 1, which is the ADC enable bit, and the 3 least signifcant bits are the prescalar, which is 128

}

unsigned int adc_read( unsigned char adc_channel)
{
  *ADmux = *ADmux | 0b00000000;// set mux bits to 0 to test A0 regardless of whatever adc_channel is
  *ADCSRa = *ADCSRa | 0b01000000; // set ADSC bit high to start conversion

  while(*ADCSRa & 0b01000000);//wait until ADSC goes low, indicated conversion is complete

  return ADC; //return bits in the adc registers
}

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

void loop() {
  // put your main code here, to run repeatedly:

  Voltage = adc_read(0b00000); // calls on adc_read

  Serial.print(Voltage); // prints voltage reading
  Serial.write("\n");

}

```

And here is a schematic of the circuit:

simulate this circuit – Schematic created using CircuitLab

I have combed over chapter 26 of the atmega2560 document and the descriptions of each register, but I am at a loss. Why is the contents of the adc registers always filled with 1's regardless of the voltage at a0?

# Answer
> 5 votes
First, let me give a couple of suggestions on the programming style. There is no point in defining your own variables for accessing the hardware registers: the avr-libc does that for you, you just have to `#include <avr/io.h>`. Actually, you don't have to #include anything: the Arduino IDE automatically #includes Arduino.h, which in turn #includes avr/io.h.

Next, the same avr-libc also defines macros for the bit names, so you don't have to explicitly write binary numbers in your own code (which is error-prone). And a couple of utility macros that you can use to make the code a little bit more readable. For example:

```
void adc_init()
{
    ADMUX  = _BV(REFS0);  // ADC reference = AVCC
    ADCSRA = _BV(ADEN)    // enable the ADC
           | _BV(ADPS2)   // set prescaler to 128
           | _BV(ADPS1)   // ditto
           | _BV(ADPS0);  // ditto
}

unsigned int adc_read(unsigned char adc_channel)
{
    ADMUX   = _BV(REFS0) | (adc_channel & 7);  // select channel
    ADCSRA |= _BV(ADSC);  // start conversion

    // Conversion is complete when ADSC goes low.
    loop_until_bit_is_clear(ADCSRA, ADSC);

    return ADC;  // return the adc data register
}

```

Now, let's answer your actual question. When you set both `REFS0` and `REFS1` to 0, the voltage reference is stated to be “AREF, internal V REF turned off”. The implication is that you are supposed to bring your own voltage reference and connect it to the AREF pin. Otherwise AREF is left as a floating input. This is illustrated in the schematic of the ADC. Here is the relevant part:

As you see here, `REFS0` is used to connect AREF to one of the other possible references: either AVCC or the internal bandgap. If `REFS0` is zero, the transistor depicted above is off, and AREF is left floating.

# Answer
> 2 votes
What are the resistance values for R1 and LDR1? Their ratio will determine the voltage at A0. If the ratio of their resistances is too high (for example, 100:1) then any light measured by LDR1 would only result in a small change in the voltage being measured. If the difference is extreme enough, the voltage could also appear to be constantly low or high. If you have a multimeter available, checking the voltage of that divider circuit could help determine what's going on.

https://learn.sparkfun.com/tutorials/voltage-dividers/all

---
Tags: analogread, atmega2560, analog
---


# Question
Title: Variable Fan Controller - Properly Sized Transistor
I would like to a build a temperature sensing variable speed fan controller for my truck. Currently using a purchased 2 speed on/off relay based controller, but my fans are overloading the whole circuit when the controller is powered on during a high speed temperature scenario. On low speed, I have the fans wired in series to spin both slower - works great. Each fan initially draws 100 amps at full 12v. On the low speed (6v/series), they cruise about 20a together. On high speed, they settle in around 25a each.

I am somewhat experienced with arduino and using a few references to build in specific features I want, but here is the main example I am going by. https://circuitdigest.com/microcontroller-projects/automatic-temperature-controlled-fan-project

My question is around the type and size of transistor that I would need to handle the amount of current these fans draw. Some examples have MOSFET while others have FET or even standard PNP. I am pretty new to working with transistors and can't find any references that make sense. Would love to get a reference to learn this calculation and appropriate type.

Edit: removed picture with incorrect wiring diagram.

# Answer
Doing a quick search for high-current MOSFET transistors, I ran across the following:

https://www.digikey.com/en/products/detail/ixys/IXFK170N20T/2126313

The important spec here is the Rds ON (max) of 11mOhm @ 60A, 10V

At your peak current of 100A, you would drop 1.1V across the transistor, for a power dissipation of 110W.

The advertised P(max) is 1150W, so assuming the junction temp can be held to under 175C (and with an entire metal truck to use for a heat sink, this shouldn't be a problem) you should be OK with this device. In the 'cruise' configuration with 25A motor current, you should have no problem controlling the fans.

YMMV ;-)
> 1 votes

---
Tags: current, transistor
---


# Question
Title: How to connect an lcd i2c using only pins A0 and A1 (SDA, SCL, GND, and VCC are given)
I want to know how to connect an lcd i2c, with an led 8x8 matrix at the same time. The problem is, all the analog in pins are used, except A0 and A1. Using this tutorial:

https://www.makerguides.com/character-i2c-lcd-arduino-tutorial/

It says I must have analog pins A0-A2 with nothing connecting, except I have A2 connected, which is why both screens don't work right. So how can I use only pins A0-A1 with an lcd i2c? Thanks.

# Answer
> 3 votes
You may be finding `Connect to LCD via I2C, default address 0x27 (A0-A2 not jumpered)` confusing. These refer to the I2C address selection lines of the IO expander (the PCF8574T) used on the I2C LCD display and not to the A0-A2 analog pins of the Arduino itself.

The note `// Wiring: SDA pin is connected to A4 and SCL pin to A5.` **is** referring to the analog pins of an UNO (or Nano) because these pins also happen to carry the ATMega328P's I2C ("Wire") signals.

So there's nothing about using the I2C display that prevents you from using the Analog A0-A2 pins of the Arduino for other purposes. Only the Arduino's A4 and A5 pins are used to carry I2C/Wire.

---
Tags: arduino-uno, led, lcd, analog
---


title: Testing 433MHz Transmitter

text:
# Question
Title: Testing 433MHz Transmitter
Folks,

There is a document named "Complete Guide for RF 433MHz Transmitter.pdf" available in the GitHub.

There is a a connection diagram showing the Data pin of the Transmitter connected to the pin 12 of the Arduino Uno.

The Transmitter sketch given in it is as follows:

```
#include <RH_ASK.h>
#include <SPI.h> // Not actually used but needed to compile

RH_ASK driver;

void setup()
{
 Serial.begin(9600); // Debugging only
 if (!driver.init())
 Serial.println("init failed");
}

void loop()
{
 const char *msg = "Hello World!";
 driver.send((uint8_t *)msg, strlen(msg));
 driver.waitPacketSent();
 delay(1000);
}

```

There is no mention of Pin 12 as part of the sketch. I am not sure how the Arduino knows the Transmitter Data input is connected to the Pin 12? Can someone please help?

Ranjith

# Answer
In RH\_ASK.h is:

```
RH_ASK(uint16_t speed = 2000, uint8_t rxPin = 11, uint8_t txPin = 12, uint8_t pttPin = 10, bool pttInverted = false);

```

So the argument has a default value specified here. If you don't specify it, it assumes that default.
> 2 votes

---
Tags: atmega2560
---


# Question
Title: Use a simple LED with no digital pins to spare
Problem: I've made a circuit consisting of an 8x8 led matrix, which uses all of the digital pins on the Arduino UNO board, and I want to add an LED too it.

I tried looking around the internet but so far, I have not seen any solution on how to use a simple LED with no digital pins to spare.

So I ask, is it possible to connect an LED with no leftover digital pins? I just want to be able to turn the LED on and off.

Thanks.

# Answer
> 1 votes
Just found this:

https://forum.arduino.cc/index.php?topic=311099.0

Turns out you can use the analog pins of an Arduino UNO using this:

```
pinMode(A1,OUTPUT);
digitalWrite(A1,HIGH);

```

You just have to list it as an analog pin. Seems to be working, don't think there are any downsides, as far as I see.

---
Tags: arduino-uno, led, pins, digitalwrite
---


# Question
Title: Seeing consistent serial data loss over USB, have ruled out hardware and rx/tx software. What's left?
I have a Lasersaur, which is an arduino-based open-source laser cutter. Part of its capabilities is raster engraving, where you etch images based on pixel data, rather than vector data. Recently I started experiencing a weird issue where I am losing some of the data that I am sending over serial to the machine, and the end of the image gets cut off. I don't believe those details are relevant to this question, but you can read my posts here for more info.

Basically, on my old Laptop B, engraving works. If I use the exact same USB hardware connection, firmware, frontend software executable, engraving settings, and image file on my current Laptop A, I see bad results. The last ~20 pixels or so of each image line are not etched in, and the only reason I can think for this is that the color data for these pixels were not sent in the first place. Notably, Laptop A used to work a few months ago when I last tried this out. So I'm pretty confident that I've ruled out hardware and rx/tx software as the possible issues.

The only difference between the two machines that I can think of that has changed since then is that I installed the Windows 10 1909 update, as well as some other software that I would have to dig back through to list out. I'd really like to not do a fresh Windows reinstall on my primary machine, but I'm close to that point.

Could something there be causing an issue? I'm out of my depth at this point, and don't know how either the operating system or another program could be affecting serial data transfer, and wouldn't know the first way to narrow it down.

Some more thoughts which may or may not be important:

* There does not seem to be data corruption, only data loss. The rx/tx protocol implements some error detection (sends every byte twice and checks for equality), and I am not seeing error corruption messages that would pop out if that were the case.
* There does not seem to be any randomness. The same behavior happens for images of different widths (leading me to think that the tx buffer isn't filling up), is the same for each image line, and has always been consistent.
* The Arduino in the machine is an Arduino Uno R3. Compilation is done using the Arduino compiler on some custom C code (not though the IDE).

# Answer
> 1 votes
I have solved the bug, you can see the writeup on the Lasersaur google group. The short of it was that this was a software bug, which was only being triggered when the hardware conspired to have some timing delays. I'm still unclear why the behavior was inconsistent previously - I must have been on the borderline of the data delays causing an issue or not.

# Answer
> 3 votes
The driver board for your "Lasersaur" appears to be based around the Adafruit Trinket Pro.

That board, on Adafruit's website, is deprecated, with the following warning:

> Deprecation Warning: The Pro Trinket bit-bang USB technique it uses doesn't work as well as it did in 2014, many modern computers won't work well. So while we still carry the Pro Trinket so that people can maintain some older projets, we no longer recommend it.

So basically the USB interface is naff. It's too slow to keep up with modern computers (hence your old laptop works but your new one doesn't), and you lose data.

You should look into the possibility of upgrading the controller board to something a little more modern and capable.

---

For UNO R3 based boards there is another fundamental flaw: there is a 64 byte receive buffer *and no flow control*. That means if you send data too fast - faster than the board can process it - data will be lost.

# Answer
> 1 votes
Well, I was able to resolve it, but I’m not sure how. After going through the steps I’ve outlined in my replies to answers here, I tried buying a new Arduino Uno R3, but that didn’t fix anything either. My last step was to do a Windows “Reset” which reinstalls Windows while keeping files but resets settings and programs. After reinstalling and adding back in all the programs I originally had, the serial communication worked again. I really don’t have a good explanation as to why this worked, but at least it did.

Edit: This problem reappeared, and the windows reset did not fix the issue this time.

---
Tags: serial, windows
---


title: ESP8266 and interrupts - not possible?

text:
# Question
Title: ESP8266 and interrupts - not possible?
I'm planning to use an ESP8266 (Wemos D1 Mini) to use as a software SPI monitor to send over WiFi.

As a test, I've done a cut-down sketch that just counts the interrupts, a simple frequency counter. I've made it as simple as possible but it won't stay connected to WiFi and crashes after about 10 seconds.

The input signal to CLKPin is 6667 Hz.

Here's the sketch:

```
#include <ESP8266WiFi.h>

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

long nextPrint = 1000; // when to print the next message to serial

const int CLKPin = 5; // Pin connected to CLK
volatile long ClkCount = 0; // number of times clock interrupt has fired

void CLK_ISR() {
  ClkCount++;
}

void setup() {
  Serial.begin(115200);
  long startTime = millis();

  WiFi.begin(ssid, password);             // Connect to the network
  Serial.print("Connecting to ");
  Serial.print(ssid); Serial.println(" ...");

  while (WiFi.status() != WL_CONNECTED) { // Wait for the Wi-Fi to connect
    delay(500);
    Serial.print(".");
  }
  Serial.println("\nConnected to wifi");

  attachInterrupt(CLKPin, CLK_ISR, RISING);

  //Set the CLK-pin to input
  pinMode(CLKPin, INPUT);
}

void loop() {
  if (millis() > nextPrint) {
    Serial.print("Freq is: ");
    Serial.println(ClkCount);
    ClkCount = 0;
    nextPrint += 1000;
  }
  yield();
}

```

It always gets in a reboot/crash loop (no idea why the first few counts are wrong - I guess the ESP isn't ready yet):

```
Connecting to SSID ...
.Connected to wifi
Freq is: 1
Freq is: 1
Freq is: 0
Freq is: 0
Freq is: 1
Freq is: 0
Freq is: 2313
Freq is: 6667
Freq is: 6666
Freq is: 6667
Freq is: 6667
Freq is: 6667
Freq is: 6667
Freq is: 6667
Freq is: 6667
Freq is: 6667

Exception (0):
epc1=0x40202034 epc2=0x00000000 epc3=0x00000000 excvaddr=0x00000000 depc=0x00000000

ctx: sys
sp: 3ffffc40 end: 3fffffb0 offset: 01a0

>>>stack>>>
3ffffde0:  401067da 00000026 00000000 00000001
3ffffdf0:  c0017025 3ffe8d04 3ffee188 00000001
3ffffe00:  00000003 00000008 3ffee99c 00000022
3ffffe10:  3fffc200 401067a0 3fffc258 4000050c
3ffffe20:  40004384 00000030 00000012 ffffffff
3ffffe30:  60000200 00000006 30043003 80000000
3ffffe40:  20000000 3fff0c38 80000000 203fc120
3ffffe50:  00000000 3fffc6fc 00000001 3fff0c3c
3ffffe60:  00000154 003fc120 60000600 00000030
3ffffe70:  40106845 00000080 00000022 3fffc200
3ffffe80:  c0017025 3fffc258 4000050c 00000022
3ffffe90:  3fffc200 401067a0 3fffc258 00000022
3ffffea0:  3fffc200 401067a0 3fffc258 4000050c
3ffffeb0:  40202b20 00000030 00000012 ffffffff
3ffffec0:  40000f49 3ffee9e8 00000000 3fffd9d0
3ffffed0:  00000000 00000000 00000000 fffffffe
3ffffee0:  ffffffff 3fffc6fc 00000001 3fffdab0
3ffffef0:  00000000 3fffdad0 3ffee9e8 00000030
3fffff00:  3ffee99c 0000000a 3ffe8bc8 402094cc
3fffff10:  00000000 400042db 3ffeff84 40104580
3fffff20:  40004b31 3fff0b84 000001f4 003fc080
3fffff30:  40105aac 000001f4 3ffed190 401004f4
3fffff40:  40106e4d 3fff0b84 00000000 00f8676f
3fffff50:  3ffe8bc8 3ffe8d04 3ffed190 40224d02
3fffff60:  40223d49 40223d52 3ffed004 3ffee1b0
3fffff70:  40228445 3ffed004 3ffee1b0 00f857fe
3fffff80:  4022848a 3fffdab0 00000000 3fffdcb0
3fffff90:  3ffee1c8 3fffdad0 3ffee9e8 40202b43
3fffffa0:  40000f49 40000f49 3fffdab0 40000f49
<<<stack<<<

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

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

wdt reset

```

What am I doing wrong, or is it just not possible to stay connected to WiFi while using interrupts on an ESP8266?

# Answer
I found the solution on another forum.

You need to add the `ICACHE_RAM_ATTR` attribute to the interrupt so it stays in cache.

```
void ICACHE_RAM_ATTR CLK_ISR() {
  ClkCount++;
}

```

Now:

```
Freq is: 332596 - connected for 680s, operating at 160MHz

```

That's all I tested to, but 330kHz is a *bit* better than crashing at 7kHz, lol!

**edit:** I've discovered that it now crashes after exactly 1200s (20mins), repetitively.

I'm still investigating why, but I believe that it's some kind of watchdog timer.
> 1 votes

# Answer
Yes possible, but the ESP8266 only has one core and one set of peripherals. WiFi uses time, interrupts, and even the ADC peripheral, and maybe more.

This is why anything timing-critical, or time-intensive, is a pain to get to work properly on an ESP8266. It depends one what you are trying to do, of course, and also on if you can unload what you want to a peripheral the WiFi doesn't use, or if switching off WiFi is an option during parts of your code.

Generally, for applications such as yours, I would get an ESP32 or an Arduino Nano 33 IoT or any other solution that has a core for handling WiFi, and a core for you to use without restrictions. It makes development a more pleasant experience.

If, for some reason, you are bound to using an ESP8266, you would have to be more specific about what your eventual goal is; maybe a workaround can be found.
> 1 votes

---
Tags: esp8266, wifi, interrupt
---


title: snprintf doesn't display float values

text:
# Question
Title: snprintf doesn't display float values
I don't understand why the formatted string is displaying ?? instead of float values. My code:

```
#include <Arduino.h>
#include <Wire.h>
#include "SparkFunCCS811.h"
#include <DFRobot_SHT3x.h>

DFRobot_SHT3x sht3x(&Wire, /*address=*/0x44, /*RST=*/4);

//* Get SHT31 readings

void readSHT(float &temp, float &humid)
{

    DFRobot_SHT3x::sRHAndTemp_t data = sht3x.readTemperatureAndHumidity(sht3x.eRepeatability_High);

    char shtVal[50];

    if (data.ERR == 0)
    {
        temp = data.TemperatureC;
        humid = data.Humidity;

        Serial.println(data.TemperatureC);
        Serial.println(data.Humidity);
    }

    snprintf(shtVal, 50, "Temp = %f  Humidity = %f", temp, humid);
    Serial.println(shtVal);
}

void setup()
{

    Serial.begin(115200);

    //*Initialize the chip
    while (sht3x.begin() != 0)
    {
        Serial.println("SHT31 Initialization Failed");
        delay(1000);

        Serial.print("Chip serial number");
        Serial.println(sht3x.readSerialNumber());

        if (!sht3x.softReset())
        {

            Serial.println("Failed to Initialize the chip....");
        }
    }
}

void loop()
{

    unsigned long newTime = millis();
    static unsigned long oldTime = 0;

    if (newTime - oldTime >= 5000)
    {

        float temp = 0.0;
        float humid = 0.0;

        oldTime = newTime;

        readSHT(temp, humid);
    }
}

```

& here is the output: Here is what I get as output:

```
21.23
41.06
Temp = ?  Humidity = ?

```

The function readSHT()has no problem displaying the actual values but why the formatted string shows ???. Am I doing something wrong?

# Answer
> 0 votes
The standard avr-libc does not have float support enabled in the `printf` family of functions. This is because float support would bloat your code massively, and most people don't need it.

It is possible to enable it through some black magic (I don't know what, but someone else may), but in general you don't want to since there are better ways.

Typically you would use `dtostrf()` to format your float into a `char` array separately. Or if all you are doing is printing to serial then you wouldn't even format it into a string in the first place.

```
Serial.print(F("Temp = "));
Serial.print(temp);
Serial.print(F("  Humidity = "));
Serial.println(humid);

```

---
Tags: c-string
---


title: Why use \" in arduino code?

text:
# Question
Title: Why use \" in arduino code?
While working with JSON parsing I noticed that the char type data string is written like this:

```
char json[] = "{\"sensor\":\"gps\",\"time\":1351824120,\"data\":[48.756080,2.302038]}";

```

Why there are (escapes) " ---" used in the code? Why can't we use the string normally?

# Answer
> 4 votes
> Why there are (escapes) " ---" used in the code? Why can't we use the string normally?

Because escapes are required.

In C `"` means 'The start or end of a string', but `\"` means 'A double-quote character'.

There has to be a way to distinguish a double-quote character from a string delimiter so the compiler knows which is which. Without escapes your string would look like:

```
char json[] = "{"sensor":"gps","time":1351824120,"data":[48.756080,2.302038]}";

```

and the compiler would find the end of the string at the second `"`, and then a load of junk before it finds the end-of-statement `;` character. It can't work out what `sensor":"gps","time":1351824120,"data":[48.756080,2.302038]}"` is supposed to be, since it isn't in the string, but after it.

---
Tags: string, data-type
---


# Question
Title: nRF24L01+ packet loss caused by Arduino reading and communicating with sensors
I have 2 Arduinos communicating with each other. My problem is that one sends packets every 1.5-2 seconds but the other Arduino does sensor reading and data uploading with a Wifi module, which may take up to 5 seconds until the next time the nRF24L01+ is available to receive data.

This results in about 4 packet losses and if I am lucky sometimes 2. Is there any way that when the nRF24L01+ sends data, the other Arduino stops everything to get the data? Like a communication between these two Arduinos that will be open 24/7, so that the other Arduino can multitask (reading sensors and upload the data through wifi).

I am using the code from this tutorial. Here is a my problem in an image (I hope this helps you understand it). Thanks in advance.

# Answer
You need to re-factor your program somewhat (I would imagine). The nRF needs to be read *at the same time* as doing other things. That means interleaving it with your other operations.

There is a concept called a finite state machine which is the best way of writing a complex program like this. The idea is that nothing ever *blocks*, it just changes states. And all the time other things can be happening, such as reading the nRF24L01+ module.

I have a little tutorial on the Finite State Machine here:

If you use the Finite State Machine concept to run the reading of your sensors and the writing of data to the WiFi the nRF can then be polled constantly outside of the FSM constantly - maybe with an FSM of its own to deal with reception etc.

Things to remember:

* Avoid `delay()`, certainly for anything longer than a couple of ms.
* Avoid `while()`, `for()`, etc except for very short loops that finish quickly.
* Any operation that takes more than a few ms to complete should be broken down into a number of sub-operations and coded as separate states of the FSM.
> 1 votes

# Answer
I see this is an old thread, but thought I'd chime in.

For an example implementation of a finite state machine, there are libraries built for this or you can use simple loop timers with if statements to "poll" sections of code instead of using ***ANY*** delays. Delays stop execution and waste your MCU time, preventing it from doing anything else, as already mentioned. Checking for wifi or serial messages can then execute with higher priority. An example pseudo-code would look like:

```
int update_ms = 500;
int last_update_ms;

setup{

last_update_ms = millis(); // or 0, to execute immediately

}

loop{

if(millis() - last_update_ms >= update_ms){
    last_update_ms = millis();
    execute_thing();}

check_for_wifi_msg();

}

```

There are libraries that do this essential behavior for you with more eloquence, as well, such as PollingTimer. I'm often surprised this isn't given as tool early on when people learn Arduino/ MCU programming, or in example codes. It is easy and so powerful.

You could accomplish the same "finite state machine" functionality with a real-time operating system built for microcontrollers. I can recommend FreeRTOS as a user-friendly entry to this. This makes your single core machine work like a multi-core machine, with a task scheduler. You can define several continually running while loops that the RTOS thread handler then interleaves for consistent execution. You could have 1 thread for your RF and 1 thread for your WiFi, with set execution rates, and RTOS handles the rest, e.g. it will try to fit RF reads inside of the Wifi loop whenever it can find downtime. This will likely make your Wifi loop somewhat longer as a sacrifice.

You can get started with these: FreeRTOS Kernel Quick Start Guide The FreeRTOS Reference Manual

Other solutions, which I won't elaborate on here include using a multi-core chip, like a ESP32, or to make use of WiFi interrupts to break out of other execution. Though, I do not know if this is specifically supported on the nRF24L01+.
> 1 votes

---
Tags: arduino-uno, communication, nrf24l01+, rf, datalogging
---


# Question
Title: ESP32 USB HID/MIDI library (not the BLE one)
I couldn't find any library to use an "old" ESP32 (not the new ESP32-S2) as an HID connected physicaly to the Usb port (not over BLE pairing) to send keystrokes to the PC ...
Is there any solution? Any code example, so far?
Thanks in advance!

# Answer
The ESP32 doesn't have USB. You can't do USB communication. All it has is (like the UNO) a USB to UART interface chip. Unlike the UNO this is *not* programmable (more like a cheap Chinese knock-off UNO clone in that respect).

You would need to couple it with a microcontroller that *has* USB and program *hat* to be your USB interface and communicate with it over some other communication medium, such as UART or I2C.
> 1 votes

---
Tags: esp32, midi, hid
---


# Question
Title: ISP Programmer with Serial and 5v/3.3v power
I currently use a Pololu USB AVR Programmer v2.1 for programming 328p chips and I really like it. The ability to have ISP and Serial in one physical device, enumerating as two separate COM ports on the PC, the programmer powering the circuit at 3.3v, with the programmers windows GUI interface to set voltages, programming frequency and give feedback on the programming when things go wrong, is all brilliant.

However, many of my circuits either have a power requirement higher than that on the Pololu (80mA), or to much capacitance (33uF) so that the power surge on connection is too much for the Pololu and it resets. The reset disconnects my serial debugger, disconnects the Pololu GUI, and sometimes does not come back on at all due to the startup current draw.

I am looking for suggestions for an alternative device, or way of stopping the brown out on power up?

Thanks very much Kevin

# Answer
How about, connecting a tiny battery across the 3.3v output of the Pololu. Lets assume a 3.7v LiPo, charged to 3.3v.

When the battery is connected at 3.3v, no current will flow.

When my device to be programmed is connected it will draw a spike of current, which will start to take the Pololu below 3.3v, but then the LiPo will start supplying current and stop the Pololu voltage getting dragged down and browning out.

The LiPo will then be slightly below 3.3v, so will get a Constant Voltage charge back to 3.3v.

Two potential issues I can see:

1. When the Pololu is disconnected from the USB will it be being 'back powered' by the LiPo?
2. When in CV charge mode, the only current limiting will be internal resistance of the Pololu output / LiPo cell, probably not an issue in practice due to the voltage drop being very small.

I know it is a hack, but thoughts welcomed.

Cheers Kev
> 1 votes

---
Tags: avr, isp, programmer
---


# Question
Title: Can i store a SqlLite DB into an (old) ESP32? (not using SD card)
I would like to know if it is possible to store a (little, basic) SqlLite DataBase (or of any other type) into the (old) ESP32.
I don't want to use an SD card for that (for which I already know it is possible).
Thanks in advance for any hint on this

# Answer
> 1 votes
I found these two post to be a useful answer to my question:

# Answer
> 0 votes
Yes you can - or you can certainly store it. ESP32 can use its flash as a filesystem (SPIFFS, LittleFS, FAT, etc) so you can store whatever data you like on there.

Whether the SQLite library can work with that file is another matter though, and is something you would have to explore yourself.

However for your use case using a database file is a bit silly. If all you want is some pre-defined runtime settings then all you really need is a simple text file. Maybe something like an INI file (key=value pairs) would be plenty for your needs, and pretty simple to parse without any libraries.

---
Tags: esp32
---