From 9b7d1a3e5c0ea35868855aac04577885e72a2029 Mon Sep 17 00:00:00 2001 From: mattmcw Date: Sun, 19 May 2024 09:38:48 -0400 Subject: [PATCH] Add a second projector version of the JKM100 script. In the script, move the 16ms delay to BEFORE the confirmation character and increase it to 100ms to make sure all shake is out of the system before shooting a frame. --- app/data/cfg.json | 2 +- app/package-lock.json | 2 +- app/package.json | 2 +- data/cfg.json | 2 +- .../mcopy_ACME_Trebes_Nanolab.ino | 4 +- ino/mcopy_JKMM100/mcopy_JKMM100.ino | 3 +- .../McopySerial.cpp | 74 ++++++ .../McopySerial.h | 89 ++++++++ .../mcopy_JKMM100_second_projector.ino | 211 ++++++++++++++++++ package-lock.json | 4 +- package.json | 2 +- processing/mcopy/cfg.json | 2 +- scripts/ino.sh | 1 + 13 files changed, 387 insertions(+), 11 deletions(-) create mode 100644 ino/mcopy_JKMM100_second_projector/McopySerial.cpp create mode 100644 ino/mcopy_JKMM100_second_projector/McopySerial.h create mode 100644 ino/mcopy_JKMM100_second_projector/mcopy_JKMM100_second_projector.ino diff --git a/app/data/cfg.json b/app/data/cfg.json index e79ec8a..3ef7aea 100644 --- a/app/data/cfg.json +++ b/app/data/cfg.json @@ -1,5 +1,5 @@ { - "version": "1.8.104", + "version": "1.8.105", "ext_port": 1111, "profiles": { "mcopy": { diff --git a/app/package-lock.json b/app/package-lock.json index a463e0b..978ce04 100644 --- a/app/package-lock.json +++ b/app/package-lock.json @@ -1,6 +1,6 @@ { "name": "mcopy-app", - "version": "1.8.104", + "version": "1.8.105", "lockfileVersion": 2, "requires": true, "packages": { diff --git a/app/package.json b/app/package.json index de33281..227980f 100644 --- a/app/package.json +++ b/app/package.json @@ -1,6 +1,6 @@ { "name": "mcopy-app", - "version": "1.8.104", + "version": "1.8.105", "description": "GUI for the mcopy small gauge film optical printer platform", "main": "main.js", "scripts": { diff --git a/data/cfg.json b/data/cfg.json index e79ec8a..3ef7aea 100644 --- a/data/cfg.json +++ b/data/cfg.json @@ -1,5 +1,5 @@ { - "version": "1.8.104", + "version": "1.8.105", "ext_port": 1111, "profiles": { "mcopy": { diff --git a/ino/mcopy_ACME_Trebes_Nanolab/mcopy_ACME_Trebes_Nanolab.ino b/ino/mcopy_ACME_Trebes_Nanolab/mcopy_ACME_Trebes_Nanolab.ino index e0d8a3c..8ffebab 100644 --- a/ino/mcopy_ACME_Trebes_Nanolab/mcopy_ACME_Trebes_Nanolab.ino +++ b/ino/mcopy_ACME_Trebes_Nanolab/mcopy_ACME_Trebes_Nanolab.ino @@ -38,8 +38,8 @@ const int PROJECTOR_BACKWARD_PIN = 4; const int PROJECTOR_SECOND_FORWARD_PIN = 3; const int PROJECTOR_SECOND_BACKWARD_PIN = 2; -const int PROJECTOR_MOMENT = 500; -const int PROJECTOR_LENGTH = 600; +const int PROJECTOR_MOMENT = 800; +const int PROJECTOR_LENGTH = 900; //OTHER CONSTATNS const int MODE_SWITCH_PIN = 12; diff --git a/ino/mcopy_JKMM100/mcopy_JKMM100.ino b/ino/mcopy_JKMM100/mcopy_JKMM100.ino index 69b56dd..6ca8c31 100644 --- a/ino/mcopy_JKMM100/mcopy_JKMM100.ino +++ b/ino/mcopy_JKMM100/mcopy_JKMM100.ino @@ -149,11 +149,12 @@ void proj_stop () { } } + delay(100); + mc.confirm(mc.PROJECTOR); mc.log("projector()"); proj_running = false; - delay(16); update_timing(millis() - proj_time); } diff --git a/ino/mcopy_JKMM100_second_projector/McopySerial.cpp b/ino/mcopy_JKMM100_second_projector/McopySerial.cpp new file mode 100644 index 0000000..a9658fc --- /dev/null +++ b/ino/mcopy_JKMM100_second_projector/McopySerial.cpp @@ -0,0 +1,74 @@ +/// mcopy Serial Library + +#include "McopySerial.h" + +McopySerial::McopySerial () {} + +void McopySerial::begin (char identity) { + id = identity; + Serial.begin(baud); + Serial.flush(); + Serial.setTimeout(serialDelay); +} + +char McopySerial::loop () { + if (Serial.available()) { + cmdChar = (char) Serial.read(); + _internal(); + } else { + cmdChar = 'z'; + } + return cmdChar; +} + +void McopySerial::_internal () { + if (cmdChar == DEBUG) { + debug(!debugOn); + } else if (cmdChar == CONNECT) { + _connect(); + } else if (cmdChar == MCOPY_IDENTIFIER) { + _identify(); + } +} + +void McopySerial::_connect () { + connected = true; + Serial.println(CONNECT); + log("connect()"); +} + +void McopySerial::_identify () { + identified = true; + Serial.println(id); + log("identify()"); +} + +void McopySerial::debug (bool state) { + debugOn = state; + log("debug()"); +} + +void McopySerial::confirm (char cmd) { + Serial.println(cmd); +} + +void McopySerial::log (String message) { + if (debugOn) { + Serial.println(message); + } +} + +String McopySerial::getString () { + while (Serial.available() == 0) { + //Wait for value string + } + return Serial.readString(); +} + +void McopySerial::sendString (String str) { + Serial.println(str); +} + +void McopySerial::print (String message) { + Serial.println(message); +} \ No newline at end of file diff --git a/ino/mcopy_JKMM100_second_projector/McopySerial.h b/ino/mcopy_JKMM100_second_projector/McopySerial.h new file mode 100644 index 0000000..8b9a80c --- /dev/null +++ b/ino/mcopy_JKMM100_second_projector/McopySerial.h @@ -0,0 +1,89 @@ +#ifndef MCOPY_SERIAL +#define MCOPY_SERIAL + +#include + +class McopySerial { + + private: + + const uint16_t serialDelay = 5; + const uint16_t baud = 57600; + + volatile bool debugOn = false; + volatile char cmdChar = 'z'; + volatile char id; + + void _internal (); + void _connect (); + void _identify (); + + public: + + volatile bool connected = false; + volatile bool identified = false; + + /* CMD FLAGS */ + const char BLACK = 'b'; + const char CAMERA = 'c'; + const char CAMERA_BACKWARD = 'f'; + const char CAMERA_CAPPER_IDENTIFIER = '8'; + const char CAMERA_CAPPER_PROJECTOR_IDENTIFIER = '9'; + const char CAMERA_CAPPER_PROJECTORS_IDENTIFIER = '0'; + const char CAMERA_EXPOSURE = 'G'; + const char CAMERA_FORWARD = 'e'; + const char CAMERA_IDENTIFIER = 'k'; + const char CAMERA_PROJECTORS_IDENTIFIER = '5'; + const char CAMERA_SECOND = '3'; + const char CAMERA_SECOND_BACKWARD = '2'; + const char CAMERA_SECOND_FORWARD = '1'; + const char CAMERA_SECOND_IDENTIFIER = 'y'; + const char CAMERA_TIMED = 'n'; + const char CAMERAS = '4'; + const char CAMERAS_IDENTIFIER = 'a'; + const char CAMERAS_PROJECTOR_IDENTIFIER = '6'; + const char CAMERAS_PROJECTORS_IDENTIFIER = '7'; + const char CAPPER_IDENTIFIER = 'C'; + const char CAPPER_OFF = 'B'; + const char CAPPER_ON = 'A'; + const char CONNECT = 'i'; + const char DEBUG = 'd'; + const char ERROR = 'E'; + const char HOME = 'I'; + const char LIGHT = 'l'; + const char LIGHT_IDENTIFIER = 'o'; + const char MCOPY_IDENTIFIER = 'm'; + const char OFFSET = 'O'; + const char PROJECTOR = 'p'; + const char PROJECTOR_BACKWARD = 'h'; + const char PROJECTOR_CAMERA_IDENTIFIER = 's'; + const char PROJECTOR_CAMERA_LIGHT_IDENTIFIER = 'r'; + const char PROJECTOR_FORWARD = 'g'; + const char PROJECTOR_IDENTIFIER = 'j'; + const char PROJECTOR_LIGHT_IDENTIFIER = 'q'; + const char PROJECTOR_SECOND = 'w'; + const char PROJECTOR_SECOND_BACKWARD = 'v'; + const char PROJECTOR_SECOND_FORWARD = 'u'; + const char PROJECTOR_SECOND_IDENTIFIER = 't'; + const char PROJECTORS = 'x'; + const char PROJECTORS_IDENTIFIER = 'd'; + const char STATE = 'H'; + const char TAKEUP_BACKWARD = 'F'; + const char TAKEUP_FORWARD = 'D'; + /* END CMD FLAGS */ + + McopySerial(); + + void begin(char identity); + char loop(); + void confirm(char cmd); + String getString(); + void print(String message); + void sendString(String str); + + void debug (bool state); + void log (String message); + +}; + +#endif diff --git a/ino/mcopy_JKMM100_second_projector/mcopy_JKMM100_second_projector.ino b/ino/mcopy_JKMM100_second_projector/mcopy_JKMM100_second_projector.ino new file mode 100644 index 0000000..6698070 --- /dev/null +++ b/ino/mcopy_JKMM100_second_projector/mcopy_JKMM100_second_projector.ino @@ -0,0 +1,211 @@ +/* + * MOD for controlling second projector only + * Sketch containing firmware for the JKMM100 + * A collaboration between MONO NO AWARE and mcopy. + * Compatible with JK105 hardware. + * + * Uses an Arduino Uno compatible board and a + * custom PCB. + * Relay module for proj : + * Sainsmart 2 solid state relay board + + Wiring + + PROJECTOR + PROJECTOR_DIR + + Wire to corresponding pins + Arduino 3 4 5V GND + Relay 1 2 VCC GND + + For controling JK Projectors 106 models + Solid state relays connect to: + 2uf run capacitor + 400 Ohm resistor (50W) + + PINS FOR PROJ WIRE + + # + 1 - Red (top left from back of socket) => Wire from resistor + 2 - White (top center) => Wire from power cable (bridged by a fuse) + 3 - Black (top right) => Wire from capacitor + 8 - Orange (bottom center) => Pin 11 (microswitch digital read) + 9 - Brown (bottom right) => GND + + Relay 1 corresponds to FWD + Relay 2 corresponse to BWD + +*/ + +#include "McopySerial.h" + +volatile unsigned long now; + +//PROJECTOR CONSTANTS +const int PROJECTOR_MICROSWITCH = 11; +const int LED_FWD = 12; +const int LED_BWD = 13; + +const int PROJECTOR_FWD = 3; +const int PROJECTOR_BWD = 4; + +const int PROJECTOR_MOMENT = 240; +const int PROJECTOR_FRAME = 600; +const int PROJECTOR_MICROSWITCH_CLOSED = 0; +const int PROJECTOR_MICROSWITCH_OPENED = 1; +const int PROJECTOR_HALF_TIME = 450; +const int PROJECTOR_STOP_DELAY = 3; + +//PROJECTOR VARIABLES +boolean proj_dir = true; +boolean proj_running = false; +boolean proj_primed = false; +volatile int proj_micro_state = 0; +volatile long proj_time = 0; +volatile long proj_avg = -1; + +volatile char cmdChar = 'z'; + +McopySerial mc; + +void setup () { + pins(); + digitalWrite(LED_FWD, HIGH); + digitalWrite(LED_BWD, HIGH); + mc.begin(mc.PROJECTOR_SECOND_IDENTIFIER); + delay(42); + digitalWrite(LED_FWD, LOW); + digitalWrite(LED_BWD, LOW); +} + +void loop () { + now = millis(); + if (proj_running) { + proj2_microswitch(); + } else { + cmdChar = mc.loop(); + cmd(cmdChar); + } +} + +void pins () { + pinMode(PROJECTOR_MICROSWITCH, INPUT_PULLUP); + pinMode(PROJECTOR_FWD, OUTPUT); + pinMode(PROJECTOR_BWD, OUTPUT); + pinMode(LED_FWD, OUTPUT); + pinMode(LED_BWD, OUTPUT); + + digitalWrite(PROJECTOR_FWD, LOW); + digitalWrite(PROJECTOR_BWD, LOW); + + digitalWrite(LED_FWD, LOW); + digitalWrite(LED_BWD, LOW); +} + +void cmd (char val) { + if (val == mc.PROJECTOR_SECOND_FORWARD) { + proj2_direction(true); + } else if (val == mc.PROJECTOR_SECOND_BACKWARD) { + proj2_direction(false); + } else if (val == mc.PROJECTOR_SECOND) { + proj2_start(); + } else if (val == mc.STATE) { + state(); + } +} + +void proj2_start () { + proj_time = millis(); + + if (proj_dir) { + digitalWrite(PROJECTOR_FWD, HIGH); + digitalWrite(LED_FWD, HIGH); + } else { + digitalWrite(PROJECTOR_BWD, HIGH); + digitalWrite(LED_BWD, HIGH); + } + + proj_running = true; +} + +void proj2_stop () { + //stop both directions + delay(2); + digitalWrite(PROJECTOR_FWD, LOW); + digitalWrite(PROJECTOR_BWD, LOW); + digitalWrite(LED_FWD, LOW); + digitalWrite(LED_BWD, LOW); + if (digitalRead(PROJECTOR_MICROSWITCH) == PROJECTOR_MICROSWITCH_CLOSED) { + if (proj_dir) { + while (digitalRead(PROJECTOR_MICROSWITCH) == PROJECTOR_MICROSWITCH_CLOSED) { + digitalWrite(PROJECTOR_BWD, HIGH); + delay(PROJECTOR_STOP_DELAY); + } + digitalWrite(PROJECTOR_BWD, LOW); + } else { + while (digitalRead(PROJECTOR_MICROSWITCH) == PROJECTOR_MICROSWITCH_CLOSED) { + digitalWrite(PROJECTOR_FWD, HIGH); + delay(PROJECTOR_STOP_DELAY); + } + digitalWrite(PROJECTOR_FWD, LOW); + } + } + + delay(100); + + mc.confirm(mc.PROJECTOR_SECOND); + mc.log("projector_second()"); + proj_running = false; + update_timing(millis() - proj_time); + +} + +void proj2_direction (boolean state) { + proj_dir = state; + if (state) { + mc.confirm(mc.PROJECTOR_SECOND_FORWARD); + mc.log("proj2_direction -> true"); + } else { + mc.confirm(mc.PROJECTOR_SECOND_BACKWARD); + mc.log("proj2_direction -> false"); + } +} + +//LOW=0=CLOSED +//HIGH=1=OPEN +void proj2_microswitch () { + int val = digitalRead(PROJECTOR_MICROSWITCH); + if (!proj_primed // if not primed + && val != proj_micro_state // AND if state changes + && val == PROJECTOR_MICROSWITCH_OPENED // AND state changes to open + && now - proj_time > PROJECTOR_HALF_TIME) { + //prime + mc.log("proj_primed => true"); + proj_micro_state = val; + proj_primed = true; + } else if (proj_primed //if primed + && val != proj_micro_state //AND if state changes + && val == PROJECTOR_MICROSWITCH_CLOSED //AND state changes to open + && now - proj_time > PROJECTOR_HALF_TIME) { //AND total elapsed time is greater than half frame time + //stop + proj_primed = false; + proj_micro_state = val; //unneeded? + proj2_stop(); + } else { + delay(2); //some smothing value + } +} + +void update_timing (int timing) { + if (proj_avg == -1) { + proj_avg = timing; + } else { + proj_avg = (int) round((proj_avg + timing) / 2); + } +} + +void state () { + String stateString = String(mc.CAMERA_EXPOSURE); + stateString += String(proj_avg); + stateString += String(mc.STATE); + mc.print(stateString); +} diff --git a/package-lock.json b/package-lock.json index 8636eb8..3ed258e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "mcopy", - "version": "1.8.104", + "version": "1.8.105", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "mcopy", - "version": "1.8.104", + "version": "1.8.105", "license": "MIT", "dependencies": { "alert": "file:app/lib/alert", diff --git a/package.json b/package.json index de7d666..e8d2895 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "mcopy", - "version": "1.8.104", + "version": "1.8.105", "description": "Small gauge film optical printer platform", "main": "build.js", "directories": { diff --git a/processing/mcopy/cfg.json b/processing/mcopy/cfg.json index e79ec8a..3ef7aea 100644 --- a/processing/mcopy/cfg.json +++ b/processing/mcopy/cfg.json @@ -1,5 +1,5 @@ { - "version": "1.8.104", + "version": "1.8.105", "ext_port": 1111, "profiles": { "mcopy": { diff --git a/scripts/ino.sh b/scripts/ino.sh index f6e9645..646e9fe 100644 --- a/scripts/ino.sh +++ b/scripts/ino.sh @@ -22,6 +22,7 @@ SKETCHES=( mcopy_cam_relay mcopy_JKMM100 mcopy_JKMM100_work + mcopy_JKMM100_second_projector components/mcopy_light mcopy_projector_firmware mcopy_ACME_Trebes_Nanolab