Skip to content

10. Output devices

1Servo_Output

Research

Individual Assignment

  • Add an output device to a microcontroller board you’ve designed and program it to do something.

For my Output week study, I modified my latest circuit to be able to connect Servo motors as the output.

Previous circuit was as follows;
latest input circuit

Copy the previous KiCAD folder in Windows explore.
copy Kicad folder

Change the folder name into “KICad_Servo_Out”.
change the folder name

Change following three files name as same name as the new folder name.
Change the file names as well

Changing three files’ name as new folder name.
Changing into same name as folder

Confirm if the “Update PCB” functions.
confirmed that Update PCB function

Check the Pin order of normal Servo Motor.
servo motor pin order

Added 2pin flat connector for outside 5V power.
2Pin for outside 5V power

Added 4pin flat connector for RX TX communication week following my instructor Kae’s suggestion.
4pin for RX TX week

Added Diode Shottky for outside 5V power.
diode shottky

Schematics for the two Servo Output circuit
Shematics

Checked “Run DRC” as no error
checked Run DRC

Measured actual Potentiometer size as follows;
B10K Potentiometer measurement size
Outside Diameter of cylinder 16.5mm
Pin Pitch 5.0mm
actual potentiometer size
B10K Potentiometer measurement size
Outside Diameter of cylinder 16.5mm
Pin Pitch 5.0mm

Since the potentiometer pin position is higher than the cylindrical part at the bottom, I decided to make a hole for cylindrical part for soldering fixation.
Make a hole with the center from the center pin at the distance of 13.25mm
16.5/2 + 5 (pin distance from case edge) = 13.25mm

With above measurement result, I designed additional part in my previous Development Board.

Mention actual Potentiometer size into PCB drawing
measured actual servo size

Here under is the KICAD PCB circuit drawing
KiCAD PCB

Arduino Code for Analog input and output test with potentiometer

int anavalue;

void setup() {
  // put your main code here, to run repeatedly:  
  pinMode(A2,INPUT);  

  // put your setup code here, to run once:
  Serial.begin(115200);

}

void loop() {
  // put your main code here, to run repeatedly:  
  anavalue = analogRead(A2);
  Serial.print("input value:");
  Serial.println(anavalue);

  delay(100);

}

I checked the input signal is read in plotter.

Then I made the following code by referencing the Book “Prototyping Lab by Shigeru Kobayashi” page 217.
Book page217

#include <Servo.h>  

int anavalue;  

Servo servo;  


void setup() {
  // put your main code here, to run repeatedly:  
  pinMode(A2,INPUT);  
  // set servo signal pin as D9:  
  servo.attach(D9);  

  // put your setup code here, to run once:
  Serial.begin(115200);

}

void loop() {
  // put your main code here, to run repeatedly:  
  anavalue = analogRead(A2);  
  // scaling the input value from 0 to 180:  
  int angle = map(value, 0, 4095, 0, 180);  
  // set servo angle:  
  servo.write(angle);  
  Serial.print("input value:");
  Serial.println(anavalue);

  delay(100);

}

I had following error by Arduino IDE;

WARNING: library Servo claims to run on avr, megaavr, sam, samd, nrf52, stm32f4, mbed, mbed_nano, mbed_portenta, mbed_rp2040, renesas, renesas_portenta, renesas_uno architecture(s) and may be incompatible with your current board which runs on esp32 architecture(s).
In file included from C:\Users\kohsh\OneDrive\Documents\Arduino\Potentiometer_test\Potentiometer_test.ino:1:
C:\Users\kohsh\AppData\Local\Arduino15\libraries\Servo\src/Servo.h:81:2: error: #error "This library only supports boards with an AVR, SAM, SAMD, NRF52, STM32F4, Renesas or XMC processor."
   81 | #error "This library only supports boards with an AVR, SAM, SAMD, NRF52, STM32F4, Renesas or XMC processor."
      |  ^~~~~
exit status 1

Compilation error: exit status 1

It seems I have to download and install the Servo library for XIAO-ESP32C3.

Here under are several method to install Servo library into Arduino IDE.
* How to install Servo Library in Arduino IDE

Reading above information, I decided to follow Dlloydev/ESP32-ESP32S2-AnalogWrite

Search XIAO-ESP32 Servo Library from Arduino IDE Sketch though “Manage Libraries”.
finding Library

Install “ESP32-ESP32S2-AnalogWrite” Library into IDE.
Install Library into IDE

Downloading the library into IDE
Downloading the Library

The library installation page explains to set following code at the beginning of IDE programming.
Guide in the explanation

Then I modified my code as follows;

#include <Servo.h>
// Servo myservo = Servo();

Servo myservo;  

int anavalue;  

// Servo servo;  


void setup() {
  // put your main code here, to run repeatedly:  
  pinMode(A2,INPUT);  
  // set servo signal pin as D9:  
  myservo.attach(D9);  


  // put your setup code here, to run once:
  Serial.begin(115200);

}

void loop() {
  // put your main code here, to run repeatedly:  
  anavalue = analogRead(A2);  
  // scaling the input value from 0 to 180:  
  int angle = map(anavalue, 0, 4095, 0, 180);  
  // set servo angle:  
  myservo.write(D9, angle);  
  Serial.print("input value:");
  Serial.println(anavalue);

  delay(100);

}

Then got following error by Arduino IDE.

c:\Users\kohsh\OneDrive\Documents\Arduino\libraries\ESP32_ESP32S2_AnalogWrite\src\pwmWrite.cpp: In member function 'uint8_t Pwm::attach(int)':
c:\Users\kohsh\OneDrive\Documents\Arduino\libraries\ESP32_ESP32S2_AnalogWrite\src\pwmWrite.cpp:55:9: error: 'ledcSetup' was not declared in this scope; did you mean 'ledc_stop'?
   55 |         ledcSetup(ch, mem[ch].frequency, mem[ch].resolution);
      |         ^~~~~
      |         ledc_stop
c:\Users\kohsh\OneDrive\Documents\Arduino\libraries\ESP32_ESP32S2_AnalogWrite\src\pwmWrite.cpp:57:9: error: 'ledcAttachPin' was not declared in this scope; did you mean 'ledcAttach'?
   57 |         ledcAttachPin(pin, ch);
      |         ^~~~~
      |         ledcAttach
c:\Users\kohsh\OneDrive\Documents\Arduino\libraries\ESP32_ESP32S2_AnalogWrite\src\pwmWrite.cpp: In member function 'uint8_t Pwm::attach(int, int)':
c:\Users\kohsh\OneDrive\Documents\Arduino\libraries\ESP32_ESP32S2_AnalogWrite\src\pwmWrite.cpp:68:5: error: 'ledcSetup' was not declared in this scope; did you mean 'ledc_stop'?
   68 |     ledcSetup(ch, mem[ch].frequency, mem[ch].resolution);
      |     ^~~~~
      |     ledc_stop
c:\Users\kohsh\OneDrive\Documents\Arduino\libraries\ESP32_ESP32S2_AnalogWrite\src\pwmWrite.cpp:70:5: error: 'ledcAttachPin' was not declared in this scope; did you mean 'ledcAttach'?
   70 |     ledcAttachPin(pin, ch);
      |     ^~~~~
      |     ledcAttach
c:\Users\kohsh\OneDrive\Documents\Arduino\libraries\ESP32_ESP32S2_AnalogWrite\src\pwmWrite.cpp: In member function 'uint8_t Pwm::attachInvert(int)':
c:\Users\kohsh\OneDrive\Documents\Arduino\libraries\ESP32_ESP32S2_AnalogWrite\src\pwmWrite.cpp:78:3: error: 'ledcSetup' was not declared in this scope; did you mean 'ledc_stop'?
   78 |   ledcSetup(ch, mem[ch].frequency, mem[ch].resolution);
      |   ^~~~~
      |   ledc_stop
c:\Users\kohsh\OneDrive\Documents\Arduino\libraries\ESP32_ESP32S2_AnalogWrite\src\pwmWrite.cpp: In member function 'uint8_t Pwm::attachInvert(int, int)':
c:\Users\kohsh\OneDrive\Documents\Arduino\libraries\ESP32_ESP32S2_AnalogWrite\src\pwmWrite.cpp:87:5: error: 'ledcSetup' was not declared in this scope; did you mean 'ledc_stop'?
   87 |     ledcSetup(ch, mem[ch].frequency, mem[ch].resolution);
      |     ^~~~~
      |     ledc_stop
c:\Users\kohsh\OneDrive\Documents\Arduino\libraries\ESP32_ESP32S2_AnalogWrite\src\pwmWrite.cpp: In member function 'float Pwm::writeServo(int, float)':
c:\Users\kohsh\OneDrive\Documents\Arduino\libraries\ESP32_ESP32S2_AnalogWrite\src\pwmWrite.cpp:180:9: error: 'ledcSetup' was not declared in this scope; did you mean 'ledc_stop'?
  180 |         ledcSetup(ch, mem[ch].frequency, mem[ch].resolution);
      |         ^~~~~
      |         ledc_stop
c:\Users\kohsh\OneDrive\Documents\Arduino\libraries\ESP32_ESP32S2_AnalogWrite\src\pwmWrite.cpp:182:9: error: 'ledcAttachPin' was not declared in this scope; did you mean 'ledcAttach'?
  182 |         ledcAttachPin(pin, ch);
      |         ^~~~~
      |         ledcAttach
c:\Users\kohsh\OneDrive\Documents\Arduino\libraries\ESP32_ESP32S2_AnalogWrite\src\pwmWrite.cpp: In member function 'void Pwm::detach(int)':
c:\Users\kohsh\OneDrive\Documents\Arduino\libraries\ESP32_ESP32S2_AnalogWrite\src\pwmWrite.cpp:253:5: error: 'ledcDetachPin' was not declared in this scope; did you mean 'ledcDetach'?
  253 |     ledcDetachPin(mem[ch].pin); // jitterless
      |     ^~~~~
      |     ledcDetach
In file included from C:\Users\kohsh\AppData\Local\Arduino15\packages\esp32\tools\esp32c3-libs\3.3.7/include/soc/esp32c3/register/soc/interrupt_core0_reg.h:13,
                 from C:\Users\kohsh\AppData\Local\Arduino15\packages\esp32\tools\esp32c3-libs\3.3.7/include/soc/esp32c3/include/soc/interrupt_reg.h:8,
                 from C:\Users\kohsh\AppData\Local\Arduino15\packages\esp32\tools\esp32c3-libs\3.3.7/include/riscv/include/riscv/rv_utils.h:12,
                 from C:\Users\kohsh\AppData\Local\Arduino15\packages\esp32\tools\esp32c3-libs\3.3.7/include/esp_hw_support/include/esp_cpu.h:19,
                 from C:\Users\kohsh\AppData\Local\Arduino15\packages\esp32\tools\esp32c3-libs\3.3.7/include/esp_hw_support/include/spinlock.h:11,
                 from C:\Users\kohsh\AppData\Local\Arduino15\packages\esp32\tools\esp32c3-libs\3.3.7/include/freertos/FreeRTOS-Kernel/portable/riscv/include/freertos/portmacro.h:65,
                 from C:\Users\kohsh\AppData\Local\Arduino15\packages\esp32\tools\esp32c3-libs\3.3.7/include/freertos/FreeRTOS-Kernel/include/freertos/portable.h:57,
                 from C:\Users\kohsh\AppData\Local\Arduino15\packages\esp32\tools\esp32c3-libs\3.3.7/include/freertos/FreeRTOS-Kernel/include/freertos/FreeRTOS.h:69,
                 from C:\Users\kohsh\AppData\Local\Arduino15\packages\esp32\hardware\esp32\3.3.7\cores\esp32/Arduino.h:33,
                 from c:\Users\kohsh\OneDrive\Documents\Arduino\libraries\ESP32_ESP32S2_AnalogWrite\src\pwmWrite.cpp:7:
c:\Users\kohsh\OneDrive\Documents\Arduino\libraries\ESP32_ESP32S2_AnalogWrite\src\pwmWrite.cpp:254:19: error: 'GPIO_PIN_MUX_REG' was not declared in this scope; did you mean 'GPIO_PIN19_REG'?
  254 |     REG_SET_FIELD(GPIO_PIN_MUX_REG[pin], MCU_SEL, GPIO_MODE_DEF_DISABLE);
      |                   ^~~~~~
C:\Users\kohsh\AppData\Local\Arduino15\packages\esp32\tools\esp32c3-libs\3.3.7/include/soc/esp32c3/include/soc/soc.h:37:37: note: in definition of macro 'REG_WRITE'
   37 |             (*(volatile uint32_t *)(_r)) = (_v);                                                                       \
      |                                     ^~
c:\Users\kohsh\OneDrive\Documents\Arduino\libraries\ESP32_ESP32S2_AnalogWrite\src\pwmWrite.cpp:254:5: note: in expansion of macro 'REG_SET_FIELD'
  254 |     REG_SET_FIELD(GPIO_PIN_MUX_REG[pin], MCU_SEL, GPIO_MODE_DEF_DISABLE);
      |     ^~~~~
C:\Users\kohsh\AppData\Local\Arduino15\packages\esp32\tools\esp32c3-libs\3.3.7/include/soc/esp32c3/include/soc/soc.h:72:43: error: invalid operands of types 'void' and 'int' to binary 'operator&'
   72 |             REG_WRITE((_r),((REG_READ(_r) & ~((_f##_V) << (_f##_S)))|(((_v) & (_f##_V))<<(_f##_S))));                  \
      |                                           ^ ~~~~~~~~~
      |                                             |
      |                                             int
C:\Users\kohsh\AppData\Local\Arduino15\packages\esp32\tools\esp32c3-libs\3.3.7/include/soc/esp32c3/include/soc/soc.h:37:45: note: in definition of macro 'REG_WRITE'
   37 |             (*(volatile uint32_t *)(_r)) = (_v);                                                                       \
      |                                             ^~
c:\Users\kohsh\OneDrive\Documents\Arduino\libraries\ESP32_ESP32S2_AnalogWrite\src\pwmWrite.cpp:254:5: note: in expansion of macro 'REG_SET_FIELD'
  254 |     REG_SET_FIELD(GPIO_PIN_MUX_REG[pin], MCU_SEL, GPIO_MODE_DEF_DISABLE);
      |     ^~~~~
c:\Users\kohsh\OneDrive\Documents\Arduino\libraries\ESP32_ESP32S2_AnalogWrite\src\pwmWrite.cpp: In member function 'bool Pwm::detached(int)':
c:\Users\kohsh\OneDrive\Documents\Arduino\libraries\ESP32_ESP32S2_AnalogWrite\src\pwmWrite.cpp:259:22: error: 'GPIO_PIN_MUX_REG' was not declared in this scope; did you mean 'GPIO_PIN19_REG'?
  259 |   if ((REG_GET_FIELD(GPIO_PIN_MUX_REG[pin], MCU_SEL)) == 0) return true;
      |                      ^~~~~~
C:\Users\kohsh\AppData\Local\Arduino15\packages\esp32\tools\esp32c3-libs\3.3.7/include/soc/esp32c3/include/soc/soc.h:42:37: note: in definition of macro 'REG_READ'
   42 |             (*(volatile uint32_t *)(_r));                                                                              \
      |                                     ^~
c:\Users\kohsh\OneDrive\Documents\Arduino\libraries\ESP32_ESP32S2_AnalogWrite\src\pwmWrite.cpp:259:8: note: in expansion of macro 'REG_GET_FIELD'
  259 |   if ((REG_GET_FIELD(GPIO_PIN_MUX_REG[pin], MCU_SEL)) == 0) return true;
      |        ^~~~~
C:\Users\kohsh\AppData\Local\Arduino15\packages\esp32\tools\esp32c3-libs\3.3.7/include/soc/esp32c3/include/soc/soc.h:67:28: error: invalid operands of types 'void' and 'int' to binary 'operator>>'
   67 |             ((REG_READ(_r) >> (_f##_S)) & (_f##_V));                                                                   \
      |                            ^~ ~~~~
c:\Users\kohsh\OneDrive\Documents\Arduino\libraries\ESP32_ESP32S2_AnalogWrite\src\pwmWrite.cpp:259:8: note: in expansion of macro 'REG_GET_FIELD'
  259 |   if ((REG_GET_FIELD(GPIO_PIN_MUX_REG[pin], MCU_SEL)) == 0) return true;
      |        ^~~~~
c:\Users\kohsh\OneDrive\Documents\Arduino\libraries\ESP32_ESP32S2_AnalogWrite\src\pwmWrite.cpp:259:55: error: invalid operands of types 'void' and 'int' to binary 'operator=='
  259 |   if ((REG_GET_FIELD(GPIO_PIN_MUX_REG[pin], MCU_SEL)) == 0) return true;
      |       ~~~~~~~~~~~~~~~~ ^ ~
      |                                                          |
      |                                                          int
c:\Users\kohsh\OneDrive\Documents\Arduino\libraries\ESP32_ESP32S2_AnalogWrite\src\pwmWrite.cpp: In member function 'float Pwm::setFrequency(int, uint32_t)':
c:\Users\kohsh\OneDrive\Documents\Arduino\libraries\ESP32_ESP32S2_AnalogWrite\src\pwmWrite.cpp:283:7: error: 'ledcSetup' was not declared in this scope; did you mean 'ledc_stop'?
  283 |       ledcSetup(ch, frequency, mem[ch].resolution);
      |       ^~~~~
      |       ledc_stop
c:\Users\kohsh\OneDrive\Documents\Arduino\libraries\ESP32_ESP32S2_AnalogWrite\src\pwmWrite.cpp: In member function 'uint8_t Pwm::setResolution(int, uint8_t)':
c:\Users\kohsh\OneDrive\Documents\Arduino\libraries\ESP32_ESP32S2_AnalogWrite\src\pwmWrite.cpp:297:7: error: 'ledcSetup' was not declared in this scope; did you mean 'ledc_stop'?
  297 |       ledcSetup(ch, mem[ch].frequency, resolution);
      |       ^~~~~
      |       ledc_stop
c:\Users\kohsh\OneDrive\Documents\Arduino\libraries\ESP32_ESP32S2_AnalogWrite\src\pwmWrite.cpp: In member function 'void Pwm::wr_servo(int, float, double, double)':
c:\Users\kohsh\OneDrive\Documents\Arduino\libraries\ESP32_ESP32S2_AnalogWrite\src\pwmWrite.cpp:376:9: error: 'ledcSetup' was not declared in this scope; did you mean 'ledc_stop'?
  376 |         ledcSetup(ch, mem[ch].frequency, mem[ch].resolution);
      |         ^~~~~
      |         ledc_stop
c:\Users\kohsh\OneDrive\Documents\Arduino\libraries\ESP32_ESP32S2_AnalogWrite\src\pwmWrite.cpp:378:9: error: 'ledcAttachPin' was not declared in this scope; did you mean 'ledcAttach'?
  378 |         ledcAttachPin(pin, ch);
      |         ^~~~~
      |         ledcAttach
c:\Users\kohsh\OneDrive\Documents\Arduino\libraries\ESP32_ESP32S2_AnalogWrite\src\pwmWrite.cpp: In member function 'void Pwm::wr_freq_res(int, uint32_t, uint8_t)':
c:\Users\kohsh\OneDrive\Documents\Arduino\libraries\ESP32_ESP32S2_AnalogWrite\src\pwmWrite.cpp:451:5: error: 'ledcSetup' was not declared in this scope; did you mean 'ledc_stop'?
  451 |     ledcSetup(ch, frequency, resolution);
      |     ^~~~~
      |     ledc_stop
Multiple libraries were found for "Servo.h"
  Used: C:\Users\kohsh\OneDrive\Documents\Arduino\libraries\ESP32_ESP32S2_AnalogWrite
  Not used: C:\Users\kohsh\AppData\Local\Arduino15\libraries\Servo
exit status 1

Compilation error: exit status 1  

I modified several part and confirmed several times and came to following coding which still have few errors.

#include <Servo.h>
Servo myservo = Servo();

// Servo myservo;  

int anavalue;  

// Servo servo;  



void setup() {
  // put your main code here, to run repeatedly:  
  pinMode(A2,INPUT);  
  // set servo signal pin as D9:  
  myservo.attach(D9);  


  // put your setup code here, to run once:
  Serial.begin(115200);

}

void loop() {
  // put your main code here, to run repeatedly:  
  anavalue = analogRead(A2);  
  // scaling the input value from 0 to 180:  
  int angle = map(anavalue, 0, 4095, 0, 180);  
  // set servo angle:  
  myservo.write(D9, angle);  
  Serial.print("input value:");
  Serial.println(anavalue);

  delay(100);

}

Then I decided to ask Copliot with following prompt;

Would you check what it wrong with following code for Arduino IDE?  
------------copied above mentioned coding-------------  

Got following advice by Copilot;

On ESP32 family boards, including ESP32‑C3, the classic Servo.h can be problematic depending on core/library versions. The commonly recommended approach is using ESP32Servo for stable PWM servo control on ESP32 boards. [docs.arduino.cc], [github.com]
So I recommend switching to:
#include <ESP32Servo.h>  

Then I decided to change the librarry from “ESP32-ESP32S2-AnalogWrite” to “ESP32Servo(by Kevin Harrington, John K.Bennett)”.
ESP32Servo library

I copied the modified coding by Copilot as a trial.

#include <ESP32Servo.h>

Servo myservo;

int anavalue;

const int POT_PIN   = A2;
const int SERVO_PIN = D9; // If upload gets unstable, change to D8 [3](https://lab.seeed.co.jp/entry/2023/04/03/120000)[4](https://qiita.com/ginger/items/476012a24c6b30121606)

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

  // analogRead works without pinMode, but it's okay to keep it
  pinMode(POT_PIN, INPUT);

  // SG90 typical pulse range
  myservo.setPeriodHertz(50);
  myservo.attach(SERVO_PIN, 500, 2400);
}

void loop() {
  anavalue = analogRead(POT_PIN);                 // 0..4095 typical
  int angle = map(anavalue, 0, 4095, 0, 180);
  angle = constrain(angle, 0, 180);

  myservo.write(angle);                           // <-- Correct usage

  Serial.print("input value: ");
  Serial.print(anavalue);
  Serial.print("  angle: ");
  Serial.println(angle);

  delay(20); // 20ms is a nice servo update interval
}

It worked with my Development Board.
1 servo output set

Then I modified a bit about potentiometer opertion angle to make it less angle operation to drive the servo full angle (180deg).

void loop() {
  anavalue = analogRead(POT_PIN);                 // 0..4095 typical
  // int angle = map(anavalue, 0, 4095, 0, 180);
  int angle = map(anavalue, 0, 2048, 0, 180);
  angle = constrain(angle, 0, 180);  
  • Useful information I got from Asian Session on March 31st day time

    I need to study Mishael Sharaf in Kochi’s Output week study regarding the PWM.

Inforamtion for Shaheen; DOIT ESP32 DevKit V1 Wi-Fi Development Board – Pinout Diagram & Arduino Reference

Inforamtion from Rico; Like Sevo Motor, Neo Pixel is currncy hngry device. Adafruit Neo Pixel consumption; Adafruit NeoPixel Überguide

Importing KiCAD line thickness from past project by Merin Cyriac

Servo Motor study by Ardradevi