From 66096fa2ea2a7b65cabe50a6be279e26aa61450e Mon Sep 17 00:00:00 2001 From: mattmcw Date: Fri, 19 Apr 2024 18:09:44 -0600 Subject: [PATCH] Add the designs and sketches for the ACME Trebes. --- ino/mcopy_ACME_Trebes_Nanolab/McopySerial.cpp | 74 ++++++ ino/mcopy_ACME_Trebes_Nanolab/McopySerial.h | 89 +++++++ .../mcopy_ACME_Trebes_Nanolab.ino | 242 ++++++++++++++++++ ino/mcopy_cam_relay/mcopy_cam_relay.ino | 4 +- scad/canon_rf_ACME_camera_mount.scad | 85 +++++- scripts/ino.sh | 1 + 6 files changed, 489 insertions(+), 6 deletions(-) create mode 100644 ino/mcopy_ACME_Trebes_Nanolab/McopySerial.cpp create mode 100644 ino/mcopy_ACME_Trebes_Nanolab/McopySerial.h create mode 100644 ino/mcopy_ACME_Trebes_Nanolab/mcopy_ACME_Trebes_Nanolab.ino diff --git a/ino/mcopy_ACME_Trebes_Nanolab/McopySerial.cpp b/ino/mcopy_ACME_Trebes_Nanolab/McopySerial.cpp new file mode 100644 index 0000000..a9658fc --- /dev/null +++ b/ino/mcopy_ACME_Trebes_Nanolab/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_ACME_Trebes_Nanolab/McopySerial.h b/ino/mcopy_ACME_Trebes_Nanolab/McopySerial.h new file mode 100644 index 0000000..8b9a80c --- /dev/null +++ b/ino/mcopy_ACME_Trebes_Nanolab/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_ACME_Trebes_Nanolab/mcopy_ACME_Trebes_Nanolab.ino b/ino/mcopy_ACME_Trebes_Nanolab/mcopy_ACME_Trebes_Nanolab.ino new file mode 100644 index 0000000..e0d8a3c --- /dev/null +++ b/ino/mcopy_ACME_Trebes_Nanolab/mcopy_ACME_Trebes_Nanolab.ino @@ -0,0 +1,242 @@ +/* + * Sketch containing firmware for the ACME Trebes + * optical printer with an existing Nanolab modification. + * + * Uses an Arduino Uno compatible board, a Sainsmart + * 8 relay module board and an ON/OFF toggle switch. + * Each relay is wired into a momentary switch in + * the Nanolab modification box. + + + Wiring + + CAMERA (OPTIONAL) + PROJECTOR + PROJECTOR 2 + + Wire to corresponding pins + Arduino 2 3 4 5 6 7 5V GND + Relay 1 2 3 4 5 6 VCC GND + Nanolab P2B P2F PB PF CB CF + + Arduino 12 GND + Switch A B + +*/ + +#include "McopySerial.h" + +//CAMERA CONSTANTS +const int CAMERA_FORWARD_PIN = 7; +const int CAMERA_BACKWARD_PIN = 6; + +const int CAMERA_MOMENT = 300; +const int CAMERA_LENGTH = 1000; + +//PROJECTOR CONSTANTS +const int PROJECTOR_FORWARD_PIN = 5; +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; + +//OTHER CONSTATNS +const int MODE_SWITCH_PIN = 12; +const int LED_PIN = 13; + +//VARIABLES +volatile bool cameraModeOn = false; +volatile char cmdChar = 'z'; +volatile long now; + +bool cam_dir = true; +bool proj_dir = true; +bool proj2_dir = true; + +McopySerial mc; + +void setup () { + pins(); + digitalWrite(LED_PIN, HIGH); + cameraMode(); + if (cameraModeOn) { + mc.begin(mc.CAMERA_PROJECTORS_IDENTIFIER); + } else { + mc.begin(mc.PROJECTORS_IDENTIFIER); + } + delay(42); + digitalWrite(LED_PIN, HIGH); +} + +void loop () { + now = millis(); + cmdChar = mc.loop(); + cmd(cmdChar); +} + +void cameraMode () { + for (uint8_t i = 0; i < 3; i++) { + //low + if (digitalRead(MODE_SWITCH_PIN) == LOW && !cameraModeOn) { + cameraModeOn = true; + } + delay(3); + } +} + +void pins () { + pinMode(MODE_SWITCH_PIN, INPUT_PULLUP); + pinMode(LED_PIN, OUTPUT); + + pinMode(CAMERA_FORWARD_PIN, OUTPUT); + pinMode(CAMERA_BACKWARD_PIN, OUTPUT); + pinMode(PROJECTOR_FORWARD_PIN, OUTPUT); + pinMode(PROJECTOR_BACKWARD_PIN, OUTPUT); + pinMode(PROJECTOR_SECOND_FORWARD_PIN, OUTPUT); + pinMode(PROJECTOR_SECOND_BACKWARD_PIN, OUTPUT); + + digitalWrite(CAMERA_FORWARD_PIN, HIGH); + digitalWrite(CAMERA_BACKWARD_PIN, HIGH); + digitalWrite(PROJECTOR_FORWARD_PIN, HIGH); + digitalWrite(PROJECTOR_BACKWARD_PIN, HIGH); + digitalWrite(PROJECTOR_SECOND_FORWARD_PIN, HIGH); + digitalWrite(PROJECTOR_SECOND_BACKWARD_PIN, HIGH); +} + +void cmd (char val) { + if (cameraModeOn && val == mc.CAMERA_FORWARD) { + camera_direction(true); + } else if (cameraModeOn && val == mc.CAMERA_BACKWARD) { + camera_direction(false); + } else if (cameraModeOn && val == mc.CAMERA) { + camera(); + } else if (val == mc.PROJECTOR_FORWARD) { + projector_direction(true); + } else if (val == mc.PROJECTOR_BACKWARD) { + projector_direction(false); + } else if (val == mc.PROJECTOR) { + projector(); + } else if (val == mc.PROJECTOR_SECOND_FORWARD) { + projector_second_direction(true); + } else if (val == mc.PROJECTOR_SECOND_BACKWARD) { + projector_second_direction(false); + } else if (val == mc.PROJECTOR_SECOND) { + projector_second(); + } else if (val == mc.PROJECTORS) { + projectors(); + } +} + +void camera_direction (bool dir) { + cam_dir = dir; + if (cam_dir) { + mc.log("Camera direction set to forward"); + mc.confirm(mc.CAMERA_FORWARD); + } else { + mc.log("Camera direction set to backward"); + mc.confirm(mc.CAMERA_BACKWARD); + } +} + +void camera () { + if (cam_dir) { + digitalWrite(CAMERA_FORWARD_PIN, LOW); + } else { + digitalWrite(CAMERA_BACKWARD_PIN, LOW); + } + delay(CAMERA_MOMENT); + if (cam_dir) { + digitalWrite(CAMERA_FORWARD_PIN, HIGH); + } else { + digitalWrite(CAMERA_BACKWARD_PIN, HIGH); + } + delay(CAMERA_LENGTH - CAMERA_MOMENT); + mc.log("camera()"); + mc.confirm(mc.CAMERA); +} + +void projector_direction (bool dir) { + proj_dir = dir; + if (proj_dir) { + mc.log("Projector direction set to forward"); + mc.confirm(mc.PROJECTOR_FORWARD); + } else { + mc.log("Projector direction set to backward"); + mc.confirm(mc.PROJECTOR_BACKWARD); + } +} + +void projector () { + if (proj_dir) { + digitalWrite(PROJECTOR_FORWARD_PIN, LOW); + } else { + digitalWrite(PROJECTOR_BACKWARD_PIN, LOW); + } + delay(PROJECTOR_MOMENT); + if (proj_dir) { + digitalWrite(PROJECTOR_FORWARD_PIN, HIGH); + } else { + digitalWrite(PROJECTOR_BACKWARD_PIN, HIGH); + } + delay(PROJECTOR_LENGTH - PROJECTOR_MOMENT); + mc.log("projector()"); + mc.confirm(mc.PROJECTOR); +} + +void projector_second_direction (bool dir) { + proj2_dir = dir; + if (proj2_dir) { + mc.log("Projector second direction set to forward"); + mc.confirm(mc.PROJECTOR_SECOND_FORWARD); + } else { + mc.log("Projector second direction set to backward"); + mc.confirm(mc.PROJECTOR_SECOND_BACKWARD); + } +} + +void projector_second () { + if (proj2_dir) { + digitalWrite(PROJECTOR_SECOND_FORWARD_PIN, LOW); + } else { + digitalWrite(PROJECTOR_SECOND_BACKWARD_PIN, LOW); + } + delay(PROJECTOR_MOMENT); + if (proj2_dir) { + digitalWrite(PROJECTOR_SECOND_FORWARD_PIN, HIGH); + } else { + digitalWrite(PROJECTOR_SECOND_BACKWARD_PIN, HIGH); + } + delay(PROJECTOR_LENGTH - PROJECTOR_MOMENT); + mc.log("projector_second()"); + mc.confirm(mc.PROJECTOR_SECOND); +} + +void projectors () { + if (proj_dir) { + digitalWrite(PROJECTOR_FORWARD_PIN, LOW); + } else { + digitalWrite(PROJECTOR_BACKWARD_PIN, LOW); + } + delay(PROJECTOR_MOMENT); + if (proj_dir) { + digitalWrite(PROJECTOR_FORWARD_PIN, HIGH); + } else { + digitalWrite(PROJECTOR_BACKWARD_PIN, HIGH); + } + delay(PROJECTOR_LENGTH - PROJECTOR_MOMENT); + if (proj2_dir) { + digitalWrite(PROJECTOR_SECOND_FORWARD_PIN, LOW); + } else { + digitalWrite(PROJECTOR_SECOND_BACKWARD_PIN, LOW); + } + delay(PROJECTOR_MOMENT); + if (proj2_dir) { + digitalWrite(PROJECTOR_SECOND_FORWARD_PIN, HIGH); + } else { + digitalWrite(PROJECTOR_SECOND_BACKWARD_PIN, HIGH); + } + delay(PROJECTOR_LENGTH - PROJECTOR_MOMENT); + mc.log("projectors()"); + mc.confirm(mc.PROJECTORS); +} \ No newline at end of file diff --git a/ino/mcopy_cam_relay/mcopy_cam_relay.ino b/ino/mcopy_cam_relay/mcopy_cam_relay.ino index 7f9cb47..d0d31f0 100644 --- a/ino/mcopy_cam_relay/mcopy_cam_relay.ino +++ b/ino/mcopy_cam_relay/mcopy_cam_relay.ino @@ -28,12 +28,12 @@ const int LED = 8; const int CAMERA_MOMENT = 240; //VARIABLES -volatile int cameraFrame = 2000; +volatile int cameraFrame = 1000; volatile char cmdChar = 'z'; volatile long now; volatile String exposureString; -volatile long exposureTarget = 2000; +volatile long exposureTarget = 1000; McopySerial mc; diff --git a/scad/canon_rf_ACME_camera_mount.scad b/scad/canon_rf_ACME_camera_mount.scad index 8793c94..766c482 100644 --- a/scad/canon_rf_ACME_camera_mount.scad +++ b/scad/canon_rf_ACME_camera_mount.scad @@ -1,16 +1,93 @@ include <./common/common.scad>; +FrontToBolt = 26.65; +FrontToFilmPlane = 15.85; + +BaseBoltD = 6.75; +BaseRegistrationPinD = 6.5; + +ChannelX = 15.5; +ChannelZ = 2.3; + +PlatformX = 90.6 + 15.5 + 80.5; +PlatformY = 105 + 73; + +MountX = 55; +MountY = 40; +MountZ = 70; +ExtensionY = 100; + +PlatformCenterX = (PlatformX / 2) - (80.5 + 7.75); + +CameraBoltD = 6.8; + +module bolt_slot (pos = [0, 0, 0], D = 10, H = 10, Length = 1) { + $fn = 80; + translate (pos) { + cube([D, Length, H + 1], center = true); + translate([0, Length / 2, 0]) cylinder(r = R(D), h = H + 1, center = true); + translate([0, -Length / 2, 0]) cylinder(r = R(D), h = H + 1, center = true); + } +} + module debug_camera() { X = 122; Y = 34.75; Z = 74; - cube([X, Y, Z], center = true); - cylinder(r = R(5), h = Z + 1, center = true, $fn = 30); + difference () { + cube([X, Y, Z], center = true); + translate([0, -(Y / 2) + FrontToBolt, 0]) cylinder(r = R(5), h = Z + 1, center = true, $fn = 30); + translate([0, -Y + FrontToFilmPlane, 39.75]) cube([X - 20, Y, Z], center = true); + } +} + +module debug_platform () { + H = 20; + $fn = 60; + translate([0, 0, -H / 2]) { + difference () { + cube([PlatformX, PlatformY, H], center = true); + translate([PlatformCenterX, 0, (H / 2) - (ChannelZ / 2) + 0.01]) cube([ChannelX, PlatformY + 1, ChannelZ], center = true); + translate([PlatformCenterX, -(PlatformY / 2) + 84, 7 / 2]) cylinder(r = R(BaseBoltD), h = H + 1, center = true); + translate([PlatformCenterX, -(PlatformY / 2) + 20.25, 7 / 2]) cylinder(r = R(BaseBoltD), h = H + 1, center = true); + } + translate([PlatformCenterX, -(PlatformY / 2) + (16 / 2), 2 / 2]) cube([ChannelX, 16, H + 2], center = true); + translate([PlatformCenterX, -(PlatformY / 2) + 32.9, 7 / 2]) cylinder(r = R(BaseRegistrationPinD), h = H + 7, center = true); + } } module canon_rf_ACME_camera_mount () { + $fn = 80; + difference () { + union () { + cube([MountX, MountY, MountZ], center = true); + translate([0, -(MountY / 2) + (ExtensionY / 2), -(MountZ / 2) + (10 / 2)]) cube([MountY + 1, ExtensionY, 10], center = true); + translate([0, -(MountY / 2) + (ExtensionY / 2), -(MountZ / 2) - (ChannelZ / 2)]) cube([ChannelX, ExtensionY, ChannelZ], center = true); + } + cube([MountX - 20, MountY + 1, MountZ - 20], center = true); + translate([0, -(MountY / 2) + (17 / 2), -MountZ / 2]) cube([ChannelX + 0.1, 17.01, 6], center = true); + //front bolt + translate([0, 0, -MountZ / 2]) cylinder(r = R(11), h = 30, center = true); + + bolt_slot([0, 13, -MountZ / 2], D = BaseRegistrationPinD, H = 30, Length = 2); + translate([0, -(MountY / 2) + 84, -MountZ / 2]) cylinder(r = R(7), h = 30, center = true); + translate([0, -(MountY / 2) + 84, -(MountZ / 2) + 22.5]) cylinder(r = R(10), h = 30, center = true); + //camera bolt + translate([0, -2, MountZ / 2]) cylinder(r = R(CameraBoltD), h = 30, center = true); + } + } -canon_rf_ACME_camera_mount(); -debug_camera(); \ No newline at end of file +module debug () { + translate([PlatformCenterX, -69, MountZ / 2]) difference() { + canon_rf_ACME_camera_mount(); + translate([50, 0, 0]) cube([100, 200, 100], center = true); + } + + translate([PlatformCenterX, -60, (110/2)]) cube([1, 63.5, 110], center = true); + translate([PlatformCenterX, -80, 105]) debug_camera(); + //color("red") debug_platform(); +} + +rotate([90, 0, 0]) canon_rf_ACME_camera_mount(); diff --git a/scripts/ino.sh b/scripts/ino.sh index 6407858..f6e9645 100644 --- a/scripts/ino.sh +++ b/scripts/ino.sh @@ -24,6 +24,7 @@ SKETCHES=( mcopy_JKMM100_work components/mcopy_light mcopy_projector_firmware + mcopy_ACME_Trebes_Nanolab ) for sketch in "${SKETCHES[@]}"; do