├── ef-lens-controller.png ├── EF-Lens-control.ino └── EF-Lense-Control2 /ef-lens-controller.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/crescentvenus/EF-Lens-CONTROL/HEAD/ef-lens-controller.png -------------------------------------------------------------------------------- /EF-Lens-control.ino: -------------------------------------------------------------------------------- 1 | /* 2 | ロータリーエンコーダの参照コード 3 | https://jumbleat.com/2016/12/17/encoder_1/ 4 | */ 5 | /* 6 | EFレンズの制御関連参考リンク 7 | ASCOM EF Lens Controller 8 | http://www.indilib.org/media/kunena/attachments/3728/ascom_efEN.pdf 9 | EFレンズから信号線の引き出の参照資料 10 | How to Move Canon EF Lenses Yosuke Bando 11 | http://web.media.mit.edu/~bandy/invariant/move_lens.pdf 12 | Canon EFレンズのArduino制御 13 | http://otobs.org/hiki/?EOS_model 14 | Technical aspects of the Canon EF lens mount 15 | http://www.eflens.com/lens_articles/ef_lens_mount.html 16 | */ 17 | #include 18 | #include 19 | 20 | #include 21 | #include 22 | #include 23 | #define SCREEN_WIDTH 128 24 | #define SCREEN_HEIGHT 64 25 | #define OLED_RESET -1 26 | Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET); 27 | 28 | #define LED_SW 7 29 | #define CS 10 // Emurate CS of SPI for DEBUG 30 | #define F1 9 // Function SW 31 | #define ENC_A 2 32 | #define ENC_B 3 33 | #define LED_Red 14 34 | #define LED_Green 15 35 | 36 | volatile byte pos; 37 | volatile int enc_count; 38 | boolean sw = false; 39 | boolean real_mode = false; 40 | 41 | int mode = 0; 42 | int mode_counter[2]; 43 | int focuserPosition, apValue, offset, apAddr, fpAddr, fpValue, x, y; 44 | boolean IsFirstConnect; 45 | 46 | void InitLens() 47 | { 48 | SPI.transfer(0x0A); 49 | delay(30); 50 | SPI.transfer(0x00); 51 | delay(30); 52 | SPI.transfer(0x0A); 53 | delay(30); 54 | SPI.transfer(0x00); 55 | delay(30); 56 | } 57 | 58 | int ENC_COUNT(int incoming) { 59 | static int enc_old = enc_count; 60 | int val_change = enc_count - enc_old; 61 | 62 | if (val_change != 0) 63 | { 64 | incoming += val_change; 65 | enc_old = enc_count; 66 | } 67 | return incoming; 68 | } 69 | 70 | void ENC_READ() { 71 | byte cur = (!digitalRead(ENC_B) << 1) + !digitalRead(ENC_A); 72 | byte old = pos & B00000011; 73 | byte dir = (pos & B00110000) >> 4; 74 | 75 | if (cur == 3) cur = 2; 76 | else if (cur == 2) cur = 3; 77 | 78 | if (cur != old) 79 | { 80 | if (dir == 0) 81 | { 82 | if (cur == 1 || cur == 3) dir = cur; 83 | } else { 84 | if (cur == 0) 85 | { 86 | if (dir == 1 && old == 3) enc_count++; 87 | else if (dir == 3 && old == 1) enc_count--; 88 | dir = 0; 89 | } 90 | } 91 | pos = (dir << 4) + (old << 2) + cur; 92 | } 93 | } 94 | 95 | void setup() { 96 | digitalWrite(13, LOW); // SPI Clock PIN 97 | pinMode(ENC_A, INPUT_PULLUP); 98 | pinMode(ENC_B, INPUT_PULLUP); 99 | pinMode(LED_Red, OUTPUT); 100 | pinMode(LED_Green, OUTPUT); 101 | pinMode(LED_SW, INPUT_PULLUP); 102 | pinMode(CS, OUTPUT); 103 | pinMode(F1, INPUT_PULLUP); 104 | 105 | attachInterrupt(0, ENC_READ, CHANGE); 106 | attachInterrupt(1, ENC_READ, CHANGE); 107 | 108 | display.begin(SSD1306_SWITCHCAPVCC, 0x3C); 109 | display.clearDisplay(); 110 | 111 | // Font size 112 | display.setTextSize(3); 113 | // Font color 114 | display.setTextColor(WHITE); 115 | display.setCursor(0, 10); 116 | display.println("EF-LensFocuser"); 117 | display.display(); 118 | delay(1000); 119 | mode = 0; // focus control mode 120 | apAddr = 0; // 1 byte memory for aperture value 121 | fpAddr = 1; // 2 byte memory for focus position 122 | focuserPosition = 5000; 123 | SPI.begin(); 124 | SPI.setBitOrder(MSBFIRST); 125 | SPI.setClockDivider(SPI_CLOCK_DIV128); 126 | SPI.setDataMode(SPI_MODE3); 127 | digitalWrite(12, HIGH); 128 | digitalWrite(LED_Red, HIGH); 129 | digitalWrite(LED_Green, LOW); 130 | InitLens(); 131 | SPI.transfer(0x05); // Focus Max 132 | delay(1000); 133 | apValue = EEPROM.read(apAddr); 134 | fpValue = EEPROM.read(fpAddr) * 256 + EEPROM.read(fpAddr + 1); // focus position 135 | offset = fpValue - focuserPosition; 136 | proc_lens(offset); // Move focus tot last position 137 | 138 | Serial.begin(9600); 139 | Serial.print("FP:"); 140 | Serial.println(fpValue); 141 | Serial.print("AP:"); 142 | Serial.println(apValue); 143 | display.clearDisplay(); 144 | display.setCursor(0, 10); 145 | display.print("F:"); 146 | display.println(fpValue); 147 | display.print("A:"); 148 | display.println(apValue); 149 | display.display(); 150 | delay(1000); 151 | } 152 | 153 | void loop() { 154 | int sw_count; 155 | int tmp, last_offset; 156 | short counter_now; 157 | digitalWrite(CS, HIGH); 158 | sw_count = 0; 159 | while (digitalRead(LED_SW) == LOW) { 160 | sw_count++; 161 | if (sw_count > 50) { 162 | if (mode == 1) { // forcus control mode 163 | digitalWrite(LED_Red, HIGH); 164 | digitalWrite(LED_Green, LOW); 165 | } else { // aperture control mode 166 | digitalWrite(LED_Green, HIGH); 167 | digitalWrite(LED_Red, LOW); 168 | } 169 | } 170 | if (sw_count > 200) { 171 | digitalWrite(LED_Green, HIGH); 172 | digitalWrite(LED_Red, HIGH); 173 | } 174 | delay(10); 175 | } 176 | delay(100); 177 | if (sw_count > 50 && sw_count < 200) { 178 | mode == 0 ? mode = 1 : mode = 0; 179 | } 180 | if (mode == 1) { 181 | digitalWrite(LED_Green, HIGH); 182 | digitalWrite(LED_Red, LOW); 183 | } else { 184 | digitalWrite(LED_Red, HIGH); 185 | digitalWrite(LED_Green, LOW); 186 | } 187 | /* 188 | if (sw_count != 0) { 189 | Serial.print("mode: "); 190 | Serial.print(mode); 191 | Serial.print(", real: "); 192 | Serial.println(real_mode); 193 | } 194 | */ 195 | if (sw_count > 200) { 196 | real_mode = !real_mode; 197 | if (real_mode) { 198 | Serial.print("mode: "); 199 | Serial.println(mode); 200 | last_offset = mode_counter[mode]; 201 | } else { 202 | mode_counter[mode] = last_offset; 203 | } 204 | } 205 | if (sw_count != 0 && (sw_count < 50) ) { 206 | proc_lens(tmp); 207 | } 208 | 209 | counter_now = ENC_COUNT(mode_counter[mode]); 210 | tmp = counter_now - mode_counter[mode]; // encoder counter state 211 | if (mode_counter[mode] != counter_now) 212 | { 213 | tmp > 0 ? 1 : -1; 214 | if (real_mode) { 215 | mode_counter[mode] += tmp; 216 | proc_lens(tmp); 217 | } else { 218 | mode_counter[mode] = counter_now; 219 | } 220 | } 221 | if (sw_count != 0 || tmp != 0) disp_update(tmp, last_offset); 222 | 223 | } 224 | 225 | void proc_lens(int tmp) { 226 | int ap; 227 | digitalWrite(CS, LOW); 228 | if (mode == 0 ) { // Send command to LENS フォーカス 229 | if (real_mode) { 230 | offset = tmp; 231 | } else { 232 | offset = mode_counter[mode] ; 233 | } 234 | x = highByte(focuserPosition); 235 | y = lowByte(focuserPosition); 236 | EEPROM.write(fpAddr, x); // write to EEPROM last focus position 237 | EEPROM.write(fpAddr + 1, y); 238 | x = highByte(offset); 239 | y = lowByte(offset); 240 | Serial.print("FP:"); 241 | Serial.print(offset); 242 | Serial.print(", "); 243 | Serial.println(focuserPosition); 244 | InitLens(); 245 | SPI.transfer(0x44); delay(30); 246 | SPI.transfer(x); delay(30); 247 | SPI.transfer(y); delay(30); 248 | SPI.transfer(0); delay(100); 249 | focuserPosition += offset; 250 | } else { // 絞り 251 | apValue = mode_counter[mode] ; 252 | ap = (apValue - EEPROM.read(apAddr)) * 3; 253 | Serial.print("APvalue:"); 254 | Serial.print(apValue); 255 | Serial.print(",SET ap:"); 256 | Serial.println(ap); 257 | if (apValue != EEPROM.read(apAddr)) 258 | { 259 | InitLens(); 260 | SPI.transfer(0x07); delay(10); 261 | SPI.transfer(0x13); delay(10); 262 | SPI.transfer((apValue - EEPROM.read(apAddr)) * 3); 263 | delay(100); 264 | SPI.transfer(0x08); delay(10); 265 | SPI.transfer(0x00); delay(10); 266 | EEPROM.write(apAddr, apValue); 267 | } 268 | } 269 | } 270 | 271 | void disp_update(int tmp, int last_offset) { 272 | char sep; 273 | display.clearDisplay(); 274 | display.setCursor(0, 10); 275 | if (real_mode) { // Update when encoder rotated 276 | sep = '>'; 277 | switch (mode) { 278 | case 0: 279 | (tmp > 0) ? sep = '>' : sep = '<'; 280 | display.print("F"); 281 | display.print(sep); 282 | display.println( last_offset ); 283 | display.print("P"); 284 | display.print(sep); 285 | display.println( focuserPosition); 286 | break; 287 | case 1: 288 | display.print("F"); 289 | display.print(sep); 290 | display.println( focuserPosition ); 291 | display.print("A"); 292 | display.print(sep); 293 | display.println(mode_counter[mode]); 294 | break; 295 | } 296 | } else { // Update when switch pushed 297 | sep = ':'; 298 | switch (mode) { 299 | case 0: 300 | display.print("F"); 301 | display.print(sep); 302 | display.println( mode_counter[mode] ); 303 | display.print("P"); 304 | display.print(sep); 305 | display.println( focuserPosition); 306 | break; 307 | case 1: 308 | display.print("F"); 309 | display.print(sep); 310 | display.println( focuserPosition ); 311 | display.print("A"); 312 | display.print(sep); 313 | display.println(mode_counter[mode]); 314 | break; 315 | } 316 | } 317 | display.display(); 318 | } 319 | -------------------------------------------------------------------------------- /EF-Lense-Control2: -------------------------------------------------------------------------------- 1 | /* 2 | ロータリーエンコーダの参照コード 3 | https://jumbleat.com/2016/12/17/encoder_1/ 4 | */ 5 | /* 6 | EFレンズの制御関連参考リンク 7 | ASCOM EF Lens Controller 8 | http://www.indilib.org/media/kunena/attachments/3728/ascom_efEN.pdf 9 | EFレンズから信号線の引き出の参照資料 10 | How to Move Canon EF Lenses Yosuke Bando 11 | http://web.media.mit.edu/~bandy/invariant/move_lens.pdf 12 | Canon EFレンズのArduino制御 13 | http://otobs.org/hiki/?EOS_model 14 | Technical aspects of the Canon EF lens mount 15 | http://www.eflens.com/lens_articles/ef_lens_mount.html 16 | */ 17 | #define DEBUG 18 | #include 19 | #include 20 | 21 | #include 22 | #include 23 | #include 24 | #define SCREEN_WIDTH 128 25 | #define SCREEN_HEIGHT 64 26 | #define OLED_RESET -1 27 | Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET); 28 | 29 | #define LED_SW 7 30 | #define SS 10 // SPI SS for ATmega168/328 31 | #define F1 9 // Function SW 32 | #define ENC_A 2 33 | #define ENC_B 3 34 | #define LED_Red 14 35 | #define LED_Green 15 36 | 37 | volatile byte pos; 38 | volatile int enc_count; 39 | boolean sw = false; 40 | boolean rec_mode = false; // move LENS without pushing SW 41 | 42 | int mode = 0; // 0:Focus control, 1:Aperture control 43 | int mode_counter[2] , focuserPosition, offset; 44 | int apAddr, apValue, fpAddr, fpValue, stepAddr, stepValue; 45 | 46 | void InitLens() 47 | { 48 | SPI.transfer(0x0A); 49 | delay(30); 50 | SPI.transfer(0x00); 51 | delay(30); 52 | SPI.transfer(0x0A); 53 | delay(30); 54 | SPI.transfer(0x00); 55 | delay(30); 56 | } 57 | 58 | int ENC_COUNT(int incoming) { 59 | static int enc_old = enc_count; 60 | int val_change = enc_count - enc_old; 61 | 62 | if (val_change != 0) 63 | { 64 | incoming += val_change; 65 | enc_old = enc_count; 66 | } 67 | return incoming; 68 | } 69 | 70 | void ENC_READ() { 71 | byte cur = (!digitalRead(ENC_B) << 1) + !digitalRead(ENC_A); 72 | byte old = pos & B00000011; 73 | byte dir = (pos & B00110000) >> 4; 74 | 75 | if (cur == 3) cur = 2; 76 | else if (cur == 2) cur = 3; 77 | 78 | if (cur != old) 79 | { 80 | if (dir == 0) 81 | { 82 | if (cur == 1 || cur == 3) dir = cur; 83 | } else { 84 | if (cur == 0) 85 | { 86 | if (dir == 1 && old == 3) enc_count++; 87 | else if (dir == 3 && old == 1) enc_count--; 88 | dir = 0; 89 | } 90 | } 91 | pos = (dir << 4) + (old << 2) + cur; 92 | } 93 | } 94 | 95 | void setup() { 96 | digitalWrite(13, LOW); // SPI Clock PIN 97 | pinMode(ENC_A, INPUT_PULLUP); 98 | pinMode(ENC_B, INPUT_PULLUP); 99 | pinMode(LED_Red, OUTPUT); 100 | pinMode(LED_Green, OUTPUT); 101 | pinMode(LED_SW, INPUT_PULLUP); 102 | pinMode(SS, OUTPUT); 103 | pinMode(F1, INPUT_PULLUP); 104 | 105 | attachInterrupt(0, ENC_READ, CHANGE); 106 | attachInterrupt(1, ENC_READ, CHANGE); 107 | 108 | display.begin(SSD1306_SWITCHCAPVCC, 0x3C); 109 | display.clearDisplay(); 110 | 111 | // Font size 112 | display.setTextSize(3); 113 | // Font color 114 | display.setTextColor(WHITE); 115 | display.setCursor(0, 10); 116 | display.println("EF-LensFocuser"); 117 | display.display(); 118 | delay(1000); 119 | mode = 0; // focus control mode 120 | apAddr = 0; // 1 byte memory for apurture value 121 | fpAddr = 1; // 2 byte memory for focus position 122 | stepAddr = 3; // 1 bye memory for focusing steps 123 | focuserPosition = 5000; 124 | SPI.begin(); 125 | SPI.setBitOrder(MSBFIRST); 126 | SPI.setClockDivider(SPI_CLOCK_DIV128); 127 | SPI.setDataMode(SPI_MODE3); 128 | digitalWrite(12, HIGH); 129 | digitalWrite(LED_Red, HIGH); 130 | digitalWrite(LED_Green, LOW); 131 | InitLens(); 132 | SPI.transfer(0x05); // Focus Max 133 | delay(1000); 134 | apValue = EEPROM.read(apAddr); 135 | fpValue = EEPROM.read(fpAddr) * 256 + EEPROM.read(fpAddr + 1); // focus position 136 | stepValue = EEPROM.read(stepAddr); 137 | 138 | offset = fpValue - focuserPosition; 139 | proc_lens(); // Move focus tot last position 140 | focuserPosition = fpValue; 141 | #ifdef DEBUG 142 | Serial.begin(9600); 143 | Serial.print("FP:"); 144 | Serial.println(fpValue); 145 | Serial.print("OffSet:"); 146 | Serial.println(offset); 147 | Serial.print("Step:"); 148 | Serial.println(stepValue); 149 | Serial.print("AP:"); 150 | Serial.println(apValue); 151 | #endif 152 | /* 153 | * Initialize starting values when needed. 154 | * Press SW at startup. 155 | */ 156 | if (digitalRead(LED_SW) == LOW){ 157 | fpValue=5000; 158 | focuserPosition=5000; 159 | offset=0; 160 | stepValue=10; 161 | apValue=0; 162 | } 163 | display.clearDisplay(); 164 | display.setCursor(0, 10); 165 | display.print("F:"); 166 | display.println(fpValue); 167 | display.print("A:"); 168 | display.println(apValue); 169 | display.display(); 170 | delay(1000); 171 | } 172 | 173 | void loop() { 174 | int sw_count; 175 | int enc_diff; 176 | short counter_now; 177 | digitalWrite(SS, HIGH); 178 | sw_count = 0; 179 | /* encorder counts */ 180 | counter_now = ENC_COUNT(mode_counter[mode]); 181 | enc_diff = counter_now - mode_counter[mode]; // encoder counter state 182 | /* SW pressed ? */ 183 | while (digitalRead(LED_SW) == LOW) { 184 | sw_count++; 185 | if (!rec_mode) { 186 | if (mode == 1) { // forcus control mode RED 187 | SetLED(HIGH, LOW); 188 | } else { // aperture control mode GREEN 189 | SetLED(LOW, HIGH); 190 | } 191 | } 192 | if (sw_count > 50) { // Change Step Size mode 193 | SetLED(HIGH, HIGH); 194 | } 195 | delay(10); 196 | } 197 | delay(100); 198 | if (sw_count > 0 && sw_count < 50) { // Toggle Focus/Aperture 199 | mode == 0 ? mode = 1 : mode = 0; 200 | disp_update(stepValue, focuserPosition); 201 | } 202 | if (mode == 1) { 203 | SetLED(LOW, HIGH); 204 | } else { 205 | SetLED(HIGH, LOW); 206 | } 207 | 208 | if (sw_count > 50 || (rec_mode && (sw_count != 0)) ) { // Toggle step counts setting mode 209 | rec_mode = ! rec_mode; 210 | if (!rec_mode) mode = 0; 211 | } 212 | if (rec_mode) { 213 | SetLED(HIGH, HIGH); 214 | mode = 0; 215 | if (sw_count != 0 || enc_diff != 0) { 216 | stepValue += enc_diff; 217 | if (stepValue < 1) stepValue = 1; // minimum step size should be 1 218 | EEPROM.write(stepAddr, stepValue); 219 | } 220 | disp_update(stepValue, focuserPosition); 221 | } else { 222 | if (mode_counter[mode] != counter_now) { 223 | enc_diff > 0 ? 1 : -1; 224 | switch (mode) { 225 | case 0: 226 | offset = enc_diff * stepValue; // Focus current position 227 | disp_update( offset , focuserPosition); 228 | break; 229 | case 1: 230 | apValue += enc_diff; 231 | disp_update( apValue , focuserPosition); 232 | break; 233 | } 234 | proc_lens(); 235 | } 236 | } 237 | } 238 | 239 | void SetLED(int red, int green) { 240 | digitalWrite(LED_Red, red); 241 | digitalWrite(LED_Green, green); 242 | } 243 | 244 | /* 245 | * Status display on OLED 246 | */ 247 | void disp_update(int tmp, int focuserPosition) { 248 | char sep; 249 | display.clearDisplay(); 250 | display.setCursor(0, 10); 251 | sep = ':'; 252 | if (rec_mode) { // Update when encoder rotated 253 | display.print("S"); 254 | display.print(sep); 255 | display.println(tmp ); 256 | display.print("F"); 257 | display.print(sep); 258 | display.println( focuserPosition); 259 | } else { // Update when switch pushed 260 | sep = ':'; 261 | switch (mode) { 262 | case 0: 263 | display.print("S"); 264 | display.print(sep); 265 | display.println( offset ); 266 | display.print("F"); 267 | display.print(sep); 268 | display.println( focuserPosition); 269 | break; 270 | case 1: 271 | display.print("A"); 272 | display.print(sep); 273 | display.println(apValue); 274 | display.print("F"); 275 | display.print(sep); 276 | display.println( focuserPosition ); 277 | break; 278 | } 279 | } 280 | display.display(); 281 | } 282 | /* 283 | * 1:Send control commands to LENS 284 | * 2:Update EEPROM data 285 | * 286 | * mode 0:focus control mode 287 | * param1 focuserPosition... focus value 288 | * param2 offset ... focus move value 289 | * mode 1:aperture control mode 290 | * param apValue ... aperture value 291 | */ 292 | void proc_lens() { 293 | int ap, x, y; 294 | digitalWrite(SS, LOW); 295 | if (mode == 0 ) { // Focus control 296 | //offset = stepValue ; 297 | x = highByte(focuserPosition); 298 | y = lowByte(focuserPosition); 299 | EEPROM.write(fpAddr, x); // write to EEPROM last focus position 300 | EEPROM.write(fpAddr + 1, y); 301 | x = highByte(offset); 302 | y = lowByte(offset); 303 | InitLens(); 304 | SPI.transfer(0x44); delay(30); 305 | SPI.transfer(x); delay(30); 306 | SPI.transfer(y); delay(30); 307 | SPI.transfer(0); delay(100); 308 | focuserPosition += offset; 309 | #ifdef DEBUG 310 | Serial.print("FP:"); 311 | Serial.print(offset); 312 | Serial.print(", "); 313 | Serial.println(focuserPosition); 314 | #endif 315 | } else { // aperture control 316 | ap = (apValue - EEPROM.read(apAddr)) * 3; 317 | if (apValue != EEPROM.read(apAddr)) 318 | { 319 | InitLens(); 320 | SPI.transfer(0x07); delay(10); 321 | SPI.transfer(0x13); delay(10); 322 | SPI.transfer((apValue - EEPROM.read(apAddr)) * 3); 323 | delay(100); 324 | SPI.transfer(0x08); delay(10); 325 | SPI.transfer(0x00); delay(10); 326 | EEPROM.write(apAddr, apValue); 327 | } 328 | } 329 | #ifdef DEBUG 330 | Serial.print("APvalue:"); 331 | Serial.print(apValue); 332 | Serial.print(",SET ap:"); 333 | Serial.println(ap); 334 | #endif 335 | } 336 | --------------------------------------------------------------------------------