canon_ble #82

Merged
mattmcw merged 149 commits from canon_ble into main 2023-08-01 03:38:52 +00:00
138 changed files with 511818 additions and 974 deletions

6
.gitignore vendored
View File

@ -3,4 +3,8 @@
*.Parent
node_modules
dist
dist
*.svd
*debug_custom.json
*debug.cfg

6
.gitmodules vendored Normal file
View File

@ -0,0 +1,6 @@
[submodule "scad/common"]
path = scad/common
url = https://git.sixteenmillimeter.com/modules/common.git
[submodule "scad/sprocketed_roller"]
path = scad/sprocketed_roller
url = https://git.sixteenmillimeter.com/modules/sprocketed_roller.git

View File

@ -2,6 +2,11 @@
An open platform for controlling small-gauge film optical printers (16mm, Super8, 8mm).
## [Project Home - git.sixteenmillimter.com/16mm/mcopy](https://git.sixteenmillimter.com/16mm/mcopy)
* Github Mirror - [github.com/sixteenmillimeter/mcopy](https://github.com/sixteenmillimeter/mcopy)
* Gitlab Mirror - [gitlab.com/16mm/mcopy](https://gitlab.com/16mm/mcopy)
-------
1. <a href="#intro">Introduction</a>
2. <a href="#downloads">Downloads</a>

6
app/.gitignore vendored
View File

@ -1,6 +1,6 @@
node_modules/*
logs/*
data/transfer*.json
.appleId
.applePwd
.appleIdentity
.appleId*
.applePwd*
.appleIdentity*

View File

@ -668,12 +668,39 @@ button:focus {
}
#settings > div {
width: 300px;
margin: 0 auto;
}
#settings > div.left {
float: left;
padding-left: 30px;
}
#settings > div.right {
float: right;
padding-right: 30px;
}
#settings > div.right input[type=number] {
min-width: 200px;
width: 200px;
}
#settings > div.right input[readonly] {
cursor: not-allowed;
}
#settings > div.right .spacer {
height: 62px;
}
#settings > div.right .proj_time {
height: 111px;
}
#settings > div.right .cam_time {
height: 111px;
}
#settings > div.right > div {
width: 270px;
}
#settings > div > div {
width: 360px;
}
#settings input[type=text],
#settings input[type=number],
#settings select {
display: block;
border-radius: 5px;
@ -688,26 +715,32 @@ button:focus {
padding: 6px 12px;
font-size: 21px;
min-width: 300px;
max-width: 300px;
}
#settings input[type=text] span,
#settings input[type=number] span,
#settings select span {
display: block;
font-size: 16px;
font-weight: 200;
}
#settings input[type=text]:active,
#settings input[type=number]:active,
#settings select:active,
#settings input[type=text] .active,
#settings input[type=number] .active,
#settings select .active {
background: #fff;
color: #272b30;
outline: none;
}
#settings input[type=text]:focus,
#settings input[type=number]:focus,
#settings select:focus {
outline: none;
}
#settings input[type=text].active,
#settings input[type=number].active,
#settings select.active {
border-color: #DAE035;
color: #DAE035;
@ -716,8 +749,9 @@ button:focus {
width: 200px;
}
#settings button {
margin-top: -1px;
margin-top: 0px;
float: right;
padding: 8px 16px 9px;
}
#settings input[type=radio] {
float: right;

View File

@ -186,7 +186,10 @@
"capper_on": "A",
"capper_off": "B",
"takeup_forward": "D",
"takeup_backward": "E"
"takeup_backward": "F",
"error" : "E",
"camera_exposure" : "G",
"state" : "H"
}
}
}

View File

@ -407,7 +407,7 @@
</div>
</div>
<div id="settings" class="screen">
<div>
<div class="left">
<div>
<h4>Devices</h4>
<select id="devices">
@ -457,6 +457,19 @@
</select>
</div>
</div>
<div class="right">
<div class="spacer"></div>
<div class="proj_time">
<h4>Projector Time (ms)</h4>
<input type="number" readonly id="proj_time" value="0" />
<button id="submit_proj_time" class="hide"></button>
</div>
<div class="cam_time">
<h4>Camera Time (ms)</h4>
<input type="number" readonly id="cam_time" value="0" />
<button id="submit_cam_time" class="hide" onclick="cam.exposure($('#cam_time').val());"></button>
</div>
</div>
</div>
</div>
<div id="overlay" onclick="gui.overlay(false);gui.spinner(false);"></div>

View File

@ -2531,4 +2531,5 @@ async function init () {
seq.init();
capper.init();
alertObj.init();
timing.init();
};

View File

@ -4,18 +4,46 @@
}
> div{
width: 300px;
margin: 0 auto;
&.left{
float: left;
padding-left: 30px;
}
&.right{
float: right;
padding-right: 30px;
input[type=number] {
min-width: 200px;
width: 200px;
}
input[readonly]{
cursor: not-allowed;
}
.spacer{
height: 62px;
}
.proj_time{
height: 111px;
}
.cam_time{
height: 111px;
}
& > div {
width: 270px;
}
}
}
> div > div{
width: 360px;
}
input[type=text],
input[type=text],
input[type=number],
select{
.button();
display: inline-block;
padding: 6px 12px;
font-size: 21px;
min-width: 300px;
max-width: 300px;
&.active{
border-color: @SELECTED;
color: @SELECTED;
@ -25,8 +53,9 @@
width: 200px;
}
button{
margin-top: -1px;
float: right;
margin-top: 0px;
float: right;
padding: 8px 16px 9px;
}
input[type=radio]{
float: right;

View File

@ -1,11 +1,23 @@
'use strict';
Object.defineProperty(exports, "__esModule", { value: true });
/**
* 2023-07-16 Clarification
*
* Previous versions of this script intermingled and even
* swapped the usage of the terms 'serial' and 'device'.
* From here on out, the terms will be used as such:
*
* serial - a hardware address of a serial port
* device - common name of a type of mcopy device (eg. camera,
* projector, light) that is aliased to a serial port
*
**/
//import Log = require('log');
const delay_1 = require("delay");
const { SerialPort } = require('serialport');
const { ReadlineParser } = require('@serialport/parser-readline');
const exec = require('child_process').exec;
const parser = new ReadlineParser({});
const parser = new ReadlineParser({ delimiter: '\r\n' });
const newlineRe = new RegExp('\n', 'g');
const returnRe = new RegExp('\r', 'g');
let eventEmitter;
@ -29,12 +41,13 @@ class Arduino {
this.path = {};
this.known = KNOWN;
this.alias = {};
this.serial = { connect: {}, projector: {}, camera: {}, light: {} };
this.serial = {};
this.hasState = {};
this.baud = 57600;
this.queue = {};
this.timer = 0;
this.lock = false;
this.locks = {};
this.stateStr = {};
this.errorState = errorState;
this.init();
}
@ -92,55 +105,122 @@ class Arduino {
**/
async sendAsync(device, cmd) {
return new Promise((resolve, reject) => {
this.log.info(`sendAsync ${cmd} -> ${device}`);
this.queue[cmd] = (ms) => {
return resolve(ms);
};
return this.serial[device].write(cmd, (err, results) => {
this.log.info(`Device: ${device}`);
return this.serial[this.alias[device]].write(cmd, (err, results) => {
if (err) {
//console.error(err)
//this.log.error(err)
return reject(err);
}
});
});
}
async send(serial, cmd) {
const device = this.alias[serial];
let results;
//console.log(`${cmd} -> ${serial}`)
if (this.locks[serial]) {
return false;
/**
*
**/
async send(device, cmd) {
const serial = this.alias[device];
let ms;
this.log.info(`send ${cmd} -> ${device}`);
if (this.isLocked(serial)) {
this.log.warn(`send Serial ${serial} is locked`);
return null;
}
this.timer = new Date().getTime();
this.locks[serial] = true;
this.lock(serial);
await delay_1.delay(cfg.arduino.serialDelay);
try {
results = await this.sendAsync(device, cmd);
ms = await this.sendAsync(device, cmd);
}
catch (e) {
return console.error(e);
return this.log.error(e);
}
this.locks[serial] = false;
this.unlock(serial);
await eventEmitter.emit('arduino_send', cmd);
return results;
return ms;
}
async string(serial, str) {
const device = this.alias[serial];
/**
*
**/
async sendString(device, str) {
let writeSuccess;
await delay_1.delay(cfg.arduino.serialDelay);
if (typeof this.serial[device].fake !== 'undefined'
&& this.serial[device].fake) {
return this.serial[device].string(str);
if (typeof this.serial[this.alias[device]].fake !== 'undefined'
&& this.serial[this.alias[device]].fake) {
return this.serial[this.alias[device]].string(str);
}
else {
this.log.info(`sendString ${str} -> ${device}`);
try {
writeSuccess = await this.writeAsync(device, str);
}
catch (e) {
return console.error(e);
return this.log.error(e);
}
this.unlock(this.alias[device]);
return writeSuccess;
}
}
/**
*
**/
async stateAsync(device, confirm = false) {
const cmd = cfg.arduino.cmd.state;
const serial = confirm ? this.alias['connect'] : this.alias[device];
return new Promise((resolve, reject) => {
this.queue[cmd] = (state) => {
this.stateStr[device] = state;
if (confirm) {
this.hasState[device] = true;
this.log.info(`Device ${device} supports state [${state}]`);
}
return resolve(state);
};
if (confirm) {
setTimeout(function () {
if (typeof this.queue[cmd] !== 'undefined') {
delete this.queue[cmd];
this.hasState[device] = false;
this.log.info(`Device ${device} does not support state`);
return resolve(null);
}
}.bind(this), 1000);
}
this.log.info(`stateAsync ${cmd} -> ${device}`);
return this.serial[serial].write(cmd, (err, results) => {
if (err) {
//this.log.error(err)
return reject(err);
}
});
});
}
/**
*
**/
async state(device, confirm = false) {
const serial = confirm ? this.alias['connect'] : this.alias[device];
let results;
if (this.isLocked(serial)) {
this.log.warn(`state Serial ${serial} is locked`);
return null;
}
this.timer = new Date().getTime();
this.lock(serial);
await delay_1.delay(cfg.arduino.serialDelay);
try {
results = await this.stateAsync(device, confirm);
}
catch (e) {
return this.log.error(e);
}
this.unlock(serial);
await eventEmitter.emit('arduino_state', cfg.arduino.cmd.state);
return results;
}
/**
* Send a string to an Arduino using async/await
*
@ -151,7 +231,7 @@ class Arduino {
**/
async writeAsync(device, str) {
return new Promise((resolve, reject) => {
this.serial[device].write(str, function (err, results) {
this.serial[this.alias[device]].write(str, function (err, results) {
if (err) {
return reject(err);
}
@ -159,60 +239,75 @@ class Arduino {
});
});
}
/**
*
**/
end(serial, data) {
const end = new Date().getTime();
const ms = end - this.timer;
let complete;
//console.log(`${serial} -> ${data}`);
//this.log.info(`end ${serial} -> ${data}`)
if (this.queue[data] !== undefined) {
this.locks[serial] = false;
this.unlock(serial);
complete = this.queue[data](ms); //execute callback
eventEmitter.emit('arduino_end', data);
delete this.queue[data];
}
else if (data === 'E') {
else if (data[0] === cfg.arduino.cmd.state) {
//this.log.info(`end serial -> ${serial}`)
this.unlock(serial);
complete = this.queue[cfg.arduino.cmd.state](data);
eventEmitter.emit('arduino_end', data);
delete this.queue[cfg.arduino.cmd.state];
return data;
}
else if (data[0] === cfg.arduino.cmd.error) {
this.log.error(`Received error from device ${serial}`);
this.unlock(serial);
//error state
//stop sequence
//throw error in ui
}
else {
//console.log('Received stray "' + data + '"'); //silent to user
//this.log.info('Received stray "' + data + '"') //silent to user
}
return ms;
}
aliasSerial(serial, device) {
//this.log.info(`Making "${serial}" an alias of ${device}`);
this.alias[serial] = device;
aliasSerial(device, serial) {
//this.log.info(`Making "${serial}" an alias of ${device}`)
this.alias[device] = serial;
}
async connect(serial, device, confirm) {
async connect(device, serial, confirm) {
//this.log.info(`connect device ${device}`)
//this.log.info(`connect serial ${serial}`)
return new Promise(async (resolve, reject) => {
let connectSuccess;
this.path[serial] = device;
this.alias[serial] = device;
this.serial[device] = new SerialPort({
path: this.path[serial],
this.path[device] = serial;
this.aliasSerial(device, serial);
this.serial[serial] = new SerialPort({
path: serial,
autoOpen: false,
baudRate: cfg.arduino.baud,
parser: parser
parser
});
this.locks[device] = false;
this.unlock(serial);
try {
connectSuccess = await this.openArduino(device);
}
catch (e) {
console.error('failed to open: ' + e);
this.log.error('failed to open: ' + e);
return reject(e);
}
//console.log(`Opened connection with ${this.path[serial]} as ${serial}`);
this.log.info(`Opened connection with ${this.path[device]} as ${device}`);
if (!confirm) {
this.serial[device].on('data', async (data) => {
this.serial[this.alias[device]].on('data', async (data) => {
let d = data.toString('utf8');
d = d.replace(newlineRe, '').replace(returnRe, '');
return this.end(serial, d);
});
}
else {
this.serial[device].on('data', async (data) => {
this.serial[this.alias[device]].on('data', async (data) => {
let d = data.toString('utf8');
d = d.replace(newlineRe, '').replace(returnRe, '');
return await this.confirmEnd(d);
@ -222,7 +317,6 @@ class Arduino {
});
}
confirmEnd(data) {
//console.dir(data)
if (data === cfg.arduino.cmd.connect
|| data === cfg.arduino.cmd.projector_identifier
|| data === cfg.arduino.cmd.camera_identifier
@ -248,11 +342,17 @@ class Arduino {
|| data === cfg.arduino.cmd.camera_capper_projectors_identifier) {
this.confirmExec(null, data);
this.confirmExec = {};
this.unlock(this.alias['connect']);
}
else if (data[0] === cfg.arduino.cmd.state) {
this.queue[cfg.arduino.cmd.state](data);
delete this.queue[cfg.arduino.cmd.state];
this.unlock(this.alias['connect']);
}
}
async verify() {
return new Promise(async (resolve, reject) => {
const device = this.alias['connect'];
const device = 'connect';
let writeSuccess;
this.confirmExec = function (err, data) {
if (data === cfg.arduino.cmd.connect) {
@ -274,7 +374,7 @@ class Arduino {
}
async distinguish() {
return new Promise(async (resolve, reject) => {
const device = this.alias['connect'];
const device = 'connect';
let writeSuccess;
let type;
this.confirmExec = function (err, data) {
@ -342,7 +442,7 @@ class Arduino {
});
}
async close() {
const device = this.alias['connect'];
const device = 'connect';
let closeSuccess;
try {
closeSuccess = await this.closeArduino(device);
@ -352,11 +452,10 @@ class Arduino {
}
return closeSuccess;
}
;
async fakeConnect(serial) {
const device = '/dev/fake';
this.alias[serial] = device;
this.serial[device] = {
async fakeConnect(device) {
const serial = '/dev/fake';
this.aliasSerial(device, serial);
this.serial[serial] = {
write: async function (cmd, cb) {
const t = {
c: cfg.arduino.cam.time + cfg.arduino.cam.delay,
@ -378,7 +477,7 @@ class Arduino {
},
fake: true
};
//console.log('Connected to fake arduino! Not real! Does not exist!');
//this.log.info('Connected to fake arduino! Not real! Does not exist!')
return true;
}
/**
@ -390,7 +489,7 @@ class Arduino {
**/
async openArduino(device) {
return new Promise((resolve, reject) => {
return this.serial[device].open((err) => {
return this.serial[this.alias[device]].open((err) => {
if (err) {
return reject(err);
}
@ -407,7 +506,7 @@ class Arduino {
**/
async closeArduino(device) {
return new Promise((resolve, reject) => {
return this.serial[device].close((err) => {
return this.serial[this.alias[device]].close((err) => {
if (err) {
return reject(err);
}
@ -415,6 +514,17 @@ class Arduino {
});
});
}
lock(serial) {
//this.log.info(`Locked serial ${serial}`)
this.locks[serial] = true;
}
unlock(serial) {
//this.log.info(`Unlocked serial ${serial}`)
this.locks[serial] = false;
}
isLocked(serial) {
return typeof this.locks[serial] !== 'undefined' && this.locks[serial] === true;
}
}
if (typeof module !== 'undefined' && module.parent) {
module.exports = function (c, ee, errorState) {

File diff suppressed because one or more lines are too long

View File

@ -2,6 +2,7 @@
Object.defineProperty(exports, "__esModule", { value: true });
const intval_1 = require("intval");
const processing_1 = require("processing");
const delay_1 = require("delay");
/** class representing camera functions **/
class Camera {
/**
@ -157,11 +158,55 @@ class Camera {
/**
*
**/
exposure(exposure, id) {
let cmd = 'E';
this.intval.setExposure(this.id, exposure, (ms) => {
this.end(cmd, id, ms);
});
async exposure(exposure, id) {
const cmd = this.cfg.arduino.cmd.camera_exposure;
const str = `${exposure}`;
const started = +new Date();
let ms;
let confirmState;
let parts;
let confirmExposure;
if (this.intval) {
return this.intval.setExposure(this.id, exposure, (ms) => {
this.ui.send('timing', { c: 'c', ms: exposure });
return this.end(cmd, id, ms);
});
}
else if (this.arduino.hasState[this.id]) {
try {
ms = this.arduino.send(this.id, cmd);
}
catch (err) {
this.log.error('Error sending camera exposure command', err);
}
await delay_1.delay(1);
try {
ms = await this.arduino.sendString(this.id, str);
}
catch (err) {
this.log.error('Error sending camera exposure string', err);
}
await ms;
await delay_1.delay(1);
try {
confirmState = await this.arduino.state(this.id, false);
}
catch (err) {
this.log.error(`Error confirming set state`, err);
}
parts = this.arduino.stateStr[this.id].split('G');
if (parts.length > 1) {
parts = parts[1].split('H');
confirmExposure = parseInt(parts[0]);
if (!isNaN(confirmExposure)) {
this.log.info(`Exposure successfully set to ${confirmExposure}ms`);
this.ui.send('timing', { c: 'c', ms: exposure });
}
}
ms = (+new Date()) - started;
return await this.end(cmd, id, ms);
}
return 0;
}
/**
*
@ -232,6 +277,14 @@ class Camera {
this.log.error(err);
}
}
else if (typeof arg.exposure !== 'undefined') {
try {
await this.exposure(arg.exposure, arg.id);
}
catch (err) {
this.log.error(err);
}
}
event.returnValue = true;
}
/**
@ -274,9 +327,13 @@ class Camera {
else if (cmd === this.cfg.arduino.cmd.camerass) {
message += 'Cameras both MOVED 1 frame each';
}
else if (cmd === this.cfg.arduino.camera_exposure) {
message += 'Camera set exposure';
}
message += ` ${ms}ms`;
this.log.info(message);
this.ui.send(this.id, { cmd: cmd, id: id, ms: ms });
return ms;
}
}
module.exports = function (arduino, cfg, ui, filmout, second) {

File diff suppressed because one or more lines are too long

View File

@ -627,6 +627,16 @@ class Commands {
}
return ms;
}
async camera_exposure(cmd) {
let ms;
try {
ms = await this.cam.exposure(cmd.light);
}
catch (err) {
throw err;
}
return ms;
}
}
module.exports = function (cfg, proj, cam, light, alert, cam2, proj2, capper) {
return new Commands(cfg, proj, cam, light, alert, cam2, proj2, capper);

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,8 @@
/**
* Delay in an async/await function
*
* @param {integer} ms Milliseconds to delay for
*
* @returns {Promise} Promise to resolve after timeout
**/
export declare function delay(ms: number): Promise<unknown>;

View File

@ -1,4 +1,6 @@
'use strict';
Object.defineProperty(exports, "__esModule", { value: true });
exports.delay = void 0;
/**
* Delay in an async/await function
*
@ -11,5 +13,6 @@ function delay(ms) {
return setTimeout(resolve, ms);
});
}
module.exports.delay = delay;
exports.delay = delay;
module.exports = { delay };
//# sourceMappingURL=index.js.map

View File

@ -1 +1 @@
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/delay/index.ts"],"names":[],"mappings":"AAAA,YAAY,CAAC;AAEb;;;;;;IAMI;AAEJ,SAAS,KAAK,CAAE,EAAW;IAC1B,OAAO,IAAI,OAAO,CAAC,CAAC,OAAa,EAAE,EAAE;QACpC,OAAO,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;IAChC,CAAC,CAAC,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,OAAO,CAAC,KAAK,GAAG,KAAK,CAAC"}
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/delay/index.ts"],"names":[],"mappings":"AAAA,YAAY,CAAC;;;AAEb;;;;;;IAMI;AAEJ,SAAgB,KAAK,CAAE,EAAW;IACjC,OAAO,IAAI,OAAO,CAAC,CAAC,OAAa,EAAE,EAAE;QACpC,OAAO,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;IAChC,CAAC,CAAC,CAAC;AACJ,CAAC;AAJD,sBAIC;AAED,MAAM,CAAC,OAAO,GAAG,EAAE,KAAK,EAAE,CAAC"}

View File

@ -56,34 +56,34 @@ class Devices {
*
**/
async enumerate() {
let devices;
let serials;
try {
devices = await this.arduino.enumerate();
serials = await this.arduino.enumerate();
}
catch (err) {
this.log.warn(err, 'SERIAL', false, true);
await delay_1.delay(1000);
return this.all([]);
}
this.log.info(`Found ${devices.length} USB devices`, 'SERIAL', true, true);
devices = this.favor(devices);
return await this.all(devices);
this.log.info(`Found ${serials.length} USB devices`, 'SERIAL', true, true);
serials = this.favor(serials);
return await this.all(serials);
}
/**
*
**/
favor(devices) {
favor(serials) {
const past = this.settings.state.devices.filter((device) => {
if (device.arduino) {
if (device.serial) {
return device;
}
}).map((device) => {
return device.arduino;
return device.serial;
});
if (past.length === 0) {
return devices;
return serials;
}
devices.sort((a, b) => {
serials.sort((a, b) => {
if (past.indexOf(a) !== -1 && past.indexOf(b) === -1) {
return 1;
}
@ -92,17 +92,18 @@ class Devices {
}
return 0;
});
return devices;
return serials;
}
/**
*
**/
async distinguish(device) {
async distinguish(serial) {
let connectSuccess;
let verifySuccess;
let type;
let device;
//this.log.info(`distinguish() ${serial}`)
try {
connectSuccess = await this.arduino.connect('connect', device, true);
connectSuccess = await this.arduino.connect('connect', serial, true);
}
catch (err) {
this.log.error('Error connecting', err);
@ -116,18 +117,25 @@ class Devices {
this.log.error('Error verifying device', err);
return null;
}
this.log.info(`Verified ${device} as mcopy device`, 'SERIAL', true, true);
this.log.info(`Verified ${serial} as mcopy device`, 'SERIAL', true, true);
await delay_1.delay(1000);
try {
type = await this.arduino.distinguish();
device = await this.arduino.distinguish();
}
catch (err) {
this.log.error('Error distinguishing device', err);
return null;
}
this.remember('arduino', device, type);
this.log.info(`Determined ${device} to be ${type}`, 'SERIAL', true, true);
return type;
this.remember('arduino', device, serial);
this.log.info(`Determined ${device} to be ${device}`, 'SERIAL', true, true);
await delay_1.delay(100);
try {
await this.arduino.state(device, true);
}
catch (err) {
this.log.error('Error checking state capability', err);
}
return device;
}
/**
*
@ -146,8 +154,8 @@ class Devices {
return true;
}
/**
*
**/
*
**/
async fakeCamera() {
this.connected.camera = '/dev/fake';
try {
@ -194,9 +202,9 @@ class Devices {
return true;
}
/**
*
**/
async connectDevice(device, type) {
*
**/
async connectDevice(device, serial) {
let closeSuccess;
let connectSuccess;
try {
@ -206,10 +214,10 @@ class Devices {
this.log.error('Error closing arduino connection', err);
return false;
}
if (type === 'projector') {
this.connected.projector = device;
if (device === 'projector') {
this.connected.projector = serial;
try {
connectSuccess = await this.arduino.connect('projector', device, false);
connectSuccess = await this.arduino.connect('projector', serial, false);
}
catch (err) {
this.log.error('Error connecting to projector', err);
@ -217,10 +225,10 @@ class Devices {
}
this.log.info(`Connected to ${device} as PROJECTOR`, 'SERIAL', true, true);
}
else if (type === 'camera') {
this.connected.camera = device;
else if (device === 'camera') {
this.connected.camera = serial;
try {
connectSuccess = await this.arduino.connect('camera', device, false);
connectSuccess = await this.arduino.connect('camera', serial, false);
}
catch (err) {
this.log.error('Error connecting to camera', err);
@ -228,10 +236,10 @@ class Devices {
}
this.log.info(`Connected to ${device} as CAMERA`, 'SERIAL', true, true);
}
else if (type === 'light') {
this.connected.light = device;
else if (device === 'light') {
this.connected.light = serial;
try {
connectSuccess = await this.arduino.connect('light', device, false);
connectSuccess = await this.arduino.connect('light', serial, false);
}
catch (err) {
this.log.error('Error connecting to light', err);
@ -239,12 +247,12 @@ class Devices {
}
this.log.info(`Connected to ${device} as LIGHT`, 'SERIAL', true, true);
}
else if (type === 'projector,light') {
this.connected.projector = device;
this.connected.light = device;
this.arduino.aliasSerial('light', device);
else if (device === 'projector,light') {
this.connected.projector = serial;
this.connected.light = serial;
this.arduino.aliasSerial('light', serial);
try {
connectSuccess = await this.arduino.connect('projector', device, false);
connectSuccess = await this.arduino.connect('projector', serial, false);
}
catch (err) {
this.log.error('Error connecting to projector and light', err);
@ -252,14 +260,14 @@ class Devices {
}
this.log.info(`Connected to ${device} as PROJECTOR + LIGHT`, 'SERIAL', true, true);
}
else if (type === 'projector,camera,light') {
this.connected.projector = device;
this.connected.camera = device;
this.connected.light = device;
this.arduino.aliasSerial('camera', device);
this.arduino.aliasSerial('light', device);
else if (device === 'projector,camera,light') {
this.connected.projector = serial;
this.connected.camera = serial;
this.connected.light = serial;
this.arduino.aliasSerial('camera', serial);
this.arduino.aliasSerial('light', serial);
try {
connectSuccess = await this.arduino.connect('projector', device, false);
connectSuccess = await this.arduino.connect('projector', serial, false);
}
catch (err) {
this.log.error('Error connecting to projector, camera and light', err);
@ -267,12 +275,12 @@ class Devices {
}
this.log.info(`Connected to ${device} as PROJECTOR + CAMERA + LIGHT`, 'SERIAL', true, true);
}
else if (type === 'projector,camera') {
this.connected.projector = device;
this.connected.camera = device;
this.arduino.aliasSerial('camera', device);
else if (device === 'projector,camera') {
this.connected.projector = serial;
this.connected.camera = serial;
this.arduino.aliasSerial('camera', serial);
try {
connectSuccess = await this.arduino.connect('projector', device, false);
connectSuccess = await this.arduino.connect('projector', serial, false);
}
catch (err) {
this.log.error('Error connecting to projector and camera', err);
@ -280,10 +288,10 @@ class Devices {
}
this.log.info(`Connected to ${device} as PROJECTOR + CAMERA`, 'SERIAL', true, true);
}
else if (type === 'projector_second') {
this.connected.projector_second = device;
else if (device === 'projector_second') {
this.connected.projector_second = serial;
try {
connectSuccess = await this.arduino.connect('projector_second', device, false);
connectSuccess = await this.arduino.connect('projector_second', serial, false);
}
catch (err) {
this.log.error('Error connecting to secondary projector', err);
@ -291,130 +299,130 @@ class Devices {
}
this.log.info(`Connected to ${device} as PROJECTOR_SECOND`, 'SERIAL', true, true);
}
else if (type === 'projector,projector_second') {
this.connected.projector = device;
this.connected.projector_second = device;
this.arduino.aliasSerial('projector_second', device);
else if (device === 'projector,projector_second') {
this.connected.projector = serial;
this.connected.projector_second = serial;
this.arduino.aliasSerial('projector_second', serial);
try {
connectSuccess = await this.arduino.connect('projector', device, false);
connectSuccess = await this.arduino.connect('projector', serial, false);
}
catch (err) {
this.log.error('Error connecting to projector and secondary projector', err);
return false;
}
}
else if (type === 'camera_second') {
this.connected.camera_second = device;
else if (device === 'camera_second') {
this.connected.camera_second = serial;
try {
connectSuccess = await this.arduino.connect('camera_second', device, false);
connectSuccess = await this.arduino.connect('camera_second', serial, false);
}
catch (err) {
console.error(err);
return false;
}
}
else if (type === 'camera,camera_second') {
this.connected.camera = device;
this.connected.camera_second = device;
this.arduino.aliasSerial('camera_second', device);
else if (device === 'camera,camera_second') {
this.connected.camera = serial;
this.connected.camera_second = serial;
this.arduino.aliasSerial('camera_second', serial);
try {
connectSuccess = await this.arduino.connect('camera', device, false);
connectSuccess = await this.arduino.connect('camera', serial, false);
}
catch (err) {
this.log.error('Error connecting to camera, camera_secondary and projector', err);
return false;
}
}
else if (type === 'camera,projector,projector_second') {
this.connected.camera = device;
this.connected.projector = device;
this.connected.projector_second = device;
this.arduino.aliasSerial('projector', device);
this.arduino.aliasSerial('projector_second', device);
else if (device === 'camera,projector,projector_second') {
this.connected.camera = serial;
this.connected.projector = serial;
this.connected.projector_second = serial;
this.arduino.aliasSerial('projector', serial);
this.arduino.aliasSerial('projector_second', serial);
try {
connectSuccess = await this.arduino.connect('camera', device, false);
connectSuccess = await this.arduino.connect('camera', serial, false);
}
catch (err) {
this.log.error('Error connecting to camera, projector and projector_second', err);
return false;
}
}
else if (type === 'camera,camera_second,projector') {
this.connected.camera = device;
this.connected.camera_second = device;
this.connected.projector = device;
this.arduino.aliasSerial('camera_second', device);
this.arduino.aliasSerial('projector', device);
else if (device === 'camera,camera_second,projector') {
this.connected.camera = serial;
this.connected.camera_second = serial;
this.connected.projector = serial;
this.arduino.aliasSerial('camera_second', serial);
this.arduino.aliasSerial('projector', serial);
try {
connectSuccess = await this.arduino.connect('camera', device, false);
connectSuccess = await this.arduino.connect('camera', serial, false);
}
catch (err) {
this.log.error('Error connecting to camera, camera_second and projector', err);
return false;
}
}
else if (type === 'camera,camera_second,projector,projector_second') {
this.connected.camera = device;
this.connected.camera_second = device;
this.connected.projector = device;
this.connected.projector_second = device;
this.arduino.aliasSerial('camera_second', device);
this.arduino.aliasSerial('projector', device);
this.arduino.aliasSerial('projector_second', device);
else if (device === 'camera,camera_second,projector,projector_second') {
this.connected.camera = serial;
this.connected.camera_second = serial;
this.connected.projector = serial;
this.connected.projector_second = serial;
this.arduino.aliasSerial('camera_second', serial);
this.arduino.aliasSerial('projector', serial);
this.arduino.aliasSerial('projector_second', serial);
try {
connectSuccess = await this.arduino.connect('camera', device, false);
connectSuccess = await this.arduino.connect('camera', serial, false);
}
catch (err) {
this.log.error('Error connecting to camera, camera_second, projector and projector_second', err);
return false;
}
}
else if (type === 'capper') {
this.connected.capper = device;
else if (device === 'capper') {
this.connected.capper = serial;
try {
connectSuccess = await this.arduino.connect('capper', device, false);
connectSuccess = await this.arduino.connect('capper', serial, false);
}
catch (err) {
this.log.error('Error connecting capper', err);
return false;
}
}
else if (type === 'camera,capper') {
this.connected.camera = device;
this.connected.capper = device;
this.arduino.aliasSerial('capper', device);
else if (device === 'camera,capper') {
this.connected.camera = serial;
this.connected.capper = serial;
this.arduino.aliasSerial('capper', serial);
try {
connectSuccess = await this.arduino.connect('camera', device, false);
connectSuccess = await this.arduino.connect('camera', serial, false);
}
catch (err) {
this.log.error('Error connecting to camera and capper', err);
return false;
}
}
else if (type === 'camera,capper,projector') {
this.connected.camera = device;
this.connected.capper = device;
this.connected.projector = device;
this.arduino.aliasSerial('capper', device);
this.arduino.aliasSerial('projector', device);
else if (device === 'camera,capper,projector') {
this.connected.camera = serial;
this.connected.capper = serial;
this.connected.projector = serial;
this.arduino.aliasSerial('capper', serial);
this.arduino.aliasSerial('projector', serial);
try {
connectSuccess = await this.arduino.connect('camera', device, false);
connectSuccess = await this.arduino.connect('camera', serial, false);
}
catch (err) {
this.log.error('Error connecting to camera, capper and projector', err);
return false;
}
}
else if (type === 'camera,capper,projector,projector_second') {
this.connected.camera = device;
this.connected.capper = device;
this.connected.projector = device;
this.connected.projector_second = device;
this.arduino.aliasSerial('capper', device);
this.arduino.aliasSerial('projector', device);
this.arduino.aliasSerial('projector_second', device);
else if (device === 'camera,capper,projector,projector_second') {
this.connected.camera = serial;
this.connected.capper = serial;
this.connected.projector = serial;
this.connected.projector_second = serial;
this.arduino.aliasSerial('capper', serial);
this.arduino.aliasSerial('projector', serial);
this.arduino.aliasSerial('projector_second', serial);
try {
connectSuccess = await this.arduino.connect('camera', device, false);
connectSuccess = await this.arduino.connect('camera', serial, false);
}
catch (err) {
this.log.error('Error connecting to camera, capper, projector and projector_second', err);
@ -424,19 +432,21 @@ class Devices {
return connectSuccess;
}
/**
*
**/
*
**/
//Cases for 1 or 2 arduinos connected
async all(devices) {
async all(serials) {
let c = {};
let p = {};
let l = {};
let type;
let device;
let d;
let cs = {};
let ps = {};
let capper = {};
let checklist = [];
let exposure;
let parts;
this.connected = {
projector: false,
camera: false,
@ -444,16 +454,16 @@ class Devices {
projector_second: false,
capper: false
};
for (let device of devices) {
for (let serial of serials) {
try {
type = await this.distinguish(device);
device = await this.distinguish(serial);
}
catch (err) {
this.log.error('Error distinguishing device', err);
throw err;
}
try {
await this.connectDevice(device, type);
await this.connectDevice(device, serial);
}
catch (err) {
this.log.error('Error connecting to device', err);
@ -464,10 +474,28 @@ class Devices {
if (!this.connected.projector) {
await this.fakeProjector();
}
else if (this.arduino.hasState['projector']) {
p.state = true;
}
p.arduino = this.connected.projector;
if (!this.connected.camera) {
await this.fakeCamera();
}
else if (this.arduino.hasState['camera']) {
if (device.indexOf('camera') !== -1) {
parts = this.arduino.stateStr[device].split('G');
if (parts.length > 1) {
parts = parts[1].split('H');
exposure = parseInt(parts[0]);
if (!isNaN(exposure)) {
this.log.info(`Timing for [${device}] = ${exposure}`);
this.ui.send('timing', { c: 'c', ms: exposure });
}
}
}
c.state = true;
c.exposure = true;
}
c.arduino = this.connected.camera;
if (!this.connected.light) {
await this.fakeLight();
@ -485,31 +513,33 @@ class Devices {
if (this.settings.state.camera && this.settings.state.camera.intval) {
c.intval = this.settings.state.camera.intval;
}
//console.dir(this.arduino.alias);
//console.dir(this.arduino.serial);
return this.ready(p, c, l, cs, ps, capper);
}
/**
*
**/
remember(which, device, type) {
*
**/
remember(device, serial, type) {
let deviceEntry;
const match = this.settings.state.devices.filter((dev) => {
if (dev[which] && dev[which] === device) {
if (dev[device] && dev[device] === serial) {
return dev;
}
});
if (match.length === 0) {
deviceEntry = {
type
device,
serial
};
deviceEntry[which] = device;
this.settings.state.devices.push(deviceEntry);
this.settings.update('devices', this.settings.state.devices);
this.settings.save();
}
}
/**
*
**/
*
**/
ready(projector, camera, light, camera_second, projector_second, capper) {
let args = {
camera,

File diff suppressed because one or more lines are too long

View File

@ -64,7 +64,7 @@ class Light {
}
await delay_1.delay(1);
try {
this.arduino.string(this.id, str);
this.arduino.sendString(this.id, str);
}
catch (err) {
this.log.error('Error sending light string', err);

View File

@ -1 +1 @@
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/light/index.ts"],"names":[],"mappings":"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"}
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/light/index.ts"],"names":[],"mappings":"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"}

View File

@ -59,6 +59,7 @@ class Projector {
this.log.error(`Error setting ${this.id} direction`, err);
}
}
console.dir(ms);
return await this.end(cmd, id, ms);
}
/**
@ -166,7 +167,7 @@ class Projector {
}
message += ` ${ms}ms`;
this.log.info(message, 'PROJECTOR');
return await this.ui.send(this.id, { cmd: cmd, id: id, ms: ms });
return await this.ui.send(this.id, { cmd, id, ms });
}
}
module.exports = function (arduino, cfg, ui, filmout, second) {

File diff suppressed because one or more lines are too long

View File

@ -1,7 +1,11 @@
'use strict';
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const Log = require("log");
const electron_1 = require("electron");
const delay_1 = __importDefault(require("delay"));
/** @module lib/sequencer **/
let seq;
class Sequencer {
@ -160,7 +164,7 @@ class Sequencer {
}
//UI initiates pause, not planned
while (this.paused) {
await delay(42);
await delay_1.default(42);
}
if (typeof this.arr[y] === 'undefined') {
continue;

File diff suppressed because one or more lines are too long

View File

@ -1,4 +1,4 @@
"use strict";
'use strict';
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
@ -10,7 +10,7 @@ const path_1 = require("path");
const uuid_1 = require("uuid");
const Log = require("log");
class Server {
constructor() {
constructor(uiInput) {
this.id = 'server';
this.isActive = false;
this.templates = [
@ -29,6 +29,7 @@ class Server {
this.queue = {};
this.intervalPeriod = 10000; //10 sec
this.init();
this.ui = uiInput;
}
async init() {
this.log = await Log({ label: this.id });
@ -59,8 +60,9 @@ class Server {
this.log.error(err);
return;
}
this.wss.on('connection', async function (ws) {
ws.on("message", function (data) {
this.wss.on('connection', async function (ws, req) {
const address = req.socket.remoteAddress;
ws.on('message', function (data) {
let obj = JSON.parse(data);
//this.log.info(data)
if (obj.id && this.queue[obj.id]) {
@ -73,9 +75,11 @@ class Server {
}.bind(this));
ws.on('close', function () {
this.log.info('Client disconnected');
this.notify('Client disconnected', `No longer forwarding digital display to client ${address}`);
}.bind(this));
await this.cmd(ws, 'mcopy');
this.log.info('Client connected');
this.notify('Client connected', `Forwarding digital display to client: ${address}`);
}.bind(this));
this.log.info(`Websocket server started!`);
this.log.info(`WSS [ ws://localhost:${this.wsPort} ]`);
@ -190,8 +194,11 @@ class Server {
//setTimeout() ?
}.bind(this));
}
notify(title, message) {
this.ui.send('gui', { notify: { title, message } });
}
}
module.exports = function () {
return new Server();
module.exports = function (ui) {
return new Server(ui);
};
//# sourceMappingURL=index.js.map

File diff suppressed because one or more lines are too long

View File

@ -81,7 +81,7 @@ cam.end = function (c, id, ms) {
gui.counterUpdate('cam2', cam.second.pos);
}
timing.update(c, ms);
gui.counterUpdate('cam', cam.pos)
gui.counterUpdate('cam', cam.pos);
if (typeof cam.queue[id] !== 'undefined') {
if (typeof cam.queue[id].callback !== 'undefined') {
cam.queue[id].callback(ms);
@ -90,6 +90,26 @@ cam.end = function (c, id, ms) {
cam.lock = false;
}
};
cam.exposure = async function (exposure) {
var obj = {
id : uuid(),
exposure
};
var change = false;
try {
change = await gui.confirm(`Are you sure you want to set camera exposure to ${exposure}ms?`);
} catch (err) {
log.error(err);
}
if (change) {
log.info(`Setting exposure: ${exposure}`);
ipcRenderer.sendSync(cam.id, obj);
} else {
timing.updateUI('#cam_time', timing.data['cam']);
}
}
cam.listen = function () {
'use strict';
ipcRenderer.on(cam.id, function (event, arg) {

View File

@ -33,14 +33,9 @@ class Devices {
let devs = [];
let notify = 'Connected to ';
let p;
//@ts-ignore
yield delay(1000);
try {
gui.spinner(false);
gui.overlay(false);
}
catch (err) {
log.error(err);
if (arg.camera && arg.camera.exposure) {
$('#submit_cam_time').removeClass('hide');
$('#cam_time').removeAttr('readonly');
}
for (let i in arg) {
devs.push(arg[i].arduino);
@ -106,6 +101,15 @@ class Devices {
grid.state(0);
grid.state(1);
seq.stats();
//@ts-ignore
yield delay(1000);
try {
gui.spinner(false);
gui.overlay(false);
}
catch (err) {
log.error(err);
}
return event.returnValue = true;
});
}

File diff suppressed because one or more lines are too long

View File

@ -1,267 +1,293 @@
/* jslint esversion: 6*/
const gui = {};
//GUI
gui.init = function () {
gui.version();
'use strict';
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
gui.fmtZero = function (val, len) {
'use strict';
const raw = val;
let str = val + '';
let output = '';
if (raw < 0) {
output = '-' + Array(len - (str.length - 1)).join('0') + str.replace('-', '');
} else {
if (str.length < len) {
output = Array(len - str.length).join('0') + str;
} else if (str.length >= len) {
str = parseInt(str) + '';
output = Array(len - str.length).join('0') + str;
}
}
return output;
};
gui.counterFormat = function (t, normal, prevent) {
'use strict';
const raw = t.value;
t.value = gui.fmtZero(raw, 6);
if (typeof normal !== 'undefined' && parseInt(raw) !== normal) {
$(t).addClass('changed');
} else {
$(t).removeClass('changed');
}
};
gui.counterUpdate = function (which, raw) {
'use strict';
const formattedVal = gui.fmtZero(raw, 6);
$(`.${which} .count`).val(formattedVal);
};
gui.notifierWorking = true;
gui.notify = function (title, message) {
'use strict';
if (!gui.notifierWorking) {
return true;
}
return new Promise((resolve, reject) => {
try {
notifier.notify({
title: title,
message: message,
//icon: path.join(__dirname, 'coulson.jpg'), // Absolute path (doesn't work on balloons)
sound: true, // Only Notification Center or Windows Toasters
wait: true // Wait with callback, until user action is taken against notification
}, function (err, response) {
// Response is response from notification
if (err) {
gui.notifierWorking = false;
log.error(`Error with notification`, err);
return reject(err);
}
return resolve(true);
});
} catch (err) {
gui.notifierWorking = false;
//notify-send is not found
//determine an alternate for raspian
//this feels like a hack
}
});
};
gui.updateCam = async function (t) {
'use strict';
const val = t.value;
let change;
if (parseInt(val) === cam.pos) {
return false;
}
change = await gui.confirm(`Are you sure you want to set camera counter to ${val}?`);
if (change) {
cam.pos = parseInt(val);
gui.updateState();
} else {
t.value = cam.pos;
gui.counterFormat(t);
}
};
gui.updateCam2 = async function (t) {
'use strict';
const val = t.value;
let change;
if (parseInt(val) === cam.pos) {
return false;
}
change = await gui.confirm(`Are you sure you want to set second camera counter to ${val}?`);
if (change) {
cam.second.pos = parseInt(val);
gui.updateState();
} else {
t.value = cam.second.pos;
gui.counterFormat(t);
}
};
gui.updateProj = async function (t) {
'use strict';
const val = t.value;
let change;
if (parseInt(val) === proj.pos) {
return false;
}
change = await gui.confirm(`Are you sure you want to set projector counter to ${val}?`);
if (change) {
proj.pos = parseInt(val);
gui.updateState();
} else {
t.value = proj.pos;
gui.counterFormat(t);
}
proj.setValue(t.value);
};
gui.updateProj2 = async function (t) {
'use strict';
const val = t.value;
let change;
if (parseInt(val) === proj.second.pos) {
return false;
}
change = await gui.confirm(`Are you sure you want to set second projector counter to ${val}?`);
if (change) {
proj.second.pos = parseInt(val);
gui.updateState();
} else {
t.value = proj.second.pos;
gui.counterFormat(t);
}
proj.setValue(t.value);
};
gui.updateState = function () {
'use strict';
const cpos = cam.pos;
const ppos = proj.pos;
const p2pos = proj.second.pos;
const c2pos = cam.second.pos;
$('#seq_cam_count').val(cpos).change();
$('#seq_proj_count').val(ppos).change();
$('#seq_cam_count_2').val(cpos).change();
$('#seq_proj_count_2').val(ppos).change();
$('#seq_cam_2_count').val(c2pos).change();
$('#seq_proj_2_count').val(p2pos).change();
$('#seq_cam_2_count_2').val(c2pos).change();
$('#seq_proj_2_count_2').val(p2pos).change();
};
gui.spinnerCfg = {
lines: 11, // The number of lines to draw
length: 15, // The length of each line
width: 7, // The line thickness
radius: 20, // The radius of the inner circle
corners: 1, // Corner roundness (0..1)
rotate: 0, // The rotation offset
direction: 1, // 1: clockwise, -1: counterclockwise
color: '#F2F2F1', // #rgb or #rrggbb or array of colors
speed: 1, // Rounds per second
trail: 60, // Afterglow percentage
shadow: true, // Whether to render a shadow
hwaccel: true, // Whether to use hardware acceleration
className: 'spinner', // The CSS class to assign to the spinner
zIndex: 2e9, // The z-index (defaults to 2000000000)
top: '50%', // Top position relative to parent
left: '50%' // Left position relative to parent
};
gui.spinner = function (state, msg, progress, cancel) {
'use strict';
let target;
let spinner;
if (msg && msg !== '') {
gui.spinnerMsg(msg);
}
if (state && !$('#spinner').hasClass('created')) {
target = document.getElementById('spinner');
spinner = new Spinner(gui.spinnerCfg).spin(target);
$('#spinnerProgress').hide();
$('#spinner').addClass('created');
} else if (state) {
$('#spinner').show();
} else if (!state) {
$('#spinner').hide();
gui.spinnerMsg('');
}
if (progress) {
$('#spinnerProgress').show();
} else {
$('#spinnerProgress').hide();
}
if (cancel) {
$('#spinnerCancel').show();
} else {
$('#spinnerCancel').hide();
}
};
gui.spinnerMsg = function (msg) {
'use strict';
$('#spinnerMsg').text(msg);
};
gui.overlay = function (state) {
'use strict';
if (state) {
$('#overlay').show();
} else {
$('#overlay').hide();
}
};
gui.info = async function (title, message) {
'use strict';
const config = {
type : 'info',
buttons : ['Ok'],
title: title,
message : message
};
return dialog.showMessageBox(config);
};
gui.confirm = async function (message, cancel = 'Cancel') {
const config = {
buttons : ['Yes', cancel],
message
}
const res = await dialog.showMessageBox(config);
return res.response === 0;
};
gui.choice = async function (message, choices) {
const config = {
buttons : choices,
defaultId : 0,
message
}
const res = await dialog.showMessageBox(config);
return res.response;
};
gui.warn = async function (title, message) {
'use strict';
const config = {
type : 'warning',
buttons : ['Ok'],
title: title,
message : message
};
return dialog.showMessageBox(config);
};
gui.error = function () {};
gui.version = function () {
$('#version').text(PACKAGE.version);
let gui;
class GUI {
constructor() {
this.id = 'gui';
this.notifierWorking = true;
this.spinnerCfg = {
lines: 11,
length: 15,
width: 7,
radius: 20,
corners: 1,
rotate: 0,
direction: 1,
color: '#F2F2F1',
speed: 1,
trail: 60,
shadow: true,
hwaccel: true,
className: 'spinner',
zIndex: 2e9,
top: '50%',
left: '50%' // Left position relative to parent
};
}
init() {
this.version();
this.listen();
}
listen() {
ipcRenderer.on(this.id, this.listener.bind(this));
}
listener(event, arg) {
if (arg.notify) {
this.notify(arg.notify.title, arg.notify.message);
}
}
fmtZero(val, len) {
const raw = val;
let str = val + '';
let output = '';
if (raw < 0) {
output = '-' + Array(len - (str.length - 1)).join('0') + str.replace('-', '');
}
else {
if (str.length < len) {
output = Array(len - str.length).join('0') + str;
}
else if (str.length >= len) {
str = parseInt(str) + '';
output = Array(len - str.length).join('0') + str;
}
}
return output;
}
counterFormat(t, normal = null) {
const raw = t.value;
t.value = gui.fmtZero(raw, 6);
if (typeof normal !== 'undefined' && parseInt(raw) !== normal) {
$(t).addClass('changed');
}
else {
$(t).removeClass('changed');
}
}
counterUpdate(which, raw) {
const formattedVal = this.fmtZero(raw, 6);
$(`.${which} .count`).val(formattedVal);
}
notify(title, message) {
const config = {
title,
message,
//icon: path.join(__dirname, 'coulson.jpg'), // Absolute path (doesn't work on balloons)
sound: true,
wait: true // Wait with callback, until user action is taken against notification
};
if (!this.notifierWorking) {
return new Promise((resolve, reject) => { return resolve(true); });
}
return new Promise((resolve, reject) => {
try {
notifier.notify(config, function (err, response) {
// Response is response from notification
if (err) {
this.notifierWorking = false;
log.error(`Error with notification`, err);
return reject(err);
}
return resolve(true);
}.bind(this));
}
catch (err) {
this.notifierWorking = false;
//notify-send is not found
//determine an alternate for raspian
//this feels like a hack
}
});
}
updateCam(t) {
return __awaiter(this, void 0, void 0, function* () {
const val = t.value;
let change;
if (parseInt(val) === cam.pos) {
return false;
}
change = yield this.confirm(`Are you sure you want to set camera counter to ${val}?`);
if (change) {
cam.pos = parseInt(val);
this.updateState();
}
else {
t.value = cam.pos;
this.counterFormat(t);
}
});
}
updateCam2(t) {
return __awaiter(this, void 0, void 0, function* () {
const val = t.value;
let change;
if (parseInt(val) === cam.pos) {
return false;
}
change = yield this.confirm(`Are you sure you want to set second camera counter to ${val}?`);
if (change) {
cam.second.pos = parseInt(val);
this.updateState();
}
else {
t.value = cam.second.pos;
this.counterFormat(t);
}
});
}
updateProj(t) {
return __awaiter(this, void 0, void 0, function* () {
const val = t.value;
let change;
if (parseInt(val) === proj.pos) {
return false;
}
change = yield this.confirm(`Are you sure you want to set projector counter to ${val}?`);
if (change) {
proj.pos = parseInt(val);
this.updateState();
}
else {
t.value = proj.pos;
this.counterFormat(t);
}
proj.setValue(t.value);
});
}
updateProj2(t) {
return __awaiter(this, void 0, void 0, function* () {
const val = t.value;
let change;
if (parseInt(val) === proj.second.pos) {
return false;
}
change = yield this.confirm(`Are you sure you want to set second projector counter to ${val}?`);
if (change) {
proj.second.pos = parseInt(val);
this.updateState();
}
else {
t.value = proj.second.pos;
this.counterFormat(t);
}
proj.setValue(t.value);
});
}
updateState() {
const cpos = cam.pos;
const ppos = proj.pos;
const p2pos = proj.second.pos;
const c2pos = cam.second.pos;
$('#seq_cam_count').val(cpos).change();
$('#seq_proj_count').val(ppos).change();
$('#seq_cam_count_2').val(cpos).change();
$('#seq_proj_count_2').val(ppos).change();
$('#seq_cam_2_count').val(c2pos).change();
$('#seq_proj_2_count').val(p2pos).change();
$('#seq_cam_2_count_2').val(c2pos).change();
$('#seq_proj_2_count_2').val(p2pos).change();
}
spinner(state, msg = null, progress = false, cancel = false) {
let target;
let spinner;
if (msg && msg !== '') {
this.spinnerMsg(msg);
}
if (state && !$('#spinner').hasClass('created')) {
target = document.getElementById('spinner');
spinner = new Spinner(this.spinnerCfg).spin(target);
$('#spinnerProgress').hide();
$('#spinner').addClass('created');
}
else if (state) {
$('#spinner').show();
}
else if (!state) {
$('#spinner').hide();
this.spinnerMsg('');
}
if (progress) {
$('#spinnerProgress').show();
}
else {
$('#spinnerProgress').hide();
}
if (cancel) {
$('#spinnerCancel').show();
}
else {
$('#spinnerCancel').hide();
}
}
spinnerMsg(msg) {
$('#spinnerMsg').text(msg);
}
overlay(state) {
if (state) {
$('#overlay').show();
}
else {
$('#overlay').hide();
}
}
info(title, message) {
return __awaiter(this, void 0, void 0, function* () {
const config = {
type: 'info',
buttons: ['Ok'],
title: title,
message: message
};
return dialog.showMessageBox(config);
});
}
confirm(message, cancel = 'Cancel') {
return __awaiter(this, void 0, void 0, function* () {
const config = {
buttons: ['Yes', cancel],
message
};
const res = yield dialog.showMessageBox(config);
return res.response === 0;
});
}
choice(message, choices) {
return __awaiter(this, void 0, void 0, function* () {
const config = {
buttons: choices,
defaultId: 0,
message
};
const res = yield dialog.showMessageBox(config);
return res.response;
});
}
warn(title, message) {
return __awaiter(this, void 0, void 0, function* () {
const config = {
type: 'warning',
buttons: ['Ok'],
title,
message
};
return dialog.showMessageBox(config);
});
}
version() {
$('#version').text(PACKAGE.version);
}
error() {
}
}
module.exports = gui;
gui = new GUI();
module.exports = gui;
//# sourceMappingURL=index.js.map

1
app/lib/ui/index.js.map Normal file

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -181,8 +181,6 @@ class Sequence {
continue;
c = step.cmd;
ms += timing.get(c);
ms += cfg.arduino.serialDelay;
ms += cfg.arduino.sequenceDelay;
if (c === cfg.cmd.camera_forward || c === cfg.cmd.black_forward) {
cam_total++;
}

File diff suppressed because one or more lines are too long

View File

@ -33,6 +33,17 @@ class Timing {
'PBPF': 'projs'
};
}
init() {
this.listen();
}
listen() {
ipcRenderer.on('timing', this.timing.bind(this));
}
timing(event, arg) {
if (typeof arg.c !== 'undefined') {
this.update(arg.c, parseInt(arg.ms), true);
}
}
reset(profile) {
const keys = Object.keys(profile);
const cmds = Object.keys(cfg.cmd);
@ -40,7 +51,6 @@ class Timing {
let proj;
let pad;
for (let key of keys) {
console.log(key);
if (key === 'label') {
continue;
}
@ -57,6 +67,7 @@ class Timing {
this.data['cam2'] = cam;
this.data['cams'] = cam;
this.data['black'] = cam + pad;
this.updateUI('#cam_time', cam);
}
else if (key === 'proj') {
proj = 0;
@ -66,17 +77,44 @@ class Timing {
this.data['proj'] = proj;
this.data['proj2'] = proj;
this.data['projs'] = proj;
this.updateUI('#proj_time', proj);
}
}
log.info('reset');
}
restore(timing) {
this.data = timing;
}
//update with rolling average
update(c, ms) {
update(c, ms, force = false) {
let cmd = this.fromArduino[c];
let id;
log.info(c);
log.info(cmd);
if (typeof cmd !== 'undefined' && typeof this.data[cmd] !== 'undefined') {
this.data[cmd] = Math.round((this.data[cmd] + ms) / 2);
if (force) {
log.info(`Forcing update of timing, ${ms}`);
this.data[cmd] = ms;
}
else {
this.data[cmd] = Math.round((this.data[cmd] + ms) / 2);
}
id = `#${cmd}_time`;
this.updateUI(id, this.data[cmd]);
}
else if (typeof cmd !== 'undefined' && force) {
//first update
setTimeout(function () {
log.info(`Forcing update of timing, ${ms}`);
this.data[cmd] = ms;
id = `#${cmd}_time`;
this.updateUI(id, this.data[cmd]);
}.bind(this), 5000);
}
}
updateUI(id, ms) {
if ($(id).length) {
$(id).val(ms);
}
}
//get current value

View File

@ -1 +1 @@
{"version":3,"file":"timing.js","sourceRoot":"","sources":["../../src/lib/ui/timing.ts"],"names":[],"mappings":"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"}
{"version":3,"file":"timing.js","sourceRoot":"","sources":["../../src/lib/ui/timing.ts"],"names":[],"mappings":"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"}

View File

@ -117,7 +117,7 @@ var init = async function () {
log.error('Error enumerating connected devices', err)
}
server = require('server')()
server = require('server')(mainWindow.webContents)
light = require('light')(arduino, cfg, mainWindow.webContents)
filmout = require('filmout')(display, server, ffmpeg, ffprobe, mainWindow.webContents, light)
cam = require('cam')(arduino, cfg, mainWindow.webContents, filmout)

2
app/package-lock.json generated
View File

@ -6,7 +6,7 @@
"packages": {
"": {
"name": "mcopy-app",
"version": "1.7.7",
"version": "1.7.21",
"hasInstallScript": true,
"license": "MIT",
"dependencies": {

View File

@ -57,4 +57,5 @@ async function init () {
seq.init();
capper.init();
alertObj.init();
timing.init();
};

View File

@ -2,7 +2,6 @@
/// <reference path ="jquery.d.ts"/>
let devices : Devices;
class Devices {
@ -29,15 +28,12 @@ class Devices {
let devs : any[] = [];
let notify : string = 'Connected to ';
let p : any;
//@ts-ignore
await delay(1000);
try {
gui.spinner(false);
gui.overlay(false);
} catch (err) {
log.error(err);
if (arg.camera && arg.camera.exposure) {
$('#submit_cam_time').removeClass('hide');
$('#cam_time').removeAttr('readonly');
}
for (let i in arg) {
devs.push(arg[i].arduino);
if (arg[i].arduino && arg[i].arduino !== '/dev/fake') {
@ -57,7 +53,7 @@ class Devices {
if (notify !== 'Connected to ') {
gui.notify('DEVICES', notify);
} else {
gui.notify('DEVICES', 'Connected to mock devices')
gui.notify('DEVICES', 'Connected to mock devices');
}
if (devs.length > 0) {
@ -105,12 +101,22 @@ class Devices {
grid.state(1);
seq.stats();
//@ts-ignore
await delay(1000);
try {
gui.spinner(false);
gui.overlay(false);
} catch (err) {
log.error(err);
}
return event.returnValue = true;
}
profiles () {
const keys : string[] = Object.keys(cfg.profiles);
const elem : any = $('#profile')
const elem : any = $('#profile');
let opt;
elem.empty();
for (let key of keys) {

306
app/src/lib/ui/index.ts Normal file
View File

@ -0,0 +1,306 @@
/* jslint esversion: 6*/
'use strict';
/// <reference path ="jquery.d.ts"/>
declare var cam : any;
declare var proj : any;
declare var notifier : any;
declare var PACKAGE : any;
declare var Spinner : any;
declare var dialog : any;
let gui : GUI;
class GUI {
private id : string = 'gui';
private notifierWorking : boolean = true;
private spinnerCfg : any= {
lines: 11, // The number of lines to draw
length: 15, // The length of each line
width: 7, // The line thickness
radius: 20, // The radius of the inner circle
corners: 1, // Corner roundness (0..1)
rotate: 0, // The rotation offset
direction: 1, // 1: clockwise, -1: counterclockwise
color: '#F2F2F1', // #rgb or #rrggbb or array of colors
speed: 1, // Rounds per second
trail: 60, // Afterglow percentage
shadow: true, // Whether to render a shadow
hwaccel: true, // Whether to use hardware acceleration
className: 'spinner', // The CSS class to assign to the spinner
zIndex: 2e9, // The z-index (defaults to 2000000000)
top: '50%', // Top position relative to parent
left: '50%' // Left position relative to parent
};
constructor () {
}
public init () {
this.version();
this.listen();
}
private listen() {
ipcRenderer.on(this.id, this.listener.bind(this));
}
private listener (event : any, arg : any) {
if (arg.notify) {
this.notify(arg.notify.title, arg.notify.message);
}
}
public fmtZero (val : any, len : number) : string {
const raw : number = val;
let str : string = val + '';
let output : string = '';
if (raw < 0) {
output = '-' + Array(len - (str.length - 1)).join('0') + str.replace('-', '');
} else {
if (str.length < len) {
output = Array(len - str.length).join('0') + str;
} else if (str.length >= len) {
str = parseInt(str) + '';
output = Array(len - str.length).join('0') + str;
}
}
return output;
}
counterFormat (t : HTMLInputElement, normal : number = null) {
const raw : string = t.value;
t.value = gui.fmtZero(raw, 6);
if (typeof normal !== 'undefined' && parseInt(raw) !== normal) {
$(t).addClass('changed');
} else {
$(t).removeClass('changed');
}
}
counterUpdate (which : string, raw : number) {
const formattedVal : string = this.fmtZero(raw, 6);
$(`.${which} .count`).val(formattedVal);
}
public notify (title : string, message : string) : Promise<boolean> {
const config : any = {
title,
message,
//icon: path.join(__dirname, 'coulson.jpg'), // Absolute path (doesn't work on balloons)
sound: true, // Only Notification Center or Windows Toasters
wait: true // Wait with callback, until user action is taken against notification
};
if (!this.notifierWorking) {
return new Promise((resolve, reject) => { return resolve(true); })
}
return new Promise((resolve, reject) => {
try {
notifier.notify(config,
function (err : Error, response : any) {
// Response is response from notification
if (err) {
this.notifierWorking = false;
log.error(`Error with notification`, err);
return reject(err);
}
return resolve(true);
}.bind(this));
} catch (err) {
this.notifierWorking = false;
//notify-send is not found
//determine an alternate for raspian
//this feels like a hack
}
});
}
public async updateCam (t : HTMLInputElement) {
const val : string = t.value;
let change : boolean;
if (parseInt(val) === cam.pos) {
return false;
}
change = await this.confirm(`Are you sure you want to set camera counter to ${val}?`);
if (change) {
cam.pos = parseInt(val);
this.updateState();
} else {
t.value = cam.pos;
this.counterFormat(t);
}
}
async updateCam2 (t : HTMLInputElement) {
const val : string = t.value;
let change : boolean;
if (parseInt(val) === cam.pos) {
return false;
}
change = await this.confirm(`Are you sure you want to set second camera counter to ${val}?`);
if (change) {
cam.second.pos = parseInt(val);
this.updateState();
} else {
t.value = cam.second.pos;
this.counterFormat(t);
}
}
async updateProj (t : HTMLInputElement) {
const val : string = t.value;
let change : boolean;
if (parseInt(val) === proj.pos) {
return false;
}
change = await this.confirm(`Are you sure you want to set projector counter to ${val}?`);
if (change) {
proj.pos = parseInt(val);
this.updateState();
} else {
t.value = proj.pos;
this.counterFormat(t);
}
proj.setValue(t.value);
}
async updateProj2 (t : HTMLInputElement) {
const val : string = t.value;
let change : boolean;
if (parseInt(val) === proj.second.pos) {
return false;
}
change = await this.confirm(`Are you sure you want to set second projector counter to ${val}?`);
if (change) {
proj.second.pos = parseInt(val);
this.updateState();
} else {
t.value = proj.second.pos;
this.counterFormat(t);
}
proj.setValue(t.value);
}
public updateState () {
const cpos : number = cam.pos;
const ppos : number = proj.pos;
const p2pos : number = proj.second.pos;
const c2pos : number = cam.second.pos;
$('#seq_cam_count').val(cpos).change();
$('#seq_proj_count').val(ppos).change();
$('#seq_cam_count_2').val(cpos).change();
$('#seq_proj_count_2').val(ppos).change();
$('#seq_cam_2_count').val(c2pos).change();
$('#seq_proj_2_count').val(p2pos).change();
$('#seq_cam_2_count_2').val(c2pos).change();
$('#seq_proj_2_count_2').val(p2pos).change();
}
public spinner (state : boolean, msg : string = null, progress : boolean = false, cancel : boolean = false) {
let target;
let spinner;
if (msg && msg !== '') {
this.spinnerMsg(msg);
}
if (state && !$('#spinner').hasClass('created')) {
target = document.getElementById('spinner');
spinner = new Spinner(this.spinnerCfg).spin(target);
$('#spinnerProgress').hide();
$('#spinner').addClass('created');
} else if (state) {
$('#spinner').show();
} else if (!state) {
$('#spinner').hide();
this.spinnerMsg('');
}
if (progress) {
$('#spinnerProgress').show();
} else {
$('#spinnerProgress').hide();
}
if (cancel) {
$('#spinnerCancel').show();
} else {
$('#spinnerCancel').hide();
}
}
private spinnerMsg (msg : string) {
$('#spinnerMsg').text(msg);
}
public overlay (state : boolean) {
if (state) {
$('#overlay').show();
} else {
$('#overlay').hide();
}
}
public async info (title : string, message : string) {
const config : any = {
type : 'info',
buttons : ['Ok'],
title: title,
message : message
};
return dialog.showMessageBox(config);
}
async confirm (message : string, cancel : string = 'Cancel') {
const config : any = {
buttons : ['Yes', cancel],
message
}
const res = await dialog.showMessageBox(config);
return res.response === 0;
}
public async choice (message : string, choices : string[]) {
const config : any = {
buttons : choices,
defaultId : 0,
message
}
const res = await dialog.showMessageBox(config);
return res.response;
}
public async warn (title : string, message : string) {
const config : any = {
type : 'warning',
buttons : ['Ok'],
title,
message
};
return dialog.showMessageBox(config);
}
private version () {
$('#version').text(PACKAGE.version);
}
private error () {
}
}
gui = new GUI();
module.exports = gui;

View File

@ -5,7 +5,6 @@
import Mscript from 'mscript';
declare var nav : any;
declare var gui : any;
declare var CodeMirror : any;
declare var mscript : any;
declare var cmd : any;

View File

@ -2,7 +2,6 @@
/// <reference path ="jquery.d.ts"/>
declare var gui : any;
declare var cfg : any;
declare var log : any;
declare var w2popup : any;
@ -215,8 +214,6 @@ class Sequence {
if (!step) continue
c = step.cmd;
ms += timing.get(c);
ms += cfg.arduino.serialDelay;
ms += cfg.arduino.sequenceDelay;
if (c === cfg.cmd.camera_forward || c === cfg.cmd.black_forward) {
cam_total++;

View File

@ -7,9 +7,7 @@ interface TimingData {
}
class Timing {
public data : TimingData = {
}
public data : TimingData = {}
private fromArduino : any = {
'c' : 'cam',
@ -46,6 +44,20 @@ class Timing {
}
public init () {
this.listen();
}
private listen () {
ipcRenderer.on('timing', this.timing.bind(this));
}
private timing (event : any, arg : any) {
if (typeof arg.c !== 'undefined') {
this.update(arg.c, parseInt(arg.ms), true);
}
}
public reset (profile : any) {
const keys : string[] = Object.keys(profile);
const cmds : string[] = Object.keys(cfg.cmd);
@ -66,10 +78,11 @@ class Timing {
pad = (profile['black'].before + profile['black'].after);
}
this.data['cam'] = cam
this.data['cam2'] = cam
this.data['cams'] = cam
this.data['black'] = cam + pad
this.data['cam'] = cam;
this.data['cam2'] = cam;
this.data['cams'] = cam;
this.data['black'] = cam + pad;
this.updateUI('#cam_time', cam);
} else if (key === 'proj') {
proj = 0;
proj += profile[key].time;
@ -78,8 +91,10 @@ class Timing {
this.data['proj'] = proj;
this.data['proj2'] = proj;
this.data['projs'] = proj;
this.updateUI('#proj_time', proj);
}
}
log.info('reset')
}
public restore (timing : TimingData) {
@ -87,10 +102,34 @@ class Timing {
}
//update with rolling average
public update (c : string, ms : number) {
public update (c : string, ms : number, force : boolean = false) {
let cmd : string = this.fromArduino[c];
let id : string;
log.info(c)
log.info(cmd)
if (typeof cmd !== 'undefined' && typeof this.data[cmd] !== 'undefined') {
this.data[cmd] = Math.round((this.data[cmd] + ms) / 2);
if (force) {
log.info(`Forcing update of timing, ${ms}`);
this.data[cmd] = ms;
} else {
this.data[cmd] = Math.round((this.data[cmd] + ms) / 2);
}
id = `#${cmd}_time`;
this.updateUI(id, this.data[cmd]);
} else if (typeof cmd !== 'undefined' && force) {
//first update
setTimeout(function () {
log.info(`Forcing update of timing, ${ms}`);
this.data[cmd] = ms;
id = `#${cmd}_time`;
this.updateUI(id, this.data[cmd]);
}.bind(this), 5000);
}
}
public updateUI (id : string, ms : number) {
if ($(id).length) {
$(id).val(ms);
}
}

View File

@ -186,7 +186,10 @@
"capper_on": "A",
"capper_off": "B",
"takeup_forward": "D",
"takeup_backward": "E"
"takeup_backward": "F",
"error" : "E",
"camera_exposure" : "G",
"state" : "H"
}
}
}

View File

@ -0,0 +1,176 @@
/*!
* @file Adafruit_Pixie.cpp
*
* @mainpage Arduino library for controlling Pixie - a 3W chainable LED.
*
* @section intro_sec Introduction
*
* Arduino library for controlling Pixie - a 3W chainable LED
*
* Check it out over at https://www.adafruit.com/products/2741
*
* Adafruit invests time and resources providing this open source code,
* please support Adafruit and open-source hardware by purchasing
* products from Adafruit!
*
* @section author Author
*
* Ytai Ben-Tsvi/Limor Fried (Adafruit Industries)
*
* @section license License
*
* BSD (see license.txt)
*/
#include "Adafruit_Pixie.h"
/*!
* @brief Instantiates a new Pixie class
* @param n
* Number of Pixies in the strip
* @param *s
* Pointer to hardware or software serial port
*/
Adafruit_Pixie::Adafruit_Pixie(uint16_t n, Stream *s)
: numLEDs(n), brightness(0), pixels(NULL), endTime(0), stream(s) {
if ((pixels = (uint8_t *)malloc(n * 3))) {
memset(pixels, 0, n * 3);
}
}
Adafruit_Pixie::~Adafruit_Pixie() {
if (pixels)
free(pixels);
}
// No begin() function; instead, just call ser.begin(115200) where 'ser'
// is the previously-opened hardware- or software-serial port for output.
/*!
* @brief Light up the LEDs!
*/
void Adafruit_Pixie::show() {
if (pixels) {
uint16_t n3 = numLEDs * 3;
while (!canShow())
; // Wait for 1ms elapsed since prior call
if (!brightness) { // No brightness adjust, output full blast
stream->write(pixels, n3);
} else { // Scale back brightness for every pixel R,G,B:
uint16_t i, b16 = (uint16_t)brightness;
for (i = 0; i < n3; i++) {
stream->write((pixels[i] * b16) >> 8);
}
}
endTime = micros(); // Save EOD time for latch on next call
}
}
/*!
* @brief Set pixel color from separate R,G,B components:
* @param n
* Pixel index
* @param r
* Red value (0-255)
* @param g
* Green value (0-255)
* @param b
* Green Blue (0-255)
*/
void Adafruit_Pixie::setPixelColor(uint16_t n, uint8_t r, uint8_t g,
uint8_t b) {
if (n < numLEDs) {
uint8_t *p = &pixels[n * 3];
p[0] = r;
p[1] = g;
p[2] = b;
}
}
/*!
* @brief Set pixel color from "packed" 32-bit RGB color
* @param n
* Pixel index
* @param c
* "packed" 32-bit RGB color
*/
void Adafruit_Pixie::setPixelColor(uint16_t n, uint32_t c) {
if (n < numLEDs) {
uint8_t r = (uint8_t)(c >> 16), g = (uint8_t)(c >> 8), b = (uint8_t)c,
*p = &pixels[n * 3];
p[0] = r;
p[1] = g;
p[2] = b;
}
}
/*!
* @brief Convert separate R,G,B into packed 32-bit RGB color.
* Packed format is always RGB, regardless of LED strand color order.
* @param r
* Red value (0-255)
* @param g
* Green value (0-255)
* @param b
* Green Blue (0-255)
* @return "Packed" 32-bit RGB color
*/
uint32_t Adafruit_Pixie::Color(uint8_t r, uint8_t g, uint8_t b) {
return ((uint32_t)r << 16) | ((uint32_t)g << 8) | b;
}
/*!
* @brief Query color from previously-set pixel (returns packed 32-bit RGB
* value)
* @param n
* Pixel index
* @return "Packed" 32-bit RGB color
*/
uint32_t Adafruit_Pixie::getPixelColor(uint16_t n) const {
if (n < numLEDs) {
uint8_t *p = &pixels[n * 3];
return ((uint32_t)p[0] << 16) | ((uint32_t)p[1] << 8) | (uint32_t)p[2];
} else {
return 0; // Out of bounds, return no color.
}
}
/*!
* @brief Sets the brightness value
* @param b
* Brightness value (0-255)
*/
void Adafruit_Pixie::setBrightness(uint8_t b) {
// Stored brightness value is different than what's passed. This
// optimizes the actual scaling math later, allowing a fast 8x8-bit
// multiply and taking the MSB. 'brightness' is a uint8_t, adding 1
// here may (intentionally) roll over...so 0 = max brightness (color
// values are interpreted literally; no scaling), 1 = min brightness
// (off), 255 = just below max brightness.
brightness = b + 1;
}
/*!
* @brief Return the brightness value
* @return The brightness value
*/
uint8_t Adafruit_Pixie::getBrightness() const {
return brightness - 1; // Reverse above operation
}
/*!
* @brief Returns the pixel colors
* @return Pixel colors
*/
uint8_t *Adafruit_Pixie::getPixels() const { return pixels; };
/*!
* @brief Returns the number of the pixels
* @return The number of the pixels
*/
uint16_t Adafruit_Pixie::numPixels() const { return numLEDs; };
/*!
* @brief Clears the pixels
*/
void Adafruit_Pixie::clear() { memset(pixels, 0, numLEDs * 3); }

View File

@ -0,0 +1,43 @@
/*!
* @file Adafruit_Pixie.h
*/
#ifndef ADAFRUIT_PIXIE_H
#define ADAFRUIT_PIXIE_H
#include <Arduino.h>
/*!
* @brief Class that stores state and functions for interacting with Adafruit
* Pixie.
*/
class Adafruit_Pixie {
public:
Adafruit_Pixie(uint16_t n, Stream *stream);
~Adafruit_Pixie();
void show();
void setPixelColor(uint16_t n, uint8_t r, uint8_t g, uint8_t b);
void setPixelColor(uint16_t n, uint32_t c);
void setBrightness(uint8_t b);
void clear();
uint8_t getBrightness() const;
uint8_t *getPixels() const;
uint16_t numPixels() const;
static uint32_t Color(uint8_t r, uint8_t g, uint8_t b);
uint32_t getPixelColor(uint16_t n) const;
/*!
* @brief Returns true if enough time has passed to refresh the LEDs
* @return True if enough time has passed to refresh the LEDs
*/
inline bool canShow() { return (micros() - endTime) > 1000L; }
private:
const uint16_t numLEDs; // Number of RGB LEDs in chain
uint8_t brightness, *pixels; // Holds LED color values (3 bytes each)
uint32_t endTime; // Latch timing reference
Stream *stream; // Hardware or software serial port
};
#endif // ADAFRUIT_PIXIE_H

View File

@ -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);
}

View File

@ -0,0 +1,87 @@
#ifndef MCOPY_SERIAL
#define MCOPY_SERIAL
#include <Arduino.h>
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 LIGHT = 'l';
const char LIGHT_IDENTIFIER = 'o';
const char MCOPY_IDENTIFIER = 'm';
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

View File

@ -1,11 +1,13 @@
#include "SoftwareSerial.h"
#include "Adafruit_Pixie.h"
#include "McopySerial.h"
#define NUMPIXELS 1 // Number of Pixies in the strip
#define PIXIEPIN 6 // Pin number for SoftwareSerial output
SoftwareSerial pixieSerial(-1, PIXIEPIN);
Adafruit_Pixie light = Adafruit_Pixie(NUMPIXELS, &pixieSerial);
McopySerial mc;
String color = "000,000,000";
@ -22,60 +24,39 @@ volatile int b = 0;
unsigned long now; //to be compared to stored values every loop
unsigned long light_time;
volatile char cmd = 'z';
const char cmd_light = 'l';
const char cmd_debug = 'd';
const char cmd_connect = 'i';
volatile char cmd_char = 'z';
const int serialDelay = 5;
void setup () {
Serial.begin(57600);
Serial.flush();
Serial.setTimeout(serialDelay);
mc.begin(mc.LIGHT_IDENTIFIER);
pixieSerial.begin(115200); // Pixie REQUIRES this baud rate
light.setPixelColor(0, 0, 0, 0);
light.show();
r = 90;
g = 90;
b = 90;
}
void loop () {
if (Serial.available()) {
/* read the most recent byte */
cmd_char = (char)Serial.read();
}
if (cmd_char != 'z') {
cmd(cmd_char);
cmd_char = 'z';
}
now = millis();
now = millis();
cmd = mc.loop();
if (cmd == mc.LIGHT) {
color = mc.getString();
parseColorString();
mc.confirm(mc.LIGHT);
}
//send light signal to pixie every second
if (now - light_time >= 1000) {
light.setPixelColor(0, r, g, b);
light.show();
light_time = now;
light.setPixelColor(0, r, g, b);
light.show();
light_time = now;
}
}
//
//l - light - followed by String
//
void cmd (char val) {
if (val == cmd_connect) {
Serial.println(cmd_connect);//confirm connection
} else if (val == cmd_light) {
colorString();
Serial.println(cmd_light);//confirm light change
}
}
void colorString () {
while (Serial.available() == 0) {
//Wait for color string
}
color = Serial.readString();
//Serial.println(color);
void parseColorString () {
commaR = color.indexOf(','); //comma trailing R
commaG = color.indexOf(',', commaR + 1);

View File

@ -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);
}

View File

@ -0,0 +1,87 @@
#ifndef MCOPY_SERIAL
#define MCOPY_SERIAL
#include <Arduino.h>
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 LIGHT = 'l';
const char LIGHT_IDENTIFIER = 'o';
const char MCOPY_IDENTIFIER = 'm';
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

View File

@ -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);
}

View File

@ -0,0 +1,87 @@
#ifndef MCOPY_SERIAL
#define MCOPY_SERIAL
#include <Arduino.h>
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 LIGHT = 'l';
const char LIGHT_IDENTIFIER = 'o';
const char MCOPY_IDENTIFIER = 'm';
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

View File

@ -0,0 +1,191 @@
/*
* 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.
* Rrelay module for proj :
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 capacitory
400 Ohm Resistor (50W)
PINS FOR PROJ WIRE
#
1 -
2 -
3 -
4 -
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;
//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_IDENTIFIER);
delay(42);
digitalWrite(LED_FWD, LOW);
digitalWrite(LED_BWD, LOW);
}
void loop () {
now = millis();
if (proj_running) {
proj_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_FORWARD) {
proj_direction(true);
} else if (val == mc.PROJECTOR_BACKWARD) {
proj_direction(false);
} else if (val == mc.PROJECTOR) {
proj_start();
} else if (val == mc.STATE) {
state();
}
}
void proj_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 proj_stop () {
//stop both directions
delay(10);
digitalWrite(PROJECTOR_FWD, LOW);
digitalWrite(PROJECTOR_BWD, LOW);
digitalWrite(LED_FWD, LOW);
digitalWrite(LED_BWD, LOW);
mc.confirm(mc.PROJECTOR);
mc.log("projector()");
proj_running = false;
update_timing(millis() - proj_time);
}
void proj_direction (boolean state) {
proj_dir = state;
if (state) {
mc.confirm(mc.PROJECTOR_FORWARD);
mc.log("proj_direction -> true");
} else {
mc.confirm(mc.PROJECTOR_BACKWARD);
mc.log("proj_direction -> false");
}
}
//LOW=0=CLOSED
//HIGH=1=OPEN
void proj_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?
proj_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);
}

View File

@ -0,0 +1,206 @@
/*
* 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.
* Rrelay module for proj :
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 capacitory
400 Ohm Resistor (50W)
PINS FOR PROJ WIRE
#
1 -
2 -
3 -
4 -
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;
//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_IDENTIFIER);
delay(42);
digitalWrite(LED_FWD, LOW);
digitalWrite(LED_BWD, LOW);
}
void loop () {
now = millis();
if (proj_running) {
proj_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_FORWARD) {
proj_direction(true);
} else if (val == mc.PROJECTOR_BACKWARD) {
proj_direction(false);
} else if (val == mc.PROJECTOR) {
proj_start();
} else if (val == mc.STATE) {
state();
}
}
void proj_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 proj_stop () {
//stop both directions
//delay(10);
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) {
digitalWrite(PROJECTOR_BWD, HIGH);
delay(15);
digitalWrite(PROJECTOR_BWD, LOW);
} else {
digitalWrite(PROJECTOR_FWD, HIGH);
delay(15);
digitalWrite(PROJECTOR_FWD, LOW);
}
}
mc.confirm(mc.PROJECTOR);
mc.log("projector()");
proj_running = false;
update_timing(millis() - proj_time);
delay(10);
mc.log(String(digitalRead(PROJECTOR_MICROSWITCH)));
}
void proj_direction (boolean state) {
proj_dir = state;
if (state) {
mc.confirm(mc.PROJECTOR_FORWARD);
mc.log("proj_direction -> true");
} else {
mc.confirm(mc.PROJECTOR_BACKWARD);
mc.log("proj_direction -> false");
}
}
//LOW=0=CLOSED
//HIGH=1=OPEN
void proj_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?
proj_stop();
} else {
//delay(1); //some smothing value
}
}
void update_timing (int timing) {
if (proj_avg == -1) {
proj_avg = timing;
} else {
proj_avg = (int) round((proj_avg + timing) / 2);
}
mc.log(String(timing) + "ms");
}
void state () {
String stateString = String(mc.CAMERA_EXPOSURE);
stateString += String(proj_avg);
stateString += String(mc.STATE);
mc.print(stateString);
}

View File

@ -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);
}

View File

@ -0,0 +1,87 @@
#ifndef MCOPY_SERIAL
#define MCOPY_SERIAL
#include <Arduino.h>
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 LIGHT = 'l';
const char LIGHT_IDENTIFIER = 'o';
const char MCOPY_IDENTIFIER = 'm';
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

View File

@ -1,6 +1,6 @@
#include <Adafruit_MotorShield.h>
#include "McopySerial.h"
volatile boolean debug_state = true;
volatile boolean cam_dir = true;
volatile boolean running = true;
@ -9,90 +9,58 @@ const int fullRotation = 3 * stepsPerRevolution;
const int openRotationForward = 300;
const int openRotationBackward = 300;
//CAMERA COMMANDS
const char cmd_camera = 'c';
const char cmd_cam_forward = 'e';
const char cmd_cam_backward = 'f';
const char cmd_debug = 'd';
const char cmd_connect = 'i';
volatile char cmd_char = 'z';
const char cmd_mcopy_identifier = 'm';
const char cmd_cam_identifier = 'k';
const int serialDelay = 5;
volatile char cmdChar = 'z';
volatile long now;
volatile long cameraFrame = -1;
Adafruit_MotorShield AFMS = Adafruit_MotorShield();
//Set up for a 200step motor (NEMA 17)
Adafruit_StepperMotor *stepper = AFMS.getStepper(stepsPerRevolution, 2);
McopySerial mc;
void setupMotor () {
//TWBR = ((F_CPU /400000l) - 16) / 2; // Change the i2c clock to 400KHz
if (!AFMS.begin()) { // default frequency 1.6KHz
log("Could not find Motor Shield. Check wiring.");
mc.log("Could not find Motor Shield. Check wiring.");
while (1);
}
log("Motor Shield found.");
mc.log("Motor Shield found.");
stepper->setSpeed(600);
}
void setup() {
Serial.begin(57600);
mc.begin(mc.CAMERA_IDENTIFIER);
setupMotor();
}
void loop() {
if (Serial.available()) {
// read the most recent byte
cmd_char = (char)Serial.read();
}
if (cmd_char != 'z') {
cmd(cmd_char);
cmd_char = 'z';
}
now = millis();
cmdChar = mc.loop();
cmd(cmdChar);
}
void cmd (char val) {
if (val == cmd_debug) {
debug();
} else if (val == cmd_connect) {
connect();
} else if (val == cmd_mcopy_identifier) {
identify();
} else if (val == cmd_cam_forward) {
setDir(true); //explicit
} else if (val == cmd_cam_backward) {
if (val == mc.CAMERA_FORWARD) {
setDir(true);
} else if (val == mc.CAMERA_BACKWARD) {
setDir(false);
} else if (val == cmd_camera) {
} else if (val == mc.CAMERA) {
cam();
} else if (val == mc.STATE) {
state();
}
}
void debug () {
debug_state = true;
Serial.println(cmd_debug);
log("debugging enabled");
}
void connect () {
Serial.println(cmd_connect);
log("connect()");
}
void identify () {
Serial.println(cmd_cam_identifier);
log("identify()");
}
void setDir (boolean dir) {
cam_dir = dir;
if (cam_dir) {
Serial.println(cmd_cam_forward);
log("setDir = true");
mc.confirm(mc.CAMERA_FORWARD);
mc.log("setDir = true");
} else {
Serial.println(cmd_cam_backward);
log("setDir -> false");
mc.confirm(mc.CAMERA_BACKWARD);
mc.log("setDir -> false");
}
}
@ -100,18 +68,27 @@ void cam () {
long startTime = millis();
if (cam_dir) {
stepper->step(fullRotation, FORWARD, DOUBLE);
Serial.println(cmd_cam_forward);
log("cam -> forward");
mc.log("cam() -> forward");
} else {
stepper->step(fullRotation, BACKWARD, DOUBLE);
Serial.println(cmd_cam_backward);
log("cam -> backward");
mc.log("cam() -> backward");
}
log(String(millis() - startTime));
mc.confirm(mc.CAMERA);
timeFrame(startTime);
mc.log(String(cameraFrame));
}
void log (String msg) {
if (debug_state) {
Serial.println(msg);
}
void timeFrame (long startTime) {
if (cameraFrame == -1) {
cameraFrame = millis() - startTime;
} else {
cameraFrame = round((cameraFrame + (millis() - startTime)) / 2);
}
}
void state () {
String stateString = String(mc.CAMERA_EXPOSURE);
stateString += String(cameraFrame);
stateString += String(mc.STATE);
mc.print(stateString);
}

2
ino/mcopy_cam_canon_ble/.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
debug*
bin

View File

@ -0,0 +1,308 @@
// ArduinoNvs.cpp
// Copyright (c) 2018 Sinai RnD
// Copyright (c) 2016-2017 TridentTD
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
#include "ArduinoNvs.h"
ArduinoNvs::ArduinoNvs()
{
}
bool ArduinoNvs::begin(String namespaceNvs)
{
esp_err_t err = nvs_flash_init();
if (err != ESP_OK)
{
DEBUG_PRINTLN("W: NVS. Cannot init flash mem");
if (err != ESP_ERR_NVS_NO_FREE_PAGES)
return false;
// erase and reinit
DEBUG_PRINTLN("NVS. Try reinit the partition");
const esp_partition_t *nvs_partition = esp_partition_find_first(ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_DATA_NVS, NULL);
if (nvs_partition == NULL)
return false;
err = esp_partition_erase_range(nvs_partition, 0, nvs_partition->size);
esp_err_t err = nvs_flash_init();
if (err)
return false;
DEBUG_PRINTLN("NVS. Partition re-formatted");
}
err = nvs_open(namespaceNvs.c_str(), NVS_READWRITE, &_nvs_handle);
if (err != ESP_OK)
return false;
return true;
}
void ArduinoNvs::close()
{
nvs_close(_nvs_handle);
}
bool ArduinoNvs::eraseAll(bool forceCommit)
{
esp_err_t err = nvs_erase_all(_nvs_handle);
if (err != ESP_OK)
return false;
return forceCommit ? commit() : true;
}
bool ArduinoNvs::erase(String key, bool forceCommit)
{
esp_err_t err = nvs_erase_key(_nvs_handle, key.c_str());
if (err != ESP_OK)
return false;
return forceCommit ? commit() : true;
}
bool ArduinoNvs::commit()
{
esp_err_t err = nvs_commit(_nvs_handle);
if (err != ESP_OK)
return false;
return true;
}
bool ArduinoNvs::setInt(String key, uint8_t value, bool forceCommit)
{
esp_err_t err = nvs_set_u8(_nvs_handle, (char *)key.c_str(), value);
if (err != ESP_OK)
return false;
return forceCommit ? commit() : true;
}
bool ArduinoNvs::setInt(String key, int16_t value, bool forceCommit)
{
esp_err_t err = nvs_set_i16(_nvs_handle, (char *)key.c_str(), value);
if (err != ESP_OK)
return false;
return forceCommit ? commit() : true;
}
bool ArduinoNvs::setInt(String key, uint16_t value, bool forceCommit)
{
esp_err_t err = nvs_set_u16(_nvs_handle, (char *)key.c_str(), value);
if (err != ESP_OK)
return false;
return forceCommit ? commit() : true;
}
bool ArduinoNvs::setInt(String key, int32_t value, bool forceCommit)
{
esp_err_t err = nvs_set_i32(_nvs_handle, (char *)key.c_str(), value);
if (err != ESP_OK)
return false;
return forceCommit ? commit() : true;
}
bool ArduinoNvs::setInt(String key, uint32_t value, bool forceCommit)
{
esp_err_t err = nvs_set_u32(_nvs_handle, (char *)key.c_str(), value);
if (err != ESP_OK)
return false;
return forceCommit ? commit() : true;
}
bool ArduinoNvs::setInt(String key, int64_t value, bool forceCommit)
{
esp_err_t err = nvs_set_i64(_nvs_handle, (char *)key.c_str(), value);
if (err != ESP_OK)
return false;
return forceCommit ? commit() : true;
}
bool ArduinoNvs::setInt(String key, uint64_t value, bool forceCommit)
{
esp_err_t err = nvs_set_u64(_nvs_handle, (char *)key.c_str(), value);
if (err != ESP_OK)
return false;
return forceCommit ? commit() : true;
}
bool ArduinoNvs::setString(String key, String value, bool forceCommit)
{
esp_err_t err = nvs_set_str(_nvs_handle, (char *)key.c_str(), value.c_str());
if (err != ESP_OK)
return false;
return forceCommit ? commit() : true;
}
bool ArduinoNvs::setBlob(String key, uint8_t *blob, size_t length, bool forceCommit)
{
DEBUG_PRINTF("ArduinoNvs::setObjct(): set obj addr = [0x%X], length = [%d]\n", (int32_t)blob, length);
if (length == 0)
return false;
esp_err_t err = nvs_set_blob(_nvs_handle, (char *)key.c_str(), blob, length);
if (err)
{
DEBUG_PRINTF("ArduinoNvs::setObjct(): err = [0x%X]\n", err);
return false;
}
return forceCommit ? commit() : true;
}
bool ArduinoNvs::setBlob(String key, std::vector<uint8_t> &blob, bool forceCommit)
{
return setBlob(key, &blob[0], blob.size(), forceCommit);
}
int64_t ArduinoNvs::getInt(String key, int64_t default_value)
{
uint8_t v_u8;
int16_t v_i16;
uint16_t v_u16;
int32_t v_i32;
uint32_t v_u32;
int64_t v_i64;
uint64_t v_u64;
esp_err_t err;
err = nvs_get_u8(_nvs_handle, (char *)key.c_str(), &v_u8);
if (err == ESP_OK)
return (int64_t)v_u8;
err = nvs_get_i16(_nvs_handle, (char *)key.c_str(), &v_i16);
if (err == ESP_OK)
return (int64_t)v_i16;
err = nvs_get_u16(_nvs_handle, (char *)key.c_str(), &v_u16);
if (err == ESP_OK)
return (int64_t)v_u16;
err = nvs_get_i32(_nvs_handle, (char *)key.c_str(), &v_i32);
if (err == ESP_OK)
return (int64_t)v_i32;
err = nvs_get_u32(_nvs_handle, (char *)key.c_str(), &v_u32);
if (err == ESP_OK)
return (int64_t)v_u32;
err = nvs_get_i64(_nvs_handle, (char *)key.c_str(), &v_i64);
if (err == ESP_OK)
return (int64_t)v_i64;
err = nvs_get_u64(_nvs_handle, (char *)key.c_str(), &v_u64);
if (err == ESP_OK)
return (int64_t)v_u64;
return default_value;
}
bool ArduinoNvs::getString(String key, String &res)
{
size_t required_size;
esp_err_t err;
err = nvs_get_str(_nvs_handle, key.c_str(), NULL, &required_size);
if (err)
return false;
char value[required_size];
err = nvs_get_str(_nvs_handle, key.c_str(), value, &required_size);
if (err)
return false;
res = value;
return true;
}
String ArduinoNvs::getString(String key)
{
String res;
bool ok = getString(key, res);
if (!ok)
return String();
return res;
}
size_t ArduinoNvs::getBlobSize(String key)
{
size_t required_size;
esp_err_t err = nvs_get_blob(_nvs_handle, key.c_str(), NULL, &required_size);
if (err)
{
if (err != ESP_ERR_NVS_NOT_FOUND) // key_not_found is not an error, just return size 0
DEBUG_PRINTF("ArduinoNvs::getBlobSize(): err = [0x%X]\n", err);
return 0;
}
return required_size;
}
bool ArduinoNvs::getBlob(String key, uint8_t *blob, size_t length)
{
if (length == 0)
return false;
size_t required_size = getBlobSize(key);
if (required_size == 0)
return false;
if (length < required_size)
return false;
esp_err_t err = nvs_get_blob(_nvs_handle, key.c_str(), blob, &required_size);
if (err)
{
DEBUG_PRINTF("ArduinoNvs::getBlob(): get object err = [0x%X]\n", err);
return false;
}
return true;
}
bool ArduinoNvs::getBlob(String key, std::vector<uint8_t> &blob)
{
size_t required_size = getBlobSize(key);
if (required_size == 0)
return false;
blob.resize(required_size);
esp_err_t err = nvs_get_blob(_nvs_handle, key.c_str(), &blob[0], &required_size);
if (err)
{
DEBUG_PRINTF("ArduinoNvs::getBlob(): get object err = [0x%X]\n", err);
return false;
}
return true;
}
std::vector<uint8_t> ArduinoNvs::getBlob(String key)
{
std::vector<uint8_t> res;
bool ok = getBlob(key, res);
if (!ok)
res.clear();
return res;
}
bool ArduinoNvs::setFloat(String key, float value, bool forceCommit)
{
return setBlob(key, (uint8_t *)&value, sizeof(float), forceCommit);
}
float ArduinoNvs::getFloat(String key, float default_value)
{
std::vector<uint8_t> res(sizeof(float));
if (!getBlob(key, res))
return default_value;
return *(float *)(&res[0]);
}
ArduinoNvs NVS;

View File

@ -0,0 +1,93 @@
// ArduinoNvs.h
// Copyright (c) 2018 Sinai RnD
// Copyright (c) 2016-2017 TridentTD
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
#ifndef __ARDUINO_NVS_H__
#define __ARDUINO_NVS_H__
#include <Arduino.h>
#include <vector>
extern "C" {
#include "esp_partition.h"
#include "esp_err.h"
#include "nvs_flash.h"
#include "nvs.h"
}
#ifndef ARDUINONVS_SILENT
#define ARDUINONVS_SILENT 0
#endif
#if ARDUINONVS_SILENT
#define DEBUG_PRINT(...) { }
#define DEBUG_PRINTLN(...) { }
#define DEBUG_PRINTF(fmt, args...) { }
#else
#define DEBUG_PRINTER Serial
#define DEBUG_PRINT(...) { DEBUG_PRINTER.print(__VA_ARGS__); }
#define DEBUG_PRINTLN(...) { DEBUG_PRINTER.println(__VA_ARGS__); }
#define DEBUG_PRINTF(fmt, args...) { DEBUG_PRINTER.printf(fmt,## args); }
#endif
class ArduinoNvs {
public:
ArduinoNvs();
bool begin(String namespaceNvs = "storage");
void close();
bool eraseAll(bool forceCommit = true);
bool erase(String key, bool forceCommit = true);
bool setInt(String key, uint8_t value, bool forceCommit = true);
bool setInt(String key, int16_t value, bool forceCommit = true);
bool setInt(String key, uint16_t value, bool forceCommit = true);
bool setInt(String key, int32_t value, bool forceCommit = true);
bool setInt(String key, uint32_t value, bool forceCommit = true);
bool setInt(String key, int64_t value, bool forceCommit = true);
bool setInt(String key, uint64_t value, bool forceCommit = true);
bool setFloat(String key, float value, bool forceCommit = true);
bool setString(String key, String value, bool forceCommit = true);
bool setBlob(String key, uint8_t* blob, size_t length, bool forceCommit = true);
bool setBlob(String key, std::vector<uint8_t>& blob, bool forceCommit = true);
int64_t getInt(String key, int64_t default_value = 0); // In case of error, default_value will be returned
float getFloat(String key, float default_value = 0);
bool getString(String key, String& res);
String getString(String key);
size_t getBlobSize(String key); /// Returns the size of the stored blob
bool getBlob(String key, uint8_t* blob, size_t length); /// User should proivde enought memory to store the loaded blob. If length < than required size to store blob, function fails.
bool getBlob(String key, std::vector<uint8_t>& blob);
std::vector<uint8_t> getBlob(String key); /// Less eficient but more simple in usage implemetation of `getBlob()`
bool commit();
protected:
nvs_handle _nvs_handle;
};
extern ArduinoNvs NVS;
#endif

View File

@ -0,0 +1,298 @@
#include "CanonBLERemote.h"
#include <Arduino.h>
#include <BLEDevice.h>
static const char *LOG_TAG = "MySecurity";
advdCallback::advdCallback(BLEUUID service_uuid, bool *ready_to_connect, BLEAddress *address_to_connect)
{
service_uuid_wanted = service_uuid;
pready_to_connect = ready_to_connect;
paddress_to_connect = address_to_connect;
}
void advdCallback::onResult(BLEAdvertisedDevice advertisedDevice)
{
if (advertisedDevice.haveServiceUUID())
{ //Check if device has service UUID available.
if (service_uuid_wanted.equals(advertisedDevice.getServiceUUID()))
{
*paddress_to_connect = advertisedDevice.getAddress();
*pready_to_connect = true;
advertisedDevice.getScan()->stop();
}
}
}
void ConnectivityState::onConnect(BLEClient *pclient)
{
// Serial.println("Device is connected");
connected = true;
}
void ConnectivityState::onDisconnect(BLEClient *pclient)
{
// Serial.println("Device disconnnect");
connected = false;
}
bool ConnectivityState::isConnected()
{
return connected;
}
class SecurityCallback : public BLESecurityCallbacks
{
uint32_t onPassKeyRequest()
{
return 123456;
}
void onPassKeyNotify(uint32_t pass_key)
{
ESP_LOGE(LOG_TAG, "The passkey Notify number:%d", pass_key);
}
bool onConfirmPIN(uint32_t pass_key)
{
ESP_LOGI(LOG_TAG, "The passkey YES/NO number:%d", pass_key);
vTaskDelay(5000);
return true;
}
bool onSecurityRequest()
{
ESP_LOGI(LOG_TAG, "Security Request");
return true;
}
void onAuthenticationComplete(esp_ble_auth_cmpl_t auth_cmpl)
{
if (auth_cmpl.success)
{
ESP_LOGI(LOG_TAG, "remote BD_ADDR:");
esp_log_buffer_hex(LOG_TAG, auth_cmpl.bd_addr, sizeof(auth_cmpl.bd_addr));
ESP_LOGI(LOG_TAG, "address type = %d", auth_cmpl.addr_type);
}
ESP_LOGI(LOG_TAG, "pair status = %s", auth_cmpl.success ? "success" : "fail");
}
};
CanonBLERemote::CanonBLERemote(String name) : SERVICE_UUID("00050000-0000-1000-0000-d8492fffa821"),
PAIRING_SERVICE("00050002-0000-1000-0000-d8492fffa821"),
SHUTTER_CONTROL_SERVICE("00050003-0000-1000-0000-d8492fffa821")
{
device_name = name;
// Add our connection callback for state tracking.
pclient->setClientCallbacks(pconnection_state);
}
void CanonBLERemote::init()
{
BLEDevice::init(device_name.c_str());
BLEDevice::setEncryptionLevel(ESP_BLE_SEC_ENCRYPT_NO_MITM);
BLEDevice::setSecurityCallbacks(new SecurityCallback());
if (nvs.begin())
{
log_e("Initialize NVS Success");
String address = nvs.getString("cameraaddr");
if (address.length() == 17)
{
// Serial.printf("Paired camera address: %s\n", address.c_str());
camera_address = BLEAddress(address.c_str());
}
else
{
// Serial.println("No camera has been paired yet.");
}
}
else
{
log_e("Initialize NVS Failed");
}
}
// Purpose : Scanning for new BLE devices around.
// When found -> advdCallback::OnResult
void CanonBLERemote::scan(unsigned int scan_duration)
{
log_i("Start BLE scan");
BLEScan *pBLEScan = BLEDevice::getScan();
advdCallback *advert_dev_callback = new advdCallback(SERVICE_UUID, &ready_to_connect, &camera_address);
pBLEScan->setAdvertisedDeviceCallbacks(advert_dev_callback); // Retrieve a Scanner and set the callback we want to use to be informed when we have detected a new device.
pBLEScan->setActiveScan(true);
pBLEScan->start(scan_duration); // Specify that we want active scanning and start the scan to run for 30 seconds.
}
BLEAddress CanonBLERemote::getPairedAddress()
{
return camera_address;
}
String CanonBLERemote::getPairedAddressString()
{
return String(camera_address.toString().c_str());
}
/**
* Scan and pair camera
*
* This function should be called only when you want to pair with the new camera, and the camera is in remote paring screen.
* After paired, camera mac address will be stored in ESP32 NVS for later connection use.
*
* @param scan_duration : Scan duration in seconds
*/
bool CanonBLERemote::pair(unsigned int scan_duration)
{
BLEDevice::setEncryptionLevel(ESP_BLE_SEC_ENCRYPT_MITM);
log_i("Scanning for camera...");
scan(scan_duration);
unsigned long start_ms = millis();
while (!ready_to_connect && millis() - start_ms < scan_duration * 1000)
{
}
if (ready_to_connect)
{
log_i("Canon device found");
// Serial.println(camera_address.toString().c_str());
}
else
{
log_i("Camera not found");
return false;
}
// Pair camera
log_i("Pairing..");
if (pclient->connect(camera_address))
{
// Acquire reference to main service
pRemoteService = pclient->getService(SERVICE_UUID);
if (pRemoteService != nullptr)
{
// Acquire reference to BLE characteristics
pRemoteCharacteristic_Pairing = pRemoteService->getCharacteristic(PAIRING_SERVICE);
if ((pRemoteCharacteristic_Pairing != nullptr))
{
// Send request on pairing service from external device
String device_name_ = " " + device_name + " "; //Pairing message to send
byte cmdPress[device_name_.length()]; // Stocking list of Bytes char of the message
device_name_.getBytes(cmdPress, device_name_.length()); // message Parser
cmdPress[0] = {0x03};
pRemoteCharacteristic_Pairing->writeValue(cmdPress, sizeof(cmdPress), false); // Writing to Canon_pairing_service
log_e("Camera paring success");
delay(200);
disconnect();
BLEDevice::setEncryptionLevel(ESP_BLE_SEC_ENCRYPT_NO_MITM);
delay(200);
connect();
nvs.setString("cameraaddr", String(camera_address.toString().c_str()));
if (nvs.commit())
{
log_i("Saving camera's address to NVS success");
return true;
}
else
{
log_e("Storing camera's address to NVS failed");
return false;
}
}
else
{
log_e("Couldn't acquire the pairing or shutter service");
}
}
else
{
log_e("Couldn't acquire the remote main service");
}
}
else
{
log_e("Couldn't connect the BLEClient to the device");
}
return false;
}
bool CanonBLERemote::connect()
{
if (pclient->connect(camera_address))
{
pRemoteService = pclient->getService(SERVICE_UUID);
if (pRemoteService != nullptr)
{
// Serial.println("Get remote service OK");
pRemoteCharacteristic_Trigger = pRemoteService->getCharacteristic(SHUTTER_CONTROL_SERVICE);
if (pRemoteCharacteristic_Trigger != nullptr)
{
log_i("Camera connection Success");
// disconnect(); // Disconnect remote from the camera every time after action, as the real canon remote did.
return true;
}
else
{
log_e("Get trigger service failed");
}
}
else
{
log_e("Couldn't acquire the remote main service");
}
disconnect();
}
return false;
}
void CanonBLERemote::disconnect()
{
pclient->disconnect();
}
bool CanonBLERemote::isConnected()
{
return pconnection_state->isConnected();
}
/** Trigger Camera
* If the camera is in photo mode, it will take a single picture.
* If the camera is in movie mode, it will start/stop movie recording.
*/
bool CanonBLERemote::trigger()
{
if (!isConnected())
{
if (!connect())
{
return false;
}
}
byte cmdByte = {MODE_IMMEDIATE | BUTTON_RELEASE}; // Binary OR : Concatenate Mode and Button
pRemoteCharacteristic_Trigger->writeValue(cmdByte, false); // Set the characteristic's value to be the array of bytes that is actually a string.
delay(200);
pRemoteCharacteristic_Trigger->writeValue(MODE_IMMEDIATE, false);
delay(50);
return true;
}
bool CanonBLERemote::focus()
{
if (!isConnected())
{
if (!connect())
{
return false;
}
}
byte cmdByte[] = {MODE_IMMEDIATE | BUTTON_FOCUS}; // Binary OR : Concatenate Mode and Button
pRemoteCharacteristic_Trigger->writeValue(cmdByte, sizeof(cmdByte)); // Set the characteristic's value to be the array of bytes that is actually a string.
delay(200);
pRemoteCharacteristic_Trigger->writeValue(MODE_IMMEDIATE, sizeof(MODE_IMMEDIATE));
return true;
}

View File

@ -0,0 +1,75 @@
#ifndef CANON_BLE_REMOTE_H_
#define CANON_BLE_REMOTE_H_
#include <BLEDevice.h>
#include <Arduino.h>
#include "ArduinoNvs.h"
class advdCallback : public BLEAdvertisedDeviceCallbacks
{
private:
BLEAddress *paddress_to_connect;
BLEUUID service_uuid_wanted;
bool *pready_to_connect;
public:
advdCallback(BLEUUID service_uuid, bool *ready_to_connect, BLEAddress *address_to_connect);
void onResult(BLEAdvertisedDevice advertisedDevice);
};
class ConnectivityState : public BLEClientCallbacks
{
private:
bool connected = false;
public:
void onConnect(BLEClient *pclient) override;
void onDisconnect(BLEClient *pclient) override;
bool isConnected();
};
class CanonBLERemote
{
private:
// Trigger options
const byte BUTTON_RELEASE = 0b10000000;
const byte BUTTON_FOCUS = 0b01000000;
const byte BUTTON_TELE = 0b00100000;
const byte BUTTON_WIDE = 0b00010000;
const byte MODE_IMMEDIATE = 0b00001100;
const byte MODE_DELAY = 0b00000100;
const byte MODE_MOVIE = 0b00001000;
const BLEUUID SERVICE_UUID;
const BLEUUID PAIRING_SERVICE;
const BLEUUID SHUTTER_CONTROL_SERVICE;
BLEClient *pclient = BLEDevice::createClient();
ConnectivityState *pconnection_state = new ConnectivityState();
BLEAddress camera_address = BLEAddress("");
BLERemoteService *pRemoteService;
BLERemoteCharacteristic *pRemoteCharacteristic_Pairing;
BLERemoteCharacteristic *pRemoteCharacteristic_Trigger;
ArduinoNvs nvs;
bool ready_to_connect = false;
String device_name = "";
void scan(unsigned int scan_duration);
bool connect();
void disconnect();
public:
CanonBLERemote(String name);
void init();
bool pair(unsigned int scan_duration);
bool isConnected();
bool trigger();
bool focus();
BLEAddress getPairedAddress();
String getPairedAddressString();
};
#endif

View File

@ -0,0 +1,14 @@
#!/bin/bash
if [ -d "../../../ArduinoNvs" ]; then
cp "../../../ArduinoNvs/src/"* ./
fi
if [ -d "../../../ESP32-Canon-BLE-Remote" ]; then
cp "../../../ESP32-Canon-BLE-Remote/src/"* ./
fi
if [ -d "../../../TickTwo" ]; then
cp "../../../TockTwo/"*.cpp ./
cp "../../../TockTwo/"*.h ./
fi

View File

@ -0,0 +1,111 @@
/**
*
* Camera Remote Menu
*
*
*
*
*
* Camera Settings
*
*
*
*
*
**/
#include "CanonBLERemote.h"
#include <Arduino.h>
#define RXD2 16
#define TXD2 17
#define LED_BUILTIN 2
#define LOG_LOCAL_LEVEL ESP_LOG_INFO
#include "esp_log.h"
#include <esp32-hal-log.h>
const String name_remote = "mcopy";
CanonBLERemote canon_ble(name_remote);
volatile boolean connected = false;
volatile boolean bleInit = false;
volatile boolean blinkState = false;
volatile long now;
volatile long last = -1;
volatile long blinkLast = 0;
volatile char cmdChar = 'z';
void setup () {
esp_log_level_set("*", ESP_LOG_NONE);
Serial2.begin(9600, SERIAL_8N1, RXD2, TXD2);
pinMode(LED_BUILTIN, OUTPUT);
}
void connectBLE () {
do {
//
}
while(!canon_ble.pair(10));
connected = true;
Serial2.println('C');
}
void loop () {
now = millis();
if (Serial2.available() > 0) {
cmdChar = Serial2.read();
}
if (connected && cmdChar == 'c') {
camera();
}
if (!bleInit && !connected) {
canon_ble.init();
bleInit = true;
}
if (bleInit && !connected && cmdChar == 'C') {
connectBLE();
}
if (connected && !canon_ble.isConnected()) {
connected = false;
Serial2.print('d');
}
blink();
cmdChar = 'z';
}
void camera () {
long start = now;
long end;
if (!canon_ble.trigger()) {
Serial2.print('E');
}
Serial2.print('c');
end = millis();
}
void blink () {
if (!connected && bleInit) {
if (now >= blinkLast + 200) {
if (blinkState) {
digitalWrite(LED_BUILTIN, HIGH);
} else {
digitalWrite(LED_BUILTIN, LOW);
}
blinkState = !blinkState;
blinkLast = now;
}
}
}

View File

@ -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);
}

View File

@ -0,0 +1,87 @@
#ifndef MCOPY_SERIAL
#define MCOPY_SERIAL
#include <Arduino.h>
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 LIGHT = 'l';
const char LIGHT_IDENTIFIER = 'o';
const char MCOPY_IDENTIFIER = 'm';
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

View File

@ -0,0 +1,190 @@
/**
*
* Camera Remote Menu
*
*
*
*
*
* Camera Settings
*
*
*
*
*
**/
#include <SoftwareSerial.h>
#include "McopySerial.h"
#define SHUTTTER_BTN 5
#define RED_LED 6
#define GREEN_LED 7
#define SOFTWARE_RX 10
#define SOFTWARE_TX 11
McopySerial mc;
SoftwareSerial SoftSerial(SOFTWARE_RX, SOFTWARE_TX);
volatile boolean connected = false;
volatile boolean bleInit = false;
volatile boolean blinkState = false;
volatile long blinkLast = 0;
volatile long now;
volatile long last = -1;
volatile long cameraFrame = 3000;
volatile long start;
volatile long end;
volatile char cmdChar = 'z';
volatile char sChar = 'z';
volatile bool connectedOnce = false;
volatile String exposureString;
volatile long exposureTarget = 3000;
void setup () {
pins();
mc.begin(mc.CAMERA_IDENTIFIER);
SoftSerial.begin(9600);
digitalWrite(RED_LED, HIGH);
digitalWrite(GREEN_LED, HIGH);
delay(42);
digitalWrite(RED_LED, LOW);
digitalWrite(GREEN_LED, LOW);
blinkLast = millis();
}
void pins () {
pinMode(SHUTTTER_BTN, INPUT_PULLUP);
pinMode(RED_LED, OUTPUT);
pinMode(GREEN_LED, OUTPUT);
digitalWrite(RED_LED, LOW);
digitalWrite(GREEN_LED, LOW);
}
void loop () {
now = millis();
cmdChar = mc.loop();
if (SoftSerial.available() > 0) {
sChar = SoftSerial.read();
}
s_cmd(sChar);
cmd(cmdChar);
// Shutter
if (digitalRead(SHUTTTER_BTN) == LOW && connected){
camera();
}
if (!connected && mc.connected && mc.identified && !connectedOnce) {
mc.log("Connecting BLE...");
SoftSerial.print('C');
connectedOnce = true;
}
blink();
}
void cmd (char val) {
if (val == mc.CAMERA && connected) {
camera();
} else if (val == mc.CAMERA_FORWARD) {
camera_direction(true);
} else if (val == mc.CAMERA_BACKWARD) {
camera_direction(false);
} else if (val == mc.CAMERA_EXPOSURE) {
exposure();
} else if (val == mc.STATE) {
state();
}
cmdChar = 'z';
}
void exposure () {
exposureString = mc.getString();
parseExposureString();
cameraFrame = exposureTarget;
mc.confirm(mc.CAMERA_EXPOSURE);
}
void parseExposureString () {
exposureTarget = exposureString.toInt();
}
void s_cmd (char val) {
if (val == 'C') {
connected = true;
digitalWrite(RED_LED, HIGH);
digitalWrite(GREEN_LED, LOW);
} else if (val == 'd') {
connected = false;
digitalWrite(RED_LED, LOW);
digitalWrite(GREEN_LED, LOW);
} else if (val == 'c') {
camera_end();
}
sChar = 'z';
}
void camera () {
start = now;
digitalWrite(GREEN_LED, HIGH);
digitalWrite(RED_LED, LOW);
mc.log("Shutter pressed");
SoftSerial.print('c');
}
void camera_end () {
end = millis();
delay(cameraFrame - (end - start));
digitalWrite(GREEN_LED, LOW);
digitalWrite(RED_LED, HIGH);
last = millis();
mc.confirm(mc.CAMERA);
mc.log("camera()");
}
//null route direction
void camera_direction (boolean state) {
if (state) {
mc.confirm(mc.CAMERA_FORWARD);
mc.log("camera_direction(true)");
} else {
mc.confirm(mc.CAMERA_BACKWARD);
mc.log("camera_direction(false)");
}
}
void blink () {
if (!connected) {
if (now >= blinkLast + 200) {
if (blinkState) {
digitalWrite(RED_LED, HIGH);
} else {
digitalWrite(RED_LED, LOW);
}
blinkState = !blinkState;
blinkLast = now;
}
}
}
void state () {
String stateString = String(mc.STATE);
stateString += String(mc.CAMERA_EXPOSURE);
stateString += String(cameraFrame);
stateString += String(mc.STATE);
mc.print(stateString);
}

View File

@ -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);
}

View File

@ -0,0 +1,87 @@
#ifndef MCOPY_SERIAL
#define MCOPY_SERIAL
#include <Arduino.h>
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 LIGHT = 'l';
const char LIGHT_IDENTIFIER = 'o';
const char MCOPY_IDENTIFIER = 'm';
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

View File

@ -0,0 +1,119 @@
/*
Control a camera with a single relay that
triggers a shutter release.
Hardware
Arduino Nano
Relay module
LED
480 Ohm resistor
Wiring
CAMERA
Wire directly to corresponding relay pins.
Arduino 2 5V GND
Relay 1 VCC GND
*/
#include "McopySerial.h"
//CAMERA CONSTANTS
const int CAMERA = 2;
const int BUTTON = 7;
const int LED = 8;
const int CAMERA_MOMENT = 240;
//VARIABLES
volatile int cameraFrame = 2000;
volatile char cmdChar = 'z';
volatile long now;
volatile String exposureString;
volatile long exposureTarget = 2000;
McopySerial mc;
void setup () {
pins();
digitalWrite(LED, HIGH);
mc.begin(mc.CAMERA_IDENTIFIER);
delay(42);
digitalWrite(LED, LOW);
}
void loop () {
now = millis();
cmdChar = mc.loop();
cmd(cmdChar);
if (digitalRead(BUTTON) == LOW) {
camera();
}
}
void pins () {
pinMode(CAMERA, OUTPUT);
pinMode(LED, OUTPUT);
pinMode(BUTTON, INPUT_PULLUP);
digitalWrite(CAMERA, LOW);
digitalWrite(LED, LOW);
}
void cmd (char val) {
if (val == mc.CAMERA_FORWARD) {
camera_direction(true);
} else if (val == mc.CAMERA_BACKWARD) {
camera_direction(false);
} else if (val == mc.CAMERA) {
camera();
} else if (val == mc.CAMERA_EXPOSURE) {
exposure();
} else if (val == mc.STATE) {
state();
}
}
void exposure () {
exposureString = mc.getString();
parseExposureString();
cameraFrame = exposureTarget;
mc.confirm(mc.CAMERA_EXPOSURE);
}
void parseExposureString () {
exposureTarget = exposureString.toInt();
}
//null route direction
void camera_direction (boolean state) {
if (state) {
mc.confirm(mc.CAMERA_FORWARD);
mc.log("camera_direction(true)");
} else {
mc.confirm(mc.CAMERA_BACKWARD);
mc.log("camera_direction(false)");
}
}
void camera () {
digitalWrite(CAMERA, HIGH);
digitalWrite(LED, HIGH);
delay(CAMERA_MOMENT);
digitalWrite(CAMERA, LOW);
delay(cameraFrame - CAMERA_MOMENT);
digitalWrite(LED, LOW);
mc.confirm(mc.CAMERA);
}
void state () {
String stateString = String(mc.STATE);
stateString += String(mc.CAMERA_EXPOSURE);
stateString += String(cameraFrame);
stateString += String(mc.STATE);
mc.sendString(stateString);
}

View File

@ -19,9 +19,9 @@
boolean debug_state = false;
const int proj_fwd_pin = 12;
const int proj_bwd_pin = 11;
const int proj_pin = 10;
const int proj_fwd_pin = 6;
const int proj_bwd_pin = 5;
const int proj_pin = 4;
const int proj_momentary = 60;
const int proj_time = 950; //secondary projector speed

View File

@ -0,0 +1,81 @@
#include "IteadDualStepperShield.h"
IteadDualStepperShield::IteadDualStepperShield () {}
void IteadDualStepperShield::setup () {
pinMode(_directionA, OUTPUT);
pinMode(_directionB, OUTPUT);
pinMode(_stepA, OUTPUT);
pinMode(_stepB, OUTPUT);
setDir(0, 1);
setDir(1, 1);
}
void IteadDualStepperShield::setDir (uint8_t motor, uint8_t dir) {
if (motor == 0) {
directionA = dir;
digitalWrite(_directionA, directionA > 0 ? HIGH : LOW);
} else if (motor == 1) {
directionB = dir;
digitalWrite(_directionB, directionB > 0 ? HIGH : LOW);
}
}
void IteadDualStepperShield::setSpeed (uint8_t motor, uint16_t rpm) {
uint32_t usPerStep = 60000000 / ((uint32_t) revsteps * (uint32_t) rpm);
if (motor == 0) {
_usStepA = usPerStep;
} else if (motor == 1) {
_usStepB = usPerStep;
}
}
void IteadDualStepperShield::_micro (uint8_t motor) {
uint8_t stepPin = motor == 0 ? _stepA : _stepB;
uint32_t usStep = motor == 0 ? _usStepA : _usStepB;
digitalWrite(stepPin, HIGH);
delayMicroseconds(usStep);
digitalWrite(stepPin, LOW);
delayMicroseconds(usStep);
}
//full
void IteadDualStepperShield::_single (uint8_t motor) {
uint8_t stepPin = motor == 0 ? _stepA : _stepB;
uint32_t usStep = motor == 0 ? _usStepA : _usStepB;
for (uint8_t i = 0; i < _microsteps; i++) {
digitalWrite(stepPin, HIGH);
delayMicroseconds(usStep);
digitalWrite(stepPin, LOW);
delayMicroseconds(usStep);
}
}
void IteadDualStepperShield::_both () {
for (uint8_t i = 0; i < _microsteps; i++) {
digitalWrite(_stepA, HIGH);
digitalWrite(_stepB, HIGH);
delayMicroseconds(_usStepA);
digitalWrite(_stepA, LOW);
digitalWrite(_stepB, LOW);
delayMicroseconds(_usStepA);
}
}
void IteadDualStepperShield::step (uint8_t motor, uint16_t steps, uint8_t dir) {
uint8_t stepPin = motor == 0 ? _stepA : _stepB;
setDir(motor, dir);
for (int i = 0; i < steps; i++) {
_single(stepPin);
}
}
void IteadDualStepperShield::onestep (uint8_t motor, uint8_t dir) {
uint8_t stepPin = motor == 0 ? _stepA : _stepB;
setDir(motor, dir);
_single(stepPin);
}
void IteadDualStepperShield::stepBoth (uint16_t steps) {
for (int i = 0; i < steps; i++) {
_both();
}
}

View File

@ -0,0 +1,42 @@
#ifndef IteadDualStepperShield_h
#define IteadDualStepperShield_h
#include <Arduino.h>
class IteadDualStepperShield {
private:
const uint8_t _microsteps = 8; //8 or 16
const uint8_t _directionA = 3;
const uint8_t _directionB = 7;
const uint8_t _stepA = 2;
const uint8_t _stepB = 6;
void _single(uint8_t motor);
void _micro(uint8_t motor);
void _both();
uint32_t _usStepA = 300;
uint32_t _usStepB = 300;
public:
IteadDualStepperShield();
uint16_t revsteps = 200; // # steps per revolution
volatile uint8_t directionA = 1;
volatile uint8_t directionB = 1;
void setup();
void setDir(uint8_t motor, uint8_t dir);
void setSpeed(uint8_t motor, uint16_t speed);
//full
void step(uint8_t motor, uint16_t steps, uint8_t dir);
void stepBoth(uint16_t steps);
void onestep(uint8_t motor, uint8_t dir);
void release();
};
#endif

View File

@ -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);
}

View File

@ -0,0 +1,87 @@
#ifndef MCOPY_SERIAL
#define MCOPY_SERIAL
#include <Arduino.h>
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 LIGHT = 'l';
const char LIGHT_IDENTIFIER = 'o';
const char MCOPY_IDENTIFIER = 'm';
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

View File

@ -0,0 +1,132 @@
/*
JK-compatible projector element
Hardware
Arduino Uno
Itead Dual Stepper Shield
2x NEMA17 Stepper Motors
Wiring
(Will vary from motor to motor)
X01A - Green
X01B - Black
X02A - Blue
X02B - Red
Y01A - Green
Y01B - Black
Y02A - Blue
Y02B - Red
*/
#include "McopySerial.h"
#include "IteadDualStepperShield.h"
//CAMERA CONSTANTS
const int BUTTON = 7;
const int LED_FWD = 8;
const int LED_BWD = 9;
const int PROJECTOR_MOMENT = 240;
const int PROJECTOR_STEPS = 25;
//VARIABLES
volatile int projectorFrame = -1;
volatile char cmdChar = 'z';
volatile long now;
volatile bool direction = true;
volatile long start;
McopySerial mcopy;
IteadDualStepperShield steppers;
void setup () {
steppers.setup();
steppers.setSpeed(0, 500);
steppers.setSpeed(1, 500);
pins();
digitalWrite(LED_FWD, HIGH);
digitalWrite(LED_BWD, HIGH);
mcopy.begin(mcopy.PROJECTOR_IDENTIFIER);
delay(42);
digitalWrite(LED_FWD, LOW);
digitalWrite(LED_BWD, LOW);
}
void loop () {
now = millis();
cmdChar = mcopy.loop();
cmd(cmdChar);
if (digitalRead(BUTTON) == LOW) {
projector();
}
}
void pins () {
pinMode(LED_FWD, OUTPUT);
pinMode(LED_BWD, OUTPUT);
pinMode(BUTTON, INPUT_PULLUP);
digitalWrite(LED_FWD, LOW);
digitalWrite(LED_BWD, LOW);
}
void cmd (char val) {
if (val == mcopy.CAMERA_FORWARD) {
projector_direction(true);
} else if (val == mcopy.CAMERA_BACKWARD) {
projector_direction(false);
} else if (val == mcopy.PROJECTOR) {
projector();
} else if (val == mcopy.STATE) {
state();
}
}
void projector_direction (boolean state) {
direction = state;
if (state) {
mcopy.confirm(mcopy.PROJECTOR_FORWARD);
mcopy.log("projector_direction(true)");
steppers.setDir(0, 1);
steppers.setDir(1, 1);
} else {
mcopy.confirm(mcopy.PROJECTOR_BACKWARD);
mcopy.log("projector_direction(false)");
steppers.setDir(0, 0);
steppers.setDir(1, 0);
}
}
void projector_timing_start () {
start = millis();
}
void projector_timing_end () {
long end = millis();
if (projectorFrame == -1) {
projectorFrame = (end - start);
} else {
//rolling mean
projectorFrame = (projectorFrame + (end - start) / 2);
}
}
void projector () {
int LED = direction ? LED_FWD : LED_BWD;
digitalWrite(LED, HIGH);
steppers.stepBoth(PROJECTOR_STEPS);
mcopy.confirm(mcopy.PROJECTOR);
digitalWrite(LED, LOW);
}
void state () {
String stateString = String(mcopy.CAMERA_EXPOSURE);
stateString += String(projectorFrame);
stateString += String(mcopy.STATE);
mcopy.print(stateString);
}

1
notes/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
env

4738
notes/debug.csv Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,26 @@
#include <Arduino.h>
#define RXD2 16
#define TXD2 17
#define LOG_LOCAL_LEVEL ESP_LOG_INFO
#include "esp_log.h"
#include <esp32-hal-log.h>
volatile char cmd = 'z';
void setup () {
Serial2.begin(9600, SERIAL_8N1, RXD2, TXD2);
}
void loop () {
if (Serial2.available() > 0) {
cmd = Serial2.read();
}
if (cmd == 'x') {
Serial2.print(cmd);
}
cmd = 'z';
}

View File

@ -0,0 +1,25 @@
import serial
import time
import serial.tools.list_ports
ports = serial.tools.list_ports.comports()
port = ''
for p in ports:
print(p)
if "Arduino" in p.description or 'ACM0' in p.description:
print("This is an Arduino!")
port = p.device
break
if port == '':
print("Arduino is not connected")
exit(1)
arduino = serial.Serial(port=port, baudrate=57600, timeout=.05)
time.sleep(1)
with open('debug.csv', 'w') as file:
while True: # Or: while ser.inWaiting():
file.write(arduino.readline().decode())

View File

@ -0,0 +1,43 @@
const int PROJECTOR_MICROSWITCH = 11;
const int PROJECTOR_FWD = 3;
const int PROJECTOR_BWD = 4;
const int PROJECTOR_MICROSWITCH_CLOSED = 0;
const int PROJECTOR_MICROSWITCH_OPENED = 1;
volatile long now;
volatile long startTime = 0;
volatile boolean writing = false;
void setup () {
Serial.begin(57600);
pins();
startTime = millis();
}
void loop () {
now = millis();
if (now >= startTime + 3000) {
digitalWrite(PROJECTOR_FWD, HIGH);
writing = true;
} else if (now >= startTime + 23000) {
digitalWrite(PROJECTOR_FWD, LOW);
writing = false;
}
if (writing) {
Serial.print(now);
Serial.print(",");
Serial.println(digitalRead(PROJECTOR_MICROSWITCH));
}
}
void pins () {
pinMode(PROJECTOR_MICROSWITCH, INPUT_PULLUP);
pinMode(PROJECTOR_FWD, OUTPUT);
pinMode(PROJECTOR_BWD, OUTPUT);
digitalWrite(PROJECTOR_FWD, LOW);
digitalWrite(PROJECTOR_BWD, LOW);
}

View File

@ -0,0 +1,40 @@
#include <SoftwareSerial.h>
#define SOFTWARE_RX 10
#define SOFTWARE_TX 11
SoftwareSerial softPort(SOFTWARE_RX, SOFTWARE_TX);
volatile char proxy = 'z';
volatile char cmd = 'z';
void setup () {
Serial.begin(57600);
softPort.begin(9600);
pinMode(LED_BUILTIN, OUTPUT);
}
//////
// Sending an x character to the nano over
// Serial will proxy it to the ESP32 over SoftSerial
// which will reflect it back to the Nano
// and will turn on the built-in LED. Proof of
// concept round trip
//////
void loop () {
if (Serial.available() > 0) {
proxy = Serial.read();
softPort.print(proxy);
}
if (softPort.available() > 0) {
cmd = softPort.read();
}
if (cmd != 'z') {
Serial.println(cmd);
}
if (cmd == 'x') {
digitalWrite(LED_BUILTIN, HIGH);
}
cmd = 'z';
}

View File

@ -38,20 +38,28 @@
"typescript": "^4.1.5"
},
"dependencies": {
"alert": "file:app/lib/alert",
"arduino": "file:app/lib/arduino",
"cam": "file:app/lib/cam",
"capper" : "file:app/lib/capper",
"cmd": "file:app/lib/cmd",
"delay": "file:app/lib/delay",
"devices": "file:app/lib/devices",
"display": "file:app/lib/display",
"exec" : "file:app/lib/exec",
"exit" : "file:app/lib/exit",
"ffmpeg" : "file:app/lib/ffmpeg",
"ffprobe" : "file:app/lib/ffprobe",
"filmout": "file:app/lib/filmout",
"frame": "file:app/lib/frame",
"intval" : "file:app/lib/intval",
"light": "file:app/lib/light",
"log": "file:app/lib/log",
"mscript": "file:app/lib/mscript",
"processing": "file:app/lib/processing",
"proj": "file:app/lib/proj",
"sequencer": "file:app/lib/sequencer",
"server" : "file:app/lib/server",
"settings": "file:app/lib/settings",
"system": "file:app/lib/system"
}

View File

@ -186,7 +186,10 @@
"capper_on": "A",
"capper_off": "B",
"takeup_forward": "D",
"takeup_backward": "E"
"takeup_backward": "F",
"error" : "E",
"camera_exposure" : "G",
"state" : "H"
}
}
}

View File

@ -0,0 +1,65 @@
//Title: Canon EF Mount Body Cap
//Modified By: Robert Macgregor
//Date: March 29, 2014
//Original Author: Alex English - ProtoParadigm
//Original Date: 8-8-2011
//License: GPL2
//$fs = .1;
$fn = 120;
module EFmount_body() {
//$fa = 1;
union() {
translate([0,0,-1])
cylinder(h = 5.8, r = 66.5/2); //outer grip
translate([0, 0, 6])
cylinder(h = 5, r = 50.5/2);
translate([0, 0, 4])
cylinder(h = 3, r = 54/2); //lip
//translate([0, 0, 12.5]) //inner mounting hole
//cylinder(h = 3.2, r1 = 39.7/2, r2 = 39.5/2);
translate([0, 0, 7])
threads();
rotate([0, 0, -33])
translate([-67/2, 0, 1.9])
cube(size=[1, 2, 5.8], center = true); //alignment mark
}
}
module threads() {
difference() {
cylinder(h = 4, r = 53.2/2); //thread outer
cylinder(h = 4, r = 50.4/2); //thread cylinder
cylinder(h = 2.6, r = 54/2); //gap lip to thread
for(i = [ [0, 0, 0], [180, 0, -70], [0, 0, -120], [180, 0, -180], [0, 0, -230], [180, 0, -300] ])
{
rotate(i)
translate([-35, 0, -5])
cube(size=[40, 18, 10]);
}
}
intersection() {
difference() {
cylinder(h = 4, r = 54/2);
cylinder(h = 4, r = 50.4/2);
}
translate([-54/2+.4, 0, 0])
cube(size=[4, 1.9, 4], center = false); //thread stopper
}
}
module EFmount () {
difference() {
EFmount_body();
translate([0, 0, 1.4])
cylinder(h = 10, r = 41.5/2);
for(k = [44.639 : 8.639 : 385]) {
rotate([0, 0, -k])
translate([-68/2, 0, -1.1])
cylinder(h = 6, r = 2);
}
//cylinder(h = 17, r = 33/2);
}
}

View File

@ -0,0 +1,191 @@
include <./nano.scad>;
include <./common/common.scad>;
afficher_nano = "x";
CaseX = 64;
CaseY = 85;
CaseZ = 35;
CaseD = 8;
CaseSplitZ = 30;
RelayModuleX = 28;
RelayModuleY = 40;
RelayModuleZ = 1.6;
RelayModulePosition = [12, -5, -9];
ArduinoNanoPosition = [-17, 17, -(CaseZ/2) + 8];
AudioJackPosition = [15, CaseY/2, 0];
ButtonPosition = [-15, -CaseY/2, 0];
LEDPosition = [15, -CaseY/2, 0];
BoltY = 25;
BoltX = 0;
module arduino_nano_mount (pos = [0, 0, 0]) {
X = 18.2;
Y = 43.9;
Z = 10.5;
BOARD_Z = 1.5;
translate(pos) difference () {
//outer
cube([X + 6, Y + 6, Z], center = true);
//inner void minus corners
difference () {
cube([X - 1, Y - 1, Z + 1], center = true);
translate([(X / 2) - 1, (Y / 2) - 1, -BOARD_Z]) cylinder(r = (2 / 2), h = Z + 1, center = true, $fn = 20);
translate([(-X / 2) + 1, (Y / 2) - 1, -BOARD_Z]) cylinder(r = (2 / 2), h = Z + 1, center = true, $fn = 20);
translate([(X / 2) - 1, (-Y / 2) + 1, -BOARD_Z]) cylinder(r = (2 / 2), h = Z + 1, center = true, $fn = 20);
translate([(-X / 2) + 1, (-Y / 2) + 1, -BOARD_Z]) cylinder(r = (2 / 2), h = Z + 1, center = true, $fn = 20);
}
//board void
translate([0, 0, (Z / 2) - (BOARD_Z / 2)]) cube([X, Y, BOARD_Z], center = true);
//usb void
translate([0, Y / 2, (Z / 2) - (6 / 2) + 0.01]) cube([8, 10, 6], center = true);
}
}
module usb_mini_void (pos = [0, 0, 0]) {
translate(pos) {
translate([0, 25, 2]) {
cube([8, 10, 5], center = true);
translate([0, 5, 0]) cube([12, 10, 8], center = true);
}
}
}
module case_shell (pos = [0,0,0]) {
$fn = 50;
translate(pos) difference () {
intersection () {
rounded_cube([CaseX, CaseY, CaseZ], d = CaseD, center = true);
translate([0, 0, -CaseD/2]) rotate([90, 0, 0]) rounded_cube([CaseX, CaseZ + CaseD, CaseY], d = CaseD, center = true);
translate([0, 0, -CaseD/2]) rotate([0, 90, 0]) rounded_cube([CaseZ + CaseD, CaseY, CaseX], d = CaseD, center = true);
}
rounded_cube([CaseX - 6, CaseY - 6, CaseZ - 6], d = 6, center = true);
}
}
module audio_jack_void (pos = [0, 0, 0]) {
$fn = 60;
translate(pos) rotate([90, 0, 0]) {
cylinder(r = R(7.7), h = 8, center = true);
translate([0, 0, -3]) cylinder(r = R(10), h = 8, center = true);
}
}
module button_void (pos = [0, 0, 0]) {
D = 6.9;
translate(pos) rotate([90, 0, 0]) cylinder(r = R(D), h = 10, center = true, $fn = 60);
}
module LED_void (pos = [0, 0, 0]) {
D = 5.1;
translate(pos) rotate([90, 0, 0]) cylinder(r = R(D), h = 10, center = true, $fn = 60);
}
module bolt_void (pos = [0, 0, 0], Z = 20, pad = 0) {
translate(pos) cylinder(r = R(3.25 + pad), h = Z, center = true, $fn = 30);
}
module bolt_plug (pos = [0, 0, 0], pad = 0) {
translate(pos) cylinder(r = R(8 + pad), h = 3.5, center = true, $fn = 60);
}
module case_bottom () {
difference () {
union () {
case_shell();
bolt_plug([BoltX, BoltY, -(CaseZ/2)+4]);
}
translate([0, 0, CaseSplitZ]) cube([CaseX + 1, CaseY + 1, CaseZ],center = true);
//bolt
translate([BoltX, BoltY, -(CaseZ/2)+(3.5/2)-0.01]) cylinder(r = R(5.6), h = 3.5, center = true, $fn = 30);
bolt_void([BoltX, BoltY, -(CaseZ/2)], 20);
//usb mini
usb_mini_void(ArduinoNanoPosition);
audio_jack_void (AudioJackPosition);
button_void(ButtonPosition);
LED_void(LEDPosition);
}
arduino_nano_mount(ArduinoNanoPosition);
relay_module_mount(RelayModulePosition);
}
module case_top () {
$fn = 50;
difference () {
case_shell();
translate([0, 0, CaseSplitZ-CaseZ]) cube([CaseX + 1, CaseY + 1, CaseZ],center = true);
bolt_void([BoltX, BoltY, 0], CaseZ - 6 + 1);
translate([2.5, -28, 17]) rotate([0, 0, 90]) scale([0.5, 0.5, 1]) linear_extrude(4) {
text("Canon Rebel T3i", font = "Liberation Sans:style=Bold Italic");
}
}
translate([0, 0, 12]) difference () {
rounded_cube([CaseX - 6.1, CaseY - 6.1, 4], d = 6, center = true);
rounded_cube([CaseX - 8, CaseY - 8, 4 + 1], d = 5, center = true);
}
difference () {
translate([BoltX, BoltY, 1]) cube([10, 10, CaseZ - 6 - 1], center = true);
bolt_void([BoltX, BoltY, -4], CaseZ - 6 + 1, -.4);
bolt_plug([BoltX, BoltY, -(CaseZ/2)+4], 0.2);
}
}
module relay_module_mount (pos = [0, 0, 0]) {
Z = 7;
translate(pos) translate([0, 0, -(Z/2) + (RelayModuleZ/2)]) rotate([0, 0, 180]) {
difference() {
cube([RelayModuleX + 6, RelayModuleY + 4, Z], center = true);
translate([0, -2, 0]) cube([RelayModuleX - 4, RelayModuleY - 8, Z + 1], center = true);
cube([14.75, RelayModuleY - 3, Z + 1], center = true);
translate([0, 0, (Z/2) - (RelayModuleZ/2)]) cube([RelayModuleX+ 0.2, RelayModuleY + 0.2, RelayModuleZ + 0.1], center = true);
}
translate([(RelayModuleX/2) - 3.5, (RelayModuleY/2) - 3.5, Z/2]) cylinder(r = R(2.6), h = RelayModuleZ + 1, center = true, $fn = 40);
translate([-(RelayModuleX/2) + 3.5, (RelayModuleY/2) - 3.5, Z/2]) cylinder(r = R(2.6), h = RelayModuleZ + 1, center = true, $fn = 40);
}
}
module debug_relay_module (pos = [0, 0, 0]) {
translate(pos) rotate([0, 0, 180]) {
difference () {
union () {
cube([RelayModuleX, RelayModuleY, RelayModuleZ], center = true);
//relay
translate([0, 0, (15.5/2) + (RelayModuleZ/2)]) cube([15.25, 18.8, 15.5], center = true);
//terminal
translate([0, -(RelayModuleY/2) + (7.75/2), (10/2) + (RelayModuleZ/2)]) cube([15.6, 7.75, 10], center = true);
}
translate([(RelayModuleX/2) - 3.5, (RelayModuleY/2) - 3.5, 0]) cylinder(r = R(2.9), h = RelayModuleZ + 1, center = true, $fn = 40);
translate([-(RelayModuleX/2) + 3.5, (RelayModuleY/2) - 3.5, 0]) cylinder(r = R(2.9), h = RelayModuleZ + 1, center = true, $fn = 40);
}
}
}
module debug () {
case_top();
difference () {
case_bottom();
translate([(CaseX/2), 0, 0]) cube([CaseX, CaseY + 1, CaseZ + 1], center = true);
}
translate([0, 0, 4]) translate(ArduinoNanoPosition) rotate([0, 0, 90]) nano_328_v1();
debug_relay_module(RelayModulePosition);
}
PART = "case_bottom";
if (PART == "case_bottom") {
case_bottom();
} else if (PART == "case_top") {
case_top();
} else {
debug();
}

View File

@ -38,7 +38,6 @@ BearingInnerDiameter = 11.5;
capM3OffsetZ = 11.5;
PART = "none";
module motorBarrel () {
$fn = 200;
@ -464,25 +463,25 @@ module driveCouplingDCConnector () {
}
LIBRARY = true;
PART = "bellows_camera_board_adapter";
PART2 = "bellows_camera_board_adapter";
if (PART2 == "drive_coupling_DC_connector") {
if (PART == "drive_coupling_DC_connector") {
driveCouplingDCConnector();
} else if (PART2 == "drive_coupling_DC") {
} else if (PART == "drive_coupling_DC") {
driveCouplingDC();
} else if (PART2 == "animation_motor_DC_cap") {
} else if (PART == "animation_motor_DC_cap") {
rotate([180, 0, 0]) animationMotorDCCap();
} else if (PART2 == "animation_motor_DC") {
} else if (PART == "animation_motor_DC") {
animationMotorDCBody();
} else if (PART2 == "animation_motor") {
} else if (PART == "animation_motor") {
animationMotorBody();
} else if (PART2 == "animation_motor_cap") {
} else if (PART == "animation_motor_cap") {
rotate([180, 0, 0]) animationMotorCap();
} else if (PART2 == "drive_coupling") {
} else if (PART == "drive_coupling") {
driveCoupling();
} else if (PART2 == "bellows_camera_board_adapter") {
} else if (PART == "bellows_camera_board_adapter") {
bodyCapBellowsAdapter();
} else if (PART2 == "bellows_camera_board") {
} else if (PART == "bellows_camera_board") {
bellows_camera_board();
}

View File

@ -1,5 +1,7 @@
include <./common.scad>;
PART="mount";
Z = 100 - 14.5;
baseX = 134.5;
@ -83,4 +85,6 @@ module center_fitting () {
//translate([0, 0, (baseZ/2) + (Z/2) + 5]) mount();
//translate([0, 0, (baseZ/2) + Z + 9])
//center_fitting();
mount();
if (PART == "mount") {
mount();
}

View File

@ -1,39 +1,75 @@
module cmount_male(len = 4) {
inner_d = 23;
outer_d = 24.7;
f_inner_d = 25.4;
f_outer_d = 28.6;
include <common/common.scad>;
LIBRARY=false;
BellowsBoard = 60;
MagnetPositionX = 40;
MagnetPositionY = 40;
module cmount_male (len = 4) {
InnerD = 23;
OuterD = 24.7;
SocketInnerD = 25.4;
SocketOuterD = 28.6;
translate ([0, 0, len / 2 ]) {
difference () {
union () {
cylinder(r = outer_d / 2, h = len, center = true);
cylinder(r = R(OuterD), h = len, center = true);
}
cylinder(r = inner_d / 2, h = len + 1, center = true);
cylinder(r = R(InnerD), h = len + 1, center = true);
}
difference () {
translate([0, 0, -(len / 2) - 1]) cylinder(r = f_outer_d / 2, h = 2, center = true);
translate([0, 0, -(len / 2) - 1]) cylinder(r1 = f_inner_d / 2, r2 = inner_d / 2, h = 3, center = true);
translate([0, 0, -(len / 2) - 1]) cylinder(r = R(SocketOuterD), h = 2, center = true);
translate([0, 0, -(len / 2) - 1]) cylinder(r1 = R(SocketInnerD), r2 = R(InnerD), h = 3, center = true);
}
}
}
module bellows_camera_board () {
module bellows_camera_board (magnets = false) {
H = 6;
INNER_D = 39;
InnerD = 39;
difference () {
cube([60, 60, H], center = true);
if (magnets) {
bellows_board_magnetic_body(H);
} else {
cube([BellowsBoard, BellowsBoard, H], center = true);
}
//center
cylinder(r = INNER_D / 2, h = H + 1, center = true, $fn = 360);
cylinder(r = R(InnerD), h = H + 1, center = true, $fn = 360);
//center bevels
translate([0, 0, 2.25]) cylinder(r1 = (INNER_D - 2) / 2, r2 = (INNER_D + 2) / 2, h = 1.5, center = true, $fn = 360);
translate([0, 0, -2.25]) cylinder(r1 = (INNER_D + 2) / 2, r2 = (INNER_D - 2) / 2, h = 1.5, center = true, $fn = 360);
translate([0, 0, 2.25]) cylinder(r1 = R(InnerD - 2), r2 = R(InnerD + 2), h = 1.5, center = true, $fn = 360);
translate([0, 0, -2.25]) cylinder(r1 = R(InnerD + 2), r2 = R(InnerD - 2), h = 1.5, center = true, $fn = 360);
//corners
for (i = [0 : 3]) {
rotate([0, 0, i * (360 / 4) + 45 ]) translate([43.5, 0, 0]) cube([11, 11, H + 1], center = true);
}
//bolt
translate([0, 30, 0]) rotate([90, 0, 0]) cylinder(r = (4 / 2), h = 30, center = true, $fn = 30);
translate([0, 30, 0]) rotate([90, 0, 0]) cylinder(r = R(4), h = 30, center = true, $fn = 30);
}
}
module bellows_lens_board (magnets = false) {
H = 3;
ProtrusionD = 38.25;
ProtrusionH = 5;
InnerD = 34.5;
difference () {
union () {
if (magnets) {
bellows_board_magnetic_body(H);
} else {
cube([BellowsBoard, BellowsBoard, H], center = true);
}
translate([0, 0, (H/2) + (ProtrusionH/2)]) cylinder(r = R(ProtrusionD), h = ProtrusionH, center = true, $fn = 360);
}
//center
cylinder(r = R(InnerD), h = H + ProtrusionH + 10, center = true, $fn = 360);
//corners
for (i = [0 : 3]) {
rotate([0, 0, i * (360 / 4) + 45 ]) translate([43.5, 0, 0]) cube([11, 11, H + 1], center = true);
}
}
}
@ -42,22 +78,62 @@ module camera_mount () {
cmount_male(5);
translate([0, 0, -4]) {
difference() {
cylinder(r = 42 / 2, h = 4, center = true);
cylinder(r = 26 / 2, h = 4 + 1, center = true);
cylinder(r = R(42), h = 4, center = true);
cylinder(r = R(26), h = 4 + 1, center = true);
}
}
translate([0, 0, -4 - 5]) {
difference() {
cylinder(r = 37.9 / 2, h = 7, center = true);
cylinder(r = 30 / 2, h = 7 + 1, center = true);
cylinder(r = R(37.9), h = 7, center = true);
cylinder(r = R(30), h = 7 + 1, center = true);
}
}
}
PART = "bellows_camera_board";
module magnet_void (pos = [0, 0, 0], H = 2.6) {
D = 6 + .25;
translate(pos) cylinder(r = R(D), h = H, center = true, $fn = 60);
}
if (PART == "bellows_camera_board") {
module bellows_board_magnetic_body (H = 6) {
X = MagnetPositionX / 2;
Y = MagnetPositionY / 2;
Z = .5;
difference () {
cube([BellowsBoard, BellowsBoard, H], center = true);
magnet_void([X, Y, Z], H);
magnet_void([-X, Y, Z], H);
magnet_void([X, -Y, Z], H);
magnet_void([-X, -Y, Z], H);
}
}
module bellows_board_magnetic(H = 3) {
InnerD = 45;
difference () {
bellows_board_magnetic_body(H);
//center
cylinder(r = R(InnerD), h = H + 1, center = true, $fn = 360);
//corners
for (i = [0 : 3]) {
rotate([0, 0, i * (360 / 4) + 45 ]) translate([43.5, 0, 0]) cube([11, 11, H + 1], center = true);
}
}
}
PART = "bellows_lens_board";
if (!LIBRARY && PART == "bellows_camera_board") {
bellows_camera_board();
} else if (PART == "camera_mount") {
} else if (!LIBRARY && PART == "bellows_camera_board_magnetic") {
bellows_camera_board(magnets = true);
} else if (!LIBRARY && PART == "camera_mount") {
camera_mount();
} else if (!LIBRARY && PART == "bellows_lens_board") {
bellows_lens_board();
} else if (!LIBRARY && PART == "bellows_lens_board_magnetic") {
bellows_lens_board(magnets = true);
} else if (!LIBRARY && PART == "bellows_board_magnetic") {
bellows_board_magnetic();
}

View File

@ -0,0 +1,13 @@
include <./Canon_EF_body_cap.scad>;
include <./common/common.scad>;
difference () {
union () {
EFmount();
translate([0, 0, -3]) cylinder(r = 38 / 2, h = 10, center = true, $fn = 360);
}
//guide
translate([0, 0, -3]) rotate([0, 0, 8.75]) translate([0, -26, 0]) cylinder(r = R(3), h = 4, center= true);
//center void
cylinder(r = 32 / 2, h = 30, center = true, $fn = 360);
}

View File

@ -0,0 +1,13 @@
include <./ef_m_mount_v3.scad>;
include <./common/common.scad>;
difference () {
union () {
ef_m_mount(thickness=2,grip = true);
translate([0, 0, -3]) cylinder(r = 38 / 2, h = 10, center = true, $fn = 360);
}
//guide
translate([0, 0, -3]) rotate([0, 0, 8.75]) translate([0, -26, 0]) cylinder(r = R(3), h = 4, center= true);
//center void
cylinder(r = 32 / 2, h = 30, center = true, $fn = 360);
}

143
scad/canon_mount.scad Normal file
View File

@ -0,0 +1,143 @@
include <./common/common.scad>;
BaseZ = 10; //debug
BaseX = 91.4;
BaseY = 97.6;
MountX = 60;
MountY = 97.6;
MountZ = 73;
CameraY = 15;
CameraBoltD = 6.4;
function hypotenuese(X) = sqrt(pow(X, 2) + pow(X, 2));
module base_void (pos = [0, 0, 0]) {
$fn = 50;
D = 9.5;
X = 39;
translate(pos) {
cube([X - D, D, BaseZ + 1], center = true);
translate([(X / 2) - (D / 2), 0, 0]) cylinder(r = R(D), h = BaseZ + 1, center = true);
translate([-(X / 2) + (D / 2), 0, 0]) cylinder(r = R(D), h = BaseZ + 1, center = true);
}
}
module base_voids () {
SPACING = 40;
base_void([0, SPACING/2, 0]);
base_void([0, -SPACING/2, 0]);
}
module base (pos = [0, 0, 0]) {
translate(pos) {
//places it at 0z
translate([0, 0, -BaseZ/2]) difference () {
cube([BaseX, BaseY, BaseZ], center = true);
base_voids();
}
}
}
module sensor (pos = [0, 0, 0], LENGTH = 1) {
X = 22.3;
Y = LENGTH;
Z = 14.9;
translate(pos) {
cube([X, Y, Z], center = true);
}
}
module cage_cube (X, Y, Z) {
difference () {
cube([X, Y, Z], center = true);
cube([X-10, Y-10, Z+1], center = true);
cube([X-10, Y+1, Z-10], center = true);
cube([X+1, Y-10, Z-10], center = true);
}
}
module canon_rebel_t3i (pos = [0, 0, 0]) {
X = 133.1;
Y = 79.7;
Z = 99.5;
translate(pos) {
color("azure", 0.25) {
cage_cube(X, Y, Z);
}
color("green") sensor([0, 0, -(Z/2) + (14.9/2) + 30.75]); //160
}
}
module canon_rebel_t3i_mount (pos = [0, 0, 0]) {
translate (pos) {
cylinder(r = R(30), h = 66, center = true);
difference () {
translate([0, 52.5/2, 66/2]) cube([30, 52.5+40, 1], center = true);
translate([0, 52.5, 66/2]) cylinder(r = R(4), h = 1 + 1, center = true);
}
}
}
module canon_m_50 (pos = [0, 0, 0]) {
X = 116;
Y = 59;
Z = 88;
translate(pos) {
color("green", 0.25) {
cage_cube(X, Y, Z);
}
color("green") sensor([0, 0, -(Z/2) + (14.9/2) + 23.71]); //,150
}
}
module canon_m_50_mount () {
X = MountX;
Y = MountY;
Z = MountZ;
SPACING = 40;
ACCESS = 15;
DIAG = hypotenuese(ACCESS);
translate([0, 0, Z/2]) {
difference () {
cube([X, Y, Z], center = true);
cube([X + 1, Y-40, Z-20], center = true);
cube([X + 1, Y-20, Z-40], center = true);
//void around camera bolt
translate([0, CameraY, (Z/2) - 15]) cylinder(r = R(30), h = 20, center = true, $fn = 100);
//void for camera bolt
translate([0, CameraY, (Z/2)]) cylinder(r = R(CameraBoltD), h = 20 + 1, center = true, $fn = 60);
//void for base bolts
base_nut_void([0, SPACING/2, -(Z/2) + 10]);
base_nut_void([0, -SPACING/2, -(Z/2) + 10]);
}
}
}
module base_nut_void (pos = [0, 0, 0], H = 8.5) {
translate(pos) {
cylinder(r = R(16.3), h = H, center = true, $fn = 6);
cylinder(r = R(9.7), h = H + 20, center = true, $fn = 40);
}
}
module debug () {
color("red") base();
//canon_rebel_t3i_mount([0, 20, 33]);
canon_rebel_t3i([0, 20+52.5, 66 + (99.5/2)]);
canon_m_50([0, CameraY, MountZ + 44]);
canon_m_50_mount();
}
PART = "mount";
if (PART == "mount") {
canon_m_50_mount();
} else {
debug();
}

1
scad/common Submodule

@ -0,0 +1 @@
Subproject commit b499c2810117b5ca57014d5cb4219cf68b4c5c0f

176
scad/cpc_connectors.scad Normal file
View File

@ -0,0 +1,176 @@
/*
Amphenol CPC 9pin Connectors
*/
include <./common/common.scad>;
PART="cpc_9pin_socket";
FN = 120;
PlugD = 15.75;
PlugH = 11.65;
PlugGuideD = 17;
PlugPinD = 3.1;
PlugGuideRetraction = 1.25;
PinSpacing = 3.85;
SocketD = PlugD + 0.4;
SocketGuideD = PlugGuideD + 0.5;
SocketOuterD = 20;
SocketH = 10.5;
CollarD = 22;
GuideAngles = [0, 100, 140, 215, 260];
GuideWidths = [3.2, 1.5, 1.5, 1.5, 1.5];
function arc_angle (D, W) = W / ((PI/180) * (D/2));
module guide (Diameter, Height, Angle, Width) {
A = arc_angle(Diameter, Width);
echo(A);
rotate([0, 0, Angle]) difference () {
cylinder(r = R(Diameter), h = Height, center = true, $fn = FN);
rotate([0, 0, -A/2]) translate([Diameter / 2, 0, 0]) cube([Diameter, Diameter * 2, Height + 1], center = true);
rotate([0, 0, A/2]) translate([-Diameter / 2, 0, 0]) cube([Diameter, Diameter * 2, Height + 1], center = true);
}
}
//
module plug_pin (X, Y, H) {
translate([X, Y, 0]) {
cylinder(r = R(PlugPinD), h = H, center = true, $fn = 40);
}
}
module m3_bolt_void (pos = [0, 0, 0], H = 1) {
D = 3.25;
translate(pos) {
cylinder(r = R(D), h = H, center = true, $fn = 40);
}
}
module plug_pin_voids (PinH) {
plug_pin(0, 0, PinH); //5
plug_pin(PinSpacing, 0, PinH); //4
plug_pin(-PinSpacing, 0, PinH); //6
plug_pin(0, PinSpacing, PinH); //2
plug_pin(0, -PinSpacing, PinH); //8
plug_pin(PinSpacing, PinSpacing, PinH); //1
plug_pin(-PinSpacing, PinSpacing, PinH); //3
plug_pin(-PinSpacing, -PinSpacing, PinH); //9
plug_pin(PinSpacing, -PinSpacing, PinH); //7
}
module cpc_9pin_plug () {
$fn = FN;
PinH = PlugH + 1;
difference () {
union () {
cylinder(r = R(PlugD), h = PlugH, center = true);
translate([0, 0, -(PlugH/2)+(2/2)]) cylinder(r = R(PlugD + 2), h = 2, center = true);
translate([0, 0, -PlugGuideRetraction/2]) {
for (i = [0 : len(GuideAngles) - 1]) {
guide(PlugGuideD, PlugH - PlugGuideRetraction, GuideAngles[i], GuideWidths[i]);
}
}
}
plug_pin_voids(PinH);
}
}
module cpc_9pin_plug_collar () {
$fn = FN;
H = 25;
difference () {
union () {
cylinder(r = R(CollarD), h = H, center = true);
}
cylinder(r = R(SocketD), h = H, center = true);
}
}
module cpc_9pin_plug_back () {
//
}
module flange_guide_void (pos = [0, 0, 0], Z = 8) {
OD = 24;
ID = 19;
translate(pos) {
intersection () {
difference () {
cylinder(r = R(OD), h = Z, center = true);
cylinder(r = R(ID), h = Z + 1, center = true);
}
union () {
translate([0, 0, 1]) cube([5, 25, Z], center = true);
translate([0, 0, -3]) rotate([7, 0, 0]) translate([(OD/2)-(5/2), OD/4, 0]) cube([OD, OD/2, 3], center = true);
translate([0, 0, -3]) rotate([-7, 0, 0]) translate([-(OD/2)+(5/2), -OD/4, 0]) cube([OD, OD/2, 3], center = true);
}
}
}
}
module cpc_9pin_socket () {
$fn = FN;
BaseH = 3;
BoltVoid = 26;
BackingH = 8;
BackingD = 17;
PinH = SocketH + BaseH + BackingH + 10;
difference () {
union () {
cylinder(r = R(SocketOuterD), h = SocketH + BaseH, center = true);
translate([0, 0, -((SocketH + BaseH) / 2) + (BaseH / 2)]) rounded_cube([34, 34, BaseH], d = 6, center = true, $fn = 40);
translate([0, 0, - (BaseH / 2) - BackingH]) cylinder(r = R(BackingD), h = BackingH, center = true);
}
translate([0, 0, BaseH]) {
cylinder(r = R(SocketD), h = SocketH + BaseH, center = true);
for (i = [0 : len(GuideAngles) - 1]) {
guide(SocketGuideD + 0.1, SocketH + BaseH, GuideAngles[i], GuideWidths[i] + 0.5);
}
}
plug_pin_voids(PinH);
translate([0, 0, 3]) rotate([0,0, 37]) flange_guide_void([0, 0, (PlugH / 2) - (8 / 2) + 0.01], 8);
translate([0, 0, -((SocketH + BaseH) / 2) + (BaseH / 2)]) {
m3_bolt_void([BoltVoid/2, BoltVoid/2, 0], BaseH + 1);
m3_bolt_void([BoltVoid/2, -BoltVoid/2, 0], BaseH + 1);
m3_bolt_void([-BoltVoid/2, BoltVoid/2, 0], BaseH + 1);
m3_bolt_void([-BoltVoid/2, -BoltVoid/2, 0], BaseH + 1);
}
}
}
module debug () {
difference () {
union () {
cpc_9pin_plug();
translate([0, 0, 13]) cpc_9pin_socket();
}
translate([25, 0, 0]) cube([50, 50, 100], center = true);
}
}
if (PART == "cpc_9pin_plug") {
cpc_9pin_plug();
} else if (PART == "cpc_9pin_plug_collar") {
cpc_9pin_plug_collar();
} else if (PART == "cpc_9pin_plug_back") {
cpc_9pin_plug_back();
} else if (PART == "cpc_9pin_socket") {
cpc_9pin_socket();
} else {
debug();
}

132
scad/ef_m_mount_v3.scad Normal file
View File

@ -0,0 +1,132 @@
/*
*
* Canon EF-M lens-side mount
*
* Remix of Canon EF-M lens mount by Peter K. Johnson (PPK):
* https://www.thingiverse.com/thing:703383
*
* Added optional thickness parameter (default is 0) to add depth to the large
* circle.
* Added grip texture option to outer edge
*
* Created EF-M pinhole module which builds a variable focal length
* EF-M pinhole lens with a slot to accept a pinhole.
*
* brett stevens 2021.
*/
/*
// constants from Fotasy adapter mount
outer_diam_1 = 54;
outer_diam_2 = 46.8;
outer_diam_3 = 42.88;
inner_diam = 41.28;
// constants from Canon mount
outer_diam_1 = 58.0;
outer_diam_2 = 47.0;
outer_diam_3 = 43.0;
*/
outer_diam_1 = 58.0;
outer_diam_2 = 47.0;
outer_diam_3 = 43.0;
pin_hole_width = 2.2;
// Partial rotate extrude from: http://www.thingiverse.com/thing:34027
module pie_slice(radius, angle, step) {
for(theta = [0:step:angle-step]) {
rotate([0,0,0])
linear_extrude(height=radius*2, center=true)
polygon(
points = [
[0,0],
[radius*cos(theta+step), radius*sin(theta+step)],
[radius*cos(theta), radius*sin(theta)]
]
);
}
}
module partial_rotate_extrude(angle, radius, convex) {
intersection () {
rotate_extrude(convexity=convex) translate([radius,0,0]) children(0);
pie_slice(radius*2, angle, angle/5);
}
}
// Canon EF-M lens mount
module ef_m_bayonet_section(angle) {
partial_rotate_extrude(angle, outer_diam_3/2-0.1, 10)
polygon([[0,-2.2],[0,0],[1.6,0],[1.6,-1.6]]);
}
module ef_m_mount( thickness = 0, grip = false) {
$fa = 0.01;
$fn = 200;
union() {
difference() {
if (grip)
difference() {
translate([0, 0, -thickness])
cylinder(h=2+thickness, d=outer_diam_1);
{
for(i = [0:100-1])
{
rotate([0,0,i*360/100])
translate([outer_diam_1/2,0,-1.75-thickness])
cylinder(thickness+0.5+2,r=0.5);
}
}
}
else
translate([0, 0, -thickness])
cylinder(h=2+thickness, d=outer_diam_1);
rotate(a=[0, 0, -22])
translate([49/2, -pin_hole_width/2, 1.1])
cube([4, pin_hole_width, 1.1]);
rotate(a=[0, 0, -83])
translate([outer_diam_1/2-2.5, 0, 1.5])
cube([1.5, 1.5, 0.6]);
}
translate([0, 0, 2])
cylinder(h=1.6, d=outer_diam_2);
difference() {
translate([0, 0, 0])
cylinder(h=7.6, d=outer_diam_3);
translate([0, 0, 7.6])
rotate(a=[0, 0, 40])
partial_rotate_extrude(140, 34.5/2, 10)
polygon([[0,-1],[0,0.1],[2.5,0.1],[2.5,-1]]);
}
translate([0, 0, 7.6]) {
partial_rotate_extrude(3, outer_diam_3/2-.1, 10)
polygon([[0,-4],[0,0],[1.4,0],[1.4,-4]]);
ef_m_bayonet_section(58);
rotate(a=[0, 0, 131])
ef_m_bayonet_section(51);
rotate(a=[0, 0, 243])
ef_m_bayonet_section(51);
}
}
}
// Example with typical EF-M hole, but that part can be modified as needed for
// whatever final assembly is being made. There's a subtle alignment dot built
// into the base mount (on the camera side), but if a more visible one is desired
// on a larger assembly it should be at -83 degrees relative to the mount.
//difference() {
// ef_m_mount();
// translate([0,0,-1]) cylinder(h=10, d=32);
//}
$fn = 200;
overlap = 0.1;

199
scad/esp32_case.scad Normal file
View File

@ -0,0 +1,199 @@
include <./arduino.scad>;
include <./common/common.scad>;
DEBUG = false;
PART = "case_top";
CaseX = 70;
CaseY = 85;
CaseZ = 35;
CaseD = 8;
CaseSplitZ = 30;
ESP32Position = [15, -7-5, -5];
ArduinoNanoPosition = [-17, -17, -(CaseZ/2) + 8];
ESP32Size = [25.85, 53.8, 1.5];
ButtonPosition = [9, CaseY/2, 0];
LEDPosition1 = [-3, CaseY/2, 0];
LEDPosition2 = [-11, CaseY/2, 0];
BoltY = 25;
module pin_debug (pos = [0, 0, 0]) {
translate(pos) cube([.6, .6, 6.26], center = true);
}
module esp32_pins_debug (pos = [0, 0, 0]) {
PinSpacing = 2.5;
translate(pos) {
cube([2.5, 48, 2.5], center = true);
translate([0, -45/2, 0]) for (i = [0 : 18]) {
pin_debug([0, i * PinSpacing, -3]);
}
}
}
module esp32_debug () {
X = ESP32Size[0];
Y = ESP32Size[1];
Z = ESP32Size[2];
cube([X, Y, Z], center = true);
//micro usb
translate([0, (Y/2)-(5.65/2), (Z/2)+(3/2)]) cube([7.5, 5.65, 3], center = true);
//pins
esp32_pins_debug([(X/2)-(2.5/2), 0, -(2.5/2)-(Z/2)]);
esp32_pins_debug([-(X/2)+(2.5/2), 0, -(2.5/2)-(Z/2)]);
//esp32 chip
translate([0, -(Y/2)+(17.9/2)+5.4, (Z/2)+(3/2)]) cube([15.9, 17.9, 3], center = true);
//antenna
translate([0, -(Y/2)+(25.5/2)-0.85, (Z/2)+(.8/2)]) cube([17.8, 25.5, .8], center = true);
}
module debug () {
//translate(ESP32Position) rotate([180, 0, 0]) esp32_debug();
difference () {
union () {
case_bottom();
translate([0, 0, 1]) rotate([0, 0, 0]) color("red") case_top();
}
translate([-CaseX / 2, 0, 0]) cube([CaseX, CaseY + 1, 100], center = true);
}
}
/**
*
**/
module case_shell (pos = [0,0,0]) {
$fn = 50;
translate(pos) difference () {
intersection () {
rounded_cube([CaseX, CaseY, CaseZ], d = CaseD, center = true);
translate([0, 0, -CaseD/2]) rotate([90, 0, 0]) rounded_cube([CaseX, CaseZ + CaseD, CaseY], d = CaseD, center = true);
translate([0, 0, -CaseD/2]) rotate([0, 90, 0]) rounded_cube([CaseZ + CaseD, CaseY, CaseX], d = CaseD, center = true);
}
rounded_cube([CaseX - 6, CaseY - 6, CaseZ - 6], d = 6, center = true);
}
}
module arduino_nano_mount (pos = [0, 0, 0]) {
X = 18.2;
Y = 43.9;
Z = 10.5;
BOARD_Z = 1.5;
translate(pos) rotate([0, 0, 180]) difference () {
//outer
cube([X + 6, Y + 6, Z], center = true);
//inner void minus corners
difference () {
cube([X - 1, Y - 1, Z + 1], center = true);
translate([(X / 2) - 1, (Y / 2) - 1, -BOARD_Z]) cylinder(r = (2 / 2), h = Z + 1, center = true, $fn = 20);
translate([(-X / 2) + 1, (Y / 2) - 1, -BOARD_Z]) cylinder(r = (2 / 2), h = Z + 1, center = true, $fn = 20);
translate([(X / 2) - 1, (-Y / 2) + 1, -BOARD_Z]) cylinder(r = (2 / 2), h = Z + 1, center = true, $fn = 20);
translate([(-X / 2) + 1, (-Y / 2) + 1, -BOARD_Z]) cylinder(r = (2 / 2), h = Z + 1, center = true, $fn = 20);
}
//board void
translate([0, 0, (Z / 2) - (BOARD_Z / 2)]) cube([X, Y, BOARD_Z], center = true);
//usb void
translate([0, Y / 2, (Z / 2) - (6 / 2) + 0.01]) cube([8, 10, 6], center = true);
}
}
module esp32_mount (pos = [0, 0, 0]) {
X = ESP32Size[0];
Y = ESP32Size[1];
Z = 2;
translate([pos[0], pos[1], pos[2]-5]) difference () {
cube([X+4, Y+4, 10], center = true);
translate([0, 0, (10/2)-(2/2)+0.01]) cube([X, Y, Z], center = true);
translate([0, 0, 0]) cube([X-1, Y-1, 10], center = true);
//micro usb
translate([0, -(Y/2), 2.7]) cube([9, 7, 5], center = true);
//antenna
translate([0, (Y/2), 3]) cube([20, 25.5, 5], center = true);
}
}
module button_void (pos = [0, 0, 0]) {
D = 6.9;
translate(pos) rotate([90, 0, 0]) cylinder(r = R(D), h = 10, center = true, $fn = 60);
}
module LED_void (pos = [0, 0, 0]) {
D = 5.1;
translate(pos) rotate([90, 0, 0]) cylinder(r = R(D), h = 10, center = true, $fn = 60);
}
module bolt_void (pos = [0, 0, 0], Z = 20, pad = 0) {
translate(pos) cylinder(r = R(3.25 + pad), h = Z, center = true, $fn = 30);
}
module bolt_plug (pos = [0, 0, 0], pad = 0) {
translate(pos) cylinder(r = R(8 + pad), h = 3.5, center = true, $fn = 60);
}
module usb_mini_void (pos = [0, 0, 0]) {
translate(pos) {
translate([0, -25, 2]) {
cube([8, 10, 5], center = true);
translate([0, -5, 0]) cube([12, 10, 8], center = true);
}
}
}
module case_bottom () {
difference () {
union () {
case_shell();
bolt_plug([0, BoltY, -(CaseZ/2)+4]);
}
translate([0, 0, CaseSplitZ]) cube([CaseX + 1, CaseY + 1, CaseZ],center = true);
//micro usb
translate([15, -(CaseY/2), -7.8]) cube([9, 7, 4], center = true);
translate([15, -(CaseY/2)-3, -7.8]) cube([12, 10, 7.7], center = true);
//mini USB
usb_mini_void(ArduinoNanoPosition);
//button
button_void(ButtonPosition);
//LEDS
LED_void(LEDPosition1);
LED_void(LEDPosition2);
//bolt
translate([0, BoltY, -(CaseZ/2)+(3.5/2)-0.01]) cylinder(r = R(5.6), h = 3.5, center = true, $fn = 30);
bolt_void([0, BoltY, -(CaseZ/2)], 20);
}
esp32_mount(ESP32Position);
arduino_nano_mount(ArduinoNanoPosition);
}
module case_top () {
$fn = 50;
difference () {
case_shell();
translate([0, 0, CaseSplitZ-CaseZ]) cube([CaseX + 1, CaseY + 1, CaseZ],center = true);
bolt_void([0, BoltY, 0], CaseZ - 6 + 1);
translate([2.5, -28, 17]) rotate([0, 0, 90]) scale([0.5, 0.5, 1]) linear_extrude(4) {
text("Canon EOS M50", font = "Liberation Sans:style=Bold Italic");
}
}
translate([0, 0, 12]) difference () {
rounded_cube([CaseX - 6.1, CaseY - 6.1, 4], d = 6, center = true);
rounded_cube([CaseX - 8, CaseY - 8, 4 + 1], d = 5, center = true);
}
difference () {
translate([0, BoltY, 1]) cube([10, 10, CaseZ - 6 - 1], center = true);
bolt_void([0, BoltY, -4], CaseZ - 6 + 1, -.4);
bolt_plug([0, BoltY, -(CaseZ/2)+4], 0.2);
}
}
if (PART == "case_bottom") {
case_bottom();
} else if (PART == "case_top") {
case_top();
} else {
debug();
}

Some files were not shown because too many files have changed in this diff Show More