W11 - Output Devices

1. Weekly Assignments ( -> what I did this week )

  • Group assignment

  • Measure the power consumption of an output device

  • Document your work (in a group or individually)

( -> I measured the power consumption of servo motor ( SG90-HV ). )

  • Individual assignment

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

( -> I added a servo motor ( SG90-HV ) to the class kit with ATtiny44, and programed to control the rotational speed of servo. Also, I made ESP32 - based MCU, modifying “Barduino 2.0”, milling PCB, and tested it as a part of my Final Project Drive Simulator. )

Have you?

Questions from “Fab Academy 2020 Assignments and Assessment

Output Devices

( -> my answers )

  • Linked to the group assignment page ( -> yes )

  • Documented how you determined power consumption of an output device with your group ( -> yes )

  • Documented what you learned from interfacing output device(s) to microcontroller and controlling the device(s) ( -> yes )

  • Described your design and fabrication process or linked to previous examples. ( -> yes )

  • Explained the programming process/es you used ( -> yes )

  • Outlined problems and how you fixed them ( -> yes )

  • Included original design files and code ( -> yes )

  • Included a ‘hero shot/video’ of your board ( -> yes )

Link

3. Works, steps and some details

3 - A . Online local session, ( ATTiny breakout board + breadboard + servo motor )

servo motors

SG90 ; lever-type, limited angle

SG90-HV ; continuous rotation

SG90 datasheet

board software input output
1 Arduino Arduino potentiometer SG90-HV
2 Arduino Arduino potentiometer SG90
3 ATtiny44 (breadboard) Arduino potentiometer SG90-HV
4 ATtiny44 (breadboard) Arduino potentiometer SG90
5 ATtiny44 (breadboard) C none SG90-HV
6 ATtiny44 (breadboard) C none SG90

0) preparation

- soldering ( ATTiny44 breakout board )

( I missed the XTAL soldering because my solder was too hot maybe. So, I used internal 8MHz clock instead of external 20MHz.)

- draw the cirquit diagram in accoradnce with the sample shown in the fab academy site ( servo )
- connecting the components of the breadboard

1) test 1

board software input output
1 Arduino Arduino potentiometer SG90-HV

code ” servo_sg90hv_test_arduino.ino “

#include <Servo.h>

Servo servo;//create servo objects

void setup(){
  //servo signal to GPTO pin3
  servo.attach(3);
  Serial.begin(9600); 

}

void loop(){
  //read sensor value
  int val=analogRead(0);
  //Serial.println(val);
  Serial.print(val);
  Serial.println("");
  delay(100);
  //map() to convert sensor value(0-678) to angle(0-180)
  int angle=map(val,0,678,0,180);
  //output to servo
 // Serial.println(angle);
  servo.write(angle);

}

2) test 2

board software input output
2 Arduino Arduino potentiometer SG90

code ” servo_sg90hv_test_arduino.ino ” <- same as test 1

3) test 3

board software input output
3 ATtiny44 (breadboard) Arduino potentiometer SG90-HV

In Arduino IDE, I selected clock ; “8 MHz (internal) ” from “Tool” option.

code ” servo_sg90hv_attiny44.ino “

#include <Servo.h>

Servo servo;//create servo objects

void setup(){
  //servo signal to GPTO pin7
  servo.attach(7);
  Serial.begin(9600); 

}

void loop(){
  //read sensor value
  int val=analogRead(0);
  //Serial.println(val);
  Serial.print(val);
  Serial.println("");
  delay(100);
  //map() to convert sensor value to speed
  int angle=map(val,50,400,56,84);
  //output to servo
 // Serial.println(angle);
  servo.write(angle);

}

I carefully tuned the parameters in the “map” function so that servo rotational speed can be controlled smoothly. ( for example, the numbers ; 56, 84 )

4) test 4

board software input output
4 ATtiny44 (breadboard) Arduino potentiometer SG90

In Arduino IDE, I selected clock ; “8 MHz (internal) ” from “Tool” option.

code ” servo_sg90hv_attiny44.ino ” <- same as test 3

result ; moves, but not smooth

no video

5) test 5

board software input output
5 ATtiny44 (breadboard) C none SG90-HV

Firstly, I used “hello.servo.44.c.make” and “hello.servo.44.c”, but it didn’t work, because of the clock frequency difference.

In accordance with the suggestion from the instructor ( Kae Nagano ), some numbers in the codes “hello.servo.44.c.make” and “hello.servo.44.c” were changed.

code ” 8mh_hello.servo.44.c.make ”

changed portions ;

  • line number 1 ; file name
  • line number 4 ; F_CPU = 8000000 ( original, F_CPU = 20000000 )
PROJECT=8mh_hello.servo.44
SOURCES=$(PROJECT).c
MMCU=attiny44
F_CPU = 8000000

CFLAGS=-mmcu=$(MMCU) -Wall -Os -DF_CPU=$(F_CPU)

$(PROJECT).hex: $(PROJECT).out
    avr-objcopy -O ihex $(PROJECT).out $(PROJECT).c.hex;\
    avr-size --mcu=$(MMCU) --format=avr $(PROJECT).out

$(PROJECT).out: $(SOURCES)
    avr-gcc $(CFLAGS) -I./ -o $(PROJECT).out $(SOURCES)

program-bsd: $(PROJECT).hex
    avrdude -p t44 -c bsd -U flash:w:$(PROJECT).c.hex

program-dasa: $(PROJECT).hex
    avrdude -p t44 -P /dev/ttyUSB0 -c dasa -U flash:w:$(PROJECT).c.hex

program-avrisp2: $(PROJECT).hex
    avrdude -p t44 -P usb -c avrisp2 -U flash:w:$(PROJECT).c.hex

program-avrisp2-fuses: $(PROJECT).hex
    avrdude -p t44 -P usb -c avrisp2 -U lfuse:w:0x5E:m

program-usbtiny: $(PROJECT).hex
    avrdude -p t44 -P usb -c usbtiny -U flash:w:$(PROJECT).c.hex

program-usbtiny-fuses: $(PROJECT).hex
    avrdude -p t44 -P usb -c usbtiny -U lfuse:w:0x5E:m

program-dragon: $(PROJECT).hex
    avrdude -p t44 -P usb -c dragon_isp -U flash:w:$(PROJECT).c.hex

program-dragon-fuses: $(PROJECT).hex
    avrdude -p t44 -P usb -c dragon_isp -U lfuse:w:0x5E:m

program-ice: $(PROJECT).hex
    avrdude -p t44 -P usb -c atmelice_isp -U flash:w:$(PROJECT).c.hex

program-ice-fuses: $(PROJECT).hex
    avrdude -p t44 -P usb -c atmelice_isp -U lfuse:w:0x5E:m

code ” 8mh_hello.servo.44.c ”

changed portions ; ( basically, 8MHz/20MHz = 2/5 )

  • line number 46 ; ICR1 = 10000; ( original, ICR1 = 25000; )

  • line number 59 ; OCR1A = 700; ( original, 1250, tuned from 500 (=1250X2/5) )

  • line number 64 ; OCR1A = 777; ( original, 1875, tuned from 750 (=1875X2/5) )

  • line number 69 ; OCR1A = 900; ( original, 2500, tuned from 1000 (=2500X2/5) )

according to the test results, in the range of 500 to 720

OCR1A ; 500 -> 720 CW ( clockwise ) fast -> slow, respectively

OCR1A ; 730 -> 770 stop

OCR1A ; 775 -> 1000 CCW ( counter clockwise ) slow -> fast, respectively

//
// hello.servo.44.c
//
// servo motor hello-world
//
// set lfuse to 0x5E for 20 MHz xtal
//
// Neil Gershenfeld
// 4/8/12
//
// (c) Massachusetts Institute of Technology 2012
// This work may be reproduced, modified, distributed,
// performed, and displayed for any purpose. Copyright is
// retained and must be preserved. The work is provided
// as is; no warranty is provided, and users accept all 
// liability.
//

#include <avr/io.h>
#include <util/delay.h>

#define output(directions,pin) (directions |= pin) // set port direction for output
#define set(port,pin) (port |= pin) // set port pin
#define clear(port,pin) (port &= (~pin)) // clear port pin
#define pin_test(pins,pin) (pins & pin) // test for port pin
#define bit_test(byte,bit) (byte & (1 << bit)) // test for bit set
#define position_delay() _delay_ms(1000)

#define PWM_port PORTA
#define PWM_pin (1 << PA6)
#define PWM_direction DDRA

int main(void) {
   //
   // main
   //
   // set clock divider to /1
   //
   CLKPR = (1 << CLKPCE);
   CLKPR = (0 << CLKPS3) | (0 << CLKPS2) | (0 << CLKPS1) | (0 << CLKPS0);
   //
   // set up timer 1
   //
   TCCR1A = (1 << COM1A1) | (0 << COM1A0); // clear OC1A on compare match
   TCCR1B = (0 << CS12) | (1 << CS11) | (0 << CS10) | (1 << WGM13); // prescaler /8, phase and frequency correct PWM, ICR1 TOP
   ICR1 = 10000; // 20 ms frequency
   //
   // set PWM pin to output
   //
   clear(PWM_port, PWM_pin);
   output(PWM_direction, PWM_pin);
   //
   // main loop
   //
   while (1) {
      //
      // 1 ms PWM on time
      //
      OCR1A = 700;
      position_delay();
      //
      // 1.5 ms PWM on time
      //
      OCR1A = 777;
      position_delay();
      //
      // 2 ms PWM on time
      //
      OCR1A = 900;
      position_delay();
      }
   }

make -f 8mh_hello.servo.44.c.make

make -f 8mh_hello.servo.44.c.make program-usbtiny

6) test 6

board software input output
6 ATtiny44 (breadboard) C none SG90

result ; moves, but not smooth

no video

3 - B . Making PCB ( ESP32 + servo motor ) for Final Project ( Drive simulator ) , ( on 2020/07/05 )

For the Drive Simulator of my Final Project, which would utilize 3 servo motors (SG90), I decided to make ESP32-based MCU, so that it can communicate with other devices like iPhone via wifi or BLE.

output 1 ; servo motor for rolled paper control ( SG90-HV (continuous rotation))

output 2 ; servo motor for magnet control ( SG90-HV (continuous rotation))

output 3 ; servo motor for slope control ( SG90 (lever-motion))

output 4 ; SSR (Solid State Relay) control to ON/OFF the generator coil

input 1 ; generator speed in terms of voltage from 1 coil (out of 8 coils)

input 2 ; slope signal from photo reflector on the drive simulator

input 3 (BLYNK BLE) ; X-Y of JOYSTICK module to control the above output 1 and 2

input 4, 5, 6 ; potentiometers for trouble shooting ( substitution of the above input 1, 2, 3, if needed)

Component layout

Considering the switch accessibility on the Drive Simulator, I planned to move the slider switch to the side of FTDI connector, which is the modification point from “Barduino 2.0”

“Barduino, fablab Kamakura” link

“Barduino, GitLab” link

Slider switch was relocated.
barduino2.0_switchrelocate_BETA_sch barduino2.0_switchrelocate_eagle_brd

This time, I tried “ground plane” referring the fablab Kamakura site shown below.

“How to make ground plane in Eagle”

summary of the procedures are ,,,,

​ surround the area to be ground plane, using “polygon” ( broken line appears )

​ name it to “GND”

​ “ratnest” it, then ground plane appears (red-colored area)

ratnest ground plane
img_9062 barduino2.0_switchrelocate_BETA_brd
trace (.png file can be downloaded from the bottom of this page)
barduino2.0_switchrelocate_beta_trace
outcut (.png file can be downloaded from the bottom of this page) holes (.png file can be downloaded from the bottom of this page)
barduino2.0_switchrelocate_beta_cutout barduino2.0_switchrelocate_beta_holes

MODs to create “.rml” files.

CNC parmeters for circuit pattern

tool diameter (in) ; 0.0156 (1/64)

cut depth (in) ; 0.004

max depth (in) ; 0.004

offset number ; 4

milling speed ; 4 mm/s

img_9068

CNC parmeters for holes and outline

tool diameter (in) ; 0.0312 (1/32)

cut depth (in) ; 0.024

max depth (in) ; 0.072

offset number ; 1

milling speed ; 4 mm/s

img_9066

img_9070

milling on SRM20

Some portions were not milled properly, I cut them using ultra-sonic cutter ( and hand files).

img_9071 img_9075
stuffing
img_9080 img_9077
put some pin number labels
img_9082 img_9085

Functionality check in accordance with the site below.

And, the results were no problem.

“Barduino, fablab Kamakura” link

LED blink hello echo
img_9084 img_9083

Assembling the drive simulator

laser cutting parts put rubber sheet on servo motor, for noise reduction
img_8920 2 img_8927 2
output 2 ; servo motor for magnet control ( SG90-HG (continuous rotation))
img_8935 2 img_8933 2
output 3 ; servo motor for slope control ( SG90 (lever-motion))
( in the back of this photo )
output 1 ; servo motor for rolled paper control ( SG90-HG (continuous rotation))
img_8937 2 img_8988
img_8945 2 img_8938

programing

( I referred some BLYNK example files in Arduino IDE. )

Regarding the setting of “Blynk BLE” on Arduino IDE and Blynk APP ( iPhone ), please refer ” 12. Interface and Application Programming , Group assignment Page “

“ESP32_Blynk_BLE_DriveSim_servo.ino”

#define BLYNK_PRINT Serial

#define BLYNK_USE_DIRECT_CONNECT

#include <BlynkSimpleEsp32_BLE.h>
#include <BLEDevice.h>
#include <BLEServer.h>


#include <ESP32Servo.h>

// You should get Auth Token in the Blynk App.
// Go to the Project Settings (nut icon).
char auth[] = "Your Auth Token";

// create three servo objects
Servo servo1;
Servo servo2;
Servo servo3;

BLYNK_WRITE(V1)
{
  servo1.write(param.asInt());
}

BLYNK_WRITE(V2)
{
  servo2.write(param.asInt());
}

BLYNK_WRITE(V3)
{
  servo3.write(param.asInt());
}



void setup() {

  {
    // Debug console
    Serial.begin(9600);
    Serial.println("Waiting for connections...");

    Blynk.setDeviceName("Blynk");

    Blynk.begin(auth);

    servo1.attach(4);
    servo2.attach(12);
    servo3.attach(14);

  }


}

void loop()

{
  Blynk.run();
}

Then, I did set the MCU and battery ( “eneloop” Ni-MH, rechargeable ), tested the “drivability ” from my iPhone. It worked fine.

img_9317 img_9141 2

( During this test, I controlled “output3, slope ” from BLYNK using the “v3” parameter in the program. )

4. Important Learning Outcome

1) basic speed control of servo motor

2) PWM setting and MC clock selection ( but need to explore PWM control more deeply )

3) making the ground plane in EAGLE CAD, and PCB milling technic

4) using BLYNK BLE to control the servo motors

servo_sg90hv_test_arduino.ino download

servo_sg90hv_attiny44.ino download

8mh_hello.servo.44.c download

8mh_hello.servo.44.c.make download

“BarDuino2.0_SwitchRelocate_BETA.sch”

download

“BarDuino2.0_SwitchRelocate_BETA.brd”

download

“BarDuino2.0_SwitchRelocate_BETA_trace.png”

download

“BarDuino2.0_SwitchRelocate_BETA_holes.png”

download

“BarDuino2.0_SwitchRelocate_BETA_cutout.png”

download

“BarDuino2.0_SwitchRelocate_BETA_trace.png.rml”

download

“BarDuino2.0_SwitchRelocate_BETA_holes.png-4.rml”

download

“BarDuino2.0_SwitchRelocate_BETA_cutout.png-2.rml”

download

“ESP32_Blynk_BLE_DriveSim_servo.ino”

download

6. Appendix

ATtiny44A data sheet

Secrets of Arduino PWM