-
Notifications
You must be signed in to change notification settings - Fork 0
/
Follow_Focus.ino
149 lines (119 loc) · 4.97 KB
/
Follow_Focus.ino
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
/*-------------------------------------------------------------
Servo Follow Focus v1
Dual-Mode Servo Follow Focus with 2-Stage smoothing, Potentiometer,
tiny Screen, auto Idle and Sleep Mode
by eBender
Parts
ESP32 (minimum: Microcontroller /w I2C, 1 ADC Input, 1 Digital Input, 1 PWM Output)
0.42" 32x64 OLED I2C Screen
25g S0025M Servo (0.06-0.08ms, 2.6-3KG, 333Hz, 2BB, MG)
10k Potentiometer
1x Momentary Button
INA219 Voltage Current Meter
2S BMS Balance Module
2S Battery Charger TP5100
6v 3A Buck Voltage Converter
2x 18650 Battery
3D Printed enclosure (files coming to thingyverse)
22/24AWG Wires
M3 Screws, M3 Inserts
ChangeLog
- fixed sleep Mode bug
- added idle indicator UI message
- added Sleep Mode selection UI message
Issues
- button might need to be de-bounced
Credits
- TaskManagerIO - Dave Cherry, Jorropo
- Moving Average - Jack Christensen
- ResponisveAnalogRead - Damien Clarke
-------------------------------------------------------------*/
#include <Arduino.h>
#include "TaskManagerIO.h"
#include <BasicInterruptAbstraction.h>
#include <Wire.h>
#include <ResponsiveAnalogRead.h>
#include "MovingAverage.h"
#include <ESP32Servo.h>
#include <U8g2lib.h>
//=============== ADJUSTABLE ===================================
#define DEBUG // note that response time is being slowed by debug mode
#define SDA 21
#define SCL 22
#define buttonPin 2
#define potiPin 4
#define servoPin 25
byte tmMultiplier = 1; // variable task update frequency - 1 normal, 2 half speed.. etc
#define smoothValue 90 / tmMultiplier // Smooth Mode Smoothing 0-255
#define expo 3.0 // Input Exponential Curve 0.0 - 10.0, fine control at startpoint
#define Hertz 333 // 50-333Hz Servo
unsigned int potiEnd = 4500.0; // Poti end stop (reduce for less poti range - scaling correctly)
#define servoStart 500 // Servo 500um-2500um pulse width
#define servoEnd 2500
bool sleepMode = true; // button double click switches sleepMode
unsigned int sleepOff = 25000; // deep Sleep in ms (don't put below 15000)
#define idleTimer 5000 // idle in ms
#define font u8g2_font_logisoso28_tn // u8g2_font_logisoso28_tn @ Y30 - u8g2_font_helvB24_tn @ Y28, (u8g2_font_battery19_tn - Battery 19px)
byte fontY = 30; // font y position in px
//=============== ADJUSTABLE END ================================
float potiIn, potiOut, potiValue, potiTemp, servoTemp, idleTemp;
unsigned long int buttonTime, codeTime, sleepTimer, timeOff, i, ms, us, taskID, sleepID;
bool buttonBool, smoothMode, idleOn;
U8G2_SSD1306_64X32_1F_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE);
ResponsiveAnalogRead analog1(potiPin, false); // Stage 1 Smoothing
MovingAverage smooth1(smoothValue); // Stage 2 Smoothing
Servo servo;
void setup() {
#ifdef DEBUG
Serial.begin(115200);
delay(300);
Serial.print("CPU: ");
Serial.println(getCpuFrequencyMhz());
#endif
u8g2.begin();
u8g2.clearBuffer();
u8g2.setFontDirection(0);
u8g2.setFontMode(1);
u8g2.setDrawColor(1);
u8g2.setFont(font);
Wire.begin(SDA, SCL, 400000);
pinMode(buttonPin, INPUT_PULLDOWN);
pinMode(potiPin, INPUT_PULLDOWN);
if (getCpuFrequencyMhz() != 240) setCpuFrequencyMhz(240); // for coming out of sleep mode
servo.setPeriodHertz(Hertz);
servo.attach(servoPin, servoStart, servoEnd); // attach Servo
BasicArduinoInterruptAbstraction interruptAbstraction; // INT for button
ms = millis();
buttonTime = ms;
sleepTimer = ms;
idleTemp = potiOut;
for (i = 64; i >= 32; i--) { // screen roll-in on startup
getPoti();
writeServo();
u8g2.clearBuffer();
u8g2.setCursor(0, i);
u8g2.print((potiOut - 500.0) / 20.0, 2); // map to 0 - 100
u8g2.sendBuffer();
}
taskManager.setInterruptCallback(interruptTask); // add interrupt routine for the button input
taskManager.addInterrupt(&interruptAbstraction, buttonPin, RISING);
taskManager.scheduleFixedRate(3 * tmMultiplier, getPoti, TIME_MILLIS); // 333hz
taskManager.scheduleFixedRate(3 * tmMultiplier, writeServo, TIME_MILLIS); // 333hz bc servo updates @ 333hz
taskManager.scheduleFixedRate(20 * tmMultiplier, writeScreen, TIME_MILLIS); // 50fps
if (sleepMode) {
sleepID = taskManager.scheduleFixedRate(1, getSleepMode, TIME_SECONDS); // 1hz
}
taskManager.scheduleFixedRate(1, idle, TIME_SECONDS); // 1hz
}
#ifdef DEBUG
void logIt(const char* toLog, unsigned long int cTime) {
Serial.print(millis());
Serial.print("ms: ");
Serial.print(cTime);
Serial.print("us - ");
Serial.println(toLog);
}
#endif
void loop() {
taskManager.runLoop();
}