11 changed files with 494 additions and 1 deletions
@ -0,0 +1,5 @@ |
|||||
|
applet |
||||
|
application.* |
||||
|
|
||||
|
ephimera/data/* |
||||
|
ephimera/history/* |
@ -1 +1,14 @@ |
|||||
ephimera |
|
||||
|
## Ephimera |
||||
|
|
||||
|
### Keyboard commands |
||||
|
|
||||
|
``` |
||||
|
ESC - Exti from the program ans shutdown |
||||
|
``` |
||||
|
``` |
||||
|
U - Unload liquid from the pumps |
||||
|
``` |
||||
|
``` |
||||
|
1-8 - Load liquid in single pumps (from 1 to 8) |
||||
|
``` |
||||
|
|
||||
|
@ -0,0 +1,171 @@ |
|||||
|
#include <Wire.h> |
||||
|
#include <Adafruit_PWMServoDriver.h> |
||||
|
|
||||
|
Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver(); |
||||
|
|
||||
|
#define SERVOMIN 330 // this is the 'minimum' pulse length count (out of 4096) - increasing SERVOMIN decrease speed
|
||||
|
#define SERVOMAX 390 // this is the 'maximum' pulse length count (out of 4096)
|
||||
|
#define TIMER 200 |
||||
|
#define SERVODIVIDER 5 |
||||
|
#define STRIP 10 |
||||
|
|
||||
|
const char HEADER = 'H'; |
||||
|
const char A_TAG = 'M'; |
||||
|
const char B_TAG = 'X'; |
||||
|
const char C_TAG = 'U'; |
||||
|
const char F_TAG = 'F'; |
||||
|
|
||||
|
const int TOTAL_BYTES = 10 ; // the total bytes in a message
|
||||
|
|
||||
|
int atomPins[] = {2,3,4,5,6,7,8,9}; |
||||
|
int currentValue = 0; |
||||
|
int values[] = {0,0,0,0,0,0,0,0}; |
||||
|
|
||||
|
int cycle = 0; |
||||
|
boolean fadeDirection = 0; // 0 grow
|
||||
|
byte fadeStatus = 0; |
||||
|
|
||||
|
void setup() { |
||||
|
Serial.begin(9600); |
||||
|
|
||||
|
for(int i=0; i<8; i++) { |
||||
|
pinMode(atomPins[i], OUTPUT); |
||||
|
pwm.setPWM(i, 0, ((SERVOMAX-SERVOMIN)/2)+SERVOMIN); |
||||
|
} |
||||
|
|
||||
|
pinMode(STRIP, OUTPUT); |
||||
|
fadeIn(); |
||||
|
pwm.begin(); |
||||
|
pwm.setPWMFreq(60); // Analog servos run at ~60 Hz updates
|
||||
|
|
||||
|
delay(10); |
||||
|
} |
||||
|
|
||||
|
void setServoPulse(uint8_t n, double pulse) { |
||||
|
double pulselength; |
||||
|
|
||||
|
pulselength = 1000000; // 1,000,000 us per second
|
||||
|
pulselength /= 60; // 60 Hz
|
||||
|
Serial.print(pulselength); Serial.println(" us per period"); |
||||
|
pulselength /= 4096; // 12 bits of resolution
|
||||
|
Serial.print(pulselength); Serial.println(" us per bit"); |
||||
|
pulse *= 1000000; // convert to us
|
||||
|
pulse /= pulselength; |
||||
|
Serial.println(pulse); |
||||
|
pwm.setPWM(n, 0, pulse); |
||||
|
} |
||||
|
|
||||
|
void loop() { |
||||
|
|
||||
|
cycle = 0; |
||||
|
|
||||
|
for(int i=0; i<8; i++) { |
||||
|
values[i] = 0; |
||||
|
} |
||||
|
|
||||
|
if(Serial.available() >= TOTAL_BYTES) { |
||||
|
if( Serial.read() == HEADER) { |
||||
|
char tag = Serial.read(); |
||||
|
|
||||
|
if(tag == F_TAG) { |
||||
|
fadeOut(); |
||||
|
} |
||||
|
|
||||
|
if(tag == A_TAG || tag == B_TAG) { |
||||
|
for(int i=0; i<8; i++) { |
||||
|
values[i] = Serial.read(); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
for(int i=0; i<8; i++) { |
||||
|
if(tag == A_TAG) { |
||||
|
pwm.setPWM(i, 0, SERVOMAX+50); |
||||
|
delay(100*SERVODIVIDER); |
||||
|
pwm.setPWM(i, 0, SERVOMAX-50); |
||||
|
delay(100*SERVODIVIDER); |
||||
|
} |
||||
|
pwm.setPWM(i, 0, SERVOMIN); |
||||
|
delay(values[i]*SERVODIVIDER); |
||||
|
pwm.setPWM(i, 0, ((SERVOMAX-SERVOMIN)/2)+SERVOMIN); |
||||
|
} |
||||
|
|
||||
|
if(tag == C_TAG) { |
||||
|
|
||||
|
for(int i=0; i<8; i++) { |
||||
|
pwm.setPWM(i, 0, SERVOMAX+50); |
||||
|
delay(100*SERVODIVIDER); |
||||
|
pwm.setPWM(i, 0, ((SERVOMAX-SERVOMIN)/2)+SERVOMIN); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
} else { |
||||
|
|
||||
|
for(int i=0; i<8; i++) { |
||||
|
Serial.print(values[i]); |
||||
|
Serial.print(" "); |
||||
|
if(values[i]>0) { |
||||
|
values[i]--; |
||||
|
digitalWrite(atomPins[i], HIGH); |
||||
|
if(values[i]==0) { |
||||
|
cycle++; |
||||
|
digitalWrite(atomPins[i], LOW); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
if(tag == A_TAG) { |
||||
|
while(cycle < 8) { |
||||
|
cycle = 0; |
||||
|
for(int i=0; i<8; i++) { |
||||
|
Serial.print(values[i]); |
||||
|
Serial.print(" "); |
||||
|
if(values[i]>0) { |
||||
|
values[i]--; |
||||
|
digitalWrite(atomPins[i], HIGH); |
||||
|
if(values[i]==0) { |
||||
|
cycle++; |
||||
|
digitalWrite(atomPins[i], LOW); |
||||
|
} |
||||
|
} else { |
||||
|
cycle++; |
||||
|
} |
||||
|
|
||||
|
for(int f=0;f<4;f++){ |
||||
|
fadeGradient(); |
||||
|
delay(TIMER/(8*4)); |
||||
|
} |
||||
|
} |
||||
|
Serial.println(""); |
||||
|
} |
||||
|
|
||||
|
fadeIn(); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
void fadeIn() { |
||||
|
for(int i=0; i<255; i++) { |
||||
|
analogWrite(STRIP, i); |
||||
|
delay(10); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
void fadeOut() { |
||||
|
for(int i=255; i>0; i--) { |
||||
|
analogWrite(STRIP, i); |
||||
|
delay(10); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
void fadeGradient() { |
||||
|
if(fadeDirection == 0) {fadeStatus++;} |
||||
|
if(fadeDirection == 1) {fadeStatus--;} |
||||
|
|
||||
|
if(fadeStatus == 0) {fadeDirection = 0;} |
||||
|
if(fadeStatus == 255) {fadeDirection = 1;} |
||||
|
|
||||
|
analogWrite(STRIP, fadeStatus); |
||||
|
} |
||||
|
|
@ -0,0 +1,84 @@ |
|||||
|
import processing.io.*; |
||||
|
import processing.serial.*; |
||||
|
//import processing.video.*; |
||||
|
import gohai.glvideo.*; |
||||
|
|
||||
|
Serial port; |
||||
|
|
||||
|
// ----------------------- camera --------------------------------------------------------------------------------- |
||||
|
//Capture video; |
||||
|
GLCapture video; |
||||
|
PImage img; |
||||
|
boolean takePicture = true; |
||||
|
int videoWidth = 480; |
||||
|
int videoHeight = 240; |
||||
|
|
||||
|
int sending = 0; |
||||
|
|
||||
|
void setup() { |
||||
|
size(480, 240, P2D); |
||||
|
frameRate(10); |
||||
|
colorMode(HSB, 100, 100, 100); |
||||
|
|
||||
|
String portName = Serial.list()[0]; |
||||
|
port = new Serial(this, portName, 9600); |
||||
|
|
||||
|
String[] cameras = GLCapture.list(); |
||||
|
video = new GLCapture(this, cameras[0], width, height, 10); |
||||
|
video.start(); |
||||
|
|
||||
|
GPIO.pinMode(4, GPIO.INPUT); |
||||
|
|
||||
|
// video = new Capture(this, width, height); |
||||
|
// video.start(); |
||||
|
|
||||
|
background(0); |
||||
|
delay(2000); |
||||
|
|
||||
|
} |
||||
|
|
||||
|
void draw() { |
||||
|
ephPercentage(); |
||||
|
|
||||
|
|
||||
|
if (GPIO.digitalRead(4) == GPIO.LOW && takePicture == true){ |
||||
|
takePicture = false; |
||||
|
sendMessage(F_TAG, colorByteValues); |
||||
|
delay(4000); |
||||
|
video.pause(); |
||||
|
makePicture(); |
||||
|
} |
||||
|
|
||||
|
if(GPIO.digitalRead(4) == GPIO.HIGH && takePicture == false){ |
||||
|
takePicture = true; |
||||
|
video.start(); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
} |
||||
|
|
||||
|
void keyPressed() { |
||||
|
if (key == 'S' || key == 's') { |
||||
|
video.pause(); |
||||
|
makePicture(); |
||||
|
} |
||||
|
if (key == 'B' || key == 'b') { |
||||
|
backupFrame(); |
||||
|
} |
||||
|
if (key == 'G' || key == 'g') { |
||||
|
video.start(); |
||||
|
} |
||||
|
if (key == 'U' || key == 'u') { |
||||
|
sendMessage(C_TAG, colorByteValues); |
||||
|
} |
||||
|
if (key == '1' || key == '2' || key == '3' || key == '4' || key == '5' || key == '6' || key == '7' || key == '8') { |
||||
|
for(int i=0; i<colorsN; i++) { |
||||
|
colorByteValues[i] = (int(key)-49) == i ? byte(100) : 0; |
||||
|
print(colorByteValues[i] + "\t"); |
||||
|
} |
||||
|
println(""); |
||||
|
sendMessage(B_TAG, colorByteValues); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
} |
@ -0,0 +1,16 @@ |
|||||
|
void makePicture() { |
||||
|
saveFrame("data/shot.gif"); |
||||
|
img = loadImage("shot.gif"); |
||||
|
//ephPercentage(); |
||||
|
ephSerial(); |
||||
|
//video.start(); |
||||
|
} |
||||
|
|
||||
|
void backupFrame() { |
||||
|
// save picture with results for backup |
||||
|
saveFrame("history/shot_" + |
||||
|
nf(year(), 4) + nf(month(), 2) + nf(day(), 2) + "_" + |
||||
|
nf(hour(), 2) + nf(minute(), 2) + nf(second(), 2) + |
||||
|
".gif"); |
||||
|
println("color count image saved"); |
||||
|
} |
After Width: | Height: | Size: 44 KiB |
After Width: | Height: | Size: 44 KiB |
@ -0,0 +1,82 @@ |
|||||
|
int cellSize = 20; |
||||
|
int cols = videoWidth / cellSize; |
||||
|
int rows = videoHeight / cellSize; |
||||
|
int cellN = (cols)*(rows); |
||||
|
int[] colorValues = {0, 0, 0, 0, 0, 0, 0, 0}; |
||||
|
byte[] colorByteValues = {0, 0, 0, 0, 0, 0, 0, 0}; |
||||
|
int colorsN = colorValues.length; |
||||
|
float colorsRange = float(100)/float(colorsN-2); |
||||
|
|
||||
|
|
||||
|
void ephPercentage() { |
||||
|
|
||||
|
if (video.available()) { |
||||
|
video.read(); |
||||
|
video.loadPixels(); |
||||
|
|
||||
|
for(int i = 0; i<colorsN; i++) { |
||||
|
colorValues[i] = 0; |
||||
|
} |
||||
|
|
||||
|
for (int i = 0; i < cols; i++) { |
||||
|
for (int j = 0; j < rows; j++) { |
||||
|
|
||||
|
int x = i*cellSize; |
||||
|
int y = j*cellSize; |
||||
|
int loc = (video.width - x - 1) + y*video.width; // Reversing x to mirror the image |
||||
|
|
||||
|
// Get hue and brightness values |
||||
|
float hueVal = constrain(hue(video.pixels[loc]),0,100); |
||||
|
float briVal = constrain(brightness(video.pixels[loc]),0,100); |
||||
|
float satVal = constrain(saturation(video.pixels[loc]),0,100); |
||||
|
|
||||
|
// Set pixel color |
||||
|
color c = color(hueVal, satVal, briVal); |
||||
|
|
||||
|
// Check brightness values, |
||||
|
// if greater then 80% increace white counter, |
||||
|
// if lower then 20% increace black counter, |
||||
|
// otherwise increase color counters |
||||
|
if(briVal > 20 && briVal < 99) { |
||||
|
colorValues[hueCal(hueVal)]++; |
||||
|
} else if(briVal <= 20) { |
||||
|
colorValues[colorsN-2]++; |
||||
|
} else if(briVal >= 99) { |
||||
|
colorValues[colorsN-1]++; |
||||
|
} |
||||
|
|
||||
|
pushMatrix(); |
||||
|
translate(x+cellSize/2, y+cellSize/2); |
||||
|
rectMode(CENTER); |
||||
|
fill(c); |
||||
|
noStroke(); |
||||
|
rect(0, 0, cellSize+6, cellSize+6); |
||||
|
popMatrix(); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// Print colors percentage values |
||||
|
for(int i = 0; i<colorsN-2; i++) { |
||||
|
fill(color((i*colorsRange), 100, 100)); |
||||
|
rect(0, (i*5)+5, map(colorValues[i]/(cellN/100),0,100,0,width), 5); |
||||
|
} |
||||
|
|
||||
|
fill(0); |
||||
|
rect(0, 5*(colorsN-2)+5, map(colorValues[colorsN-2]/(cellN/100),0,100,0,width), 5); |
||||
|
fill(100); |
||||
|
rect(0, 5*(colorsN-1)+5, map(colorValues[colorsN-1]/(cellN/100),0,100,0,width), 5); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
int hueCal(float val){ |
||||
|
int result = 0; |
||||
|
if(val<11){result = 0;} |
||||
|
if(val>=11 && val<22){result = 1;} |
||||
|
if(val>=22 && val<44){result = 2;} |
||||
|
if(val>=44 && val<56){result = 3;} |
||||
|
if(val>=56 && val<80){result = 4;} |
||||
|
if(val>=80){result = 5;} |
||||
|
//if(val>=90){result = 0;} |
||||
|
|
||||
|
return result; |
||||
|
} |
@ -0,0 +1,36 @@ |
|||||
|
public static final char HEADER = 'H'; |
||||
|
public static final char A_TAG = 'M'; |
||||
|
public static final char B_TAG = 'X'; |
||||
|
public static final char C_TAG = 'U'; |
||||
|
public static final char F_TAG = 'F'; |
||||
|
|
||||
|
void ephSerial() { |
||||
|
|
||||
|
for(int i = 0; i<colorsN; i++) { |
||||
|
colorByteValues[i] = byte(colorValues[i]/(cellN/100)); |
||||
|
print(colorByteValues[i] + "\t"); |
||||
|
} |
||||
|
println(""); |
||||
|
sendMessage(A_TAG, colorByteValues); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
void sendMessage(char tag, byte[] cbv){ |
||||
|
// send the given index and value to the serial port |
||||
|
port.write(HEADER); |
||||
|
port.write(tag); |
||||
|
|
||||
|
for(int i=0; i<cbv.length; i++) { |
||||
|
port.write(cbv[i]); |
||||
|
} |
||||
|
port.clear(); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
void serialEvent(Serial p) { |
||||
|
// handle incoming serial data |
||||
|
String inString = port.readStringUntil('\n'); |
||||
|
if(inString != null) { |
||||
|
print( inString ); // echo text string from Arduino |
||||
|
} |
||||
|
} |
@ -0,0 +1,2 @@ |
|||||
|
sleep 5 |
||||
|
/home/pi/Desktop/ephimera/ephimera/application.linux-armv6hf/ephimera && sleep 5 && sudo halt |
@ -0,0 +1,84 @@ |
|||||
|
/***************************************************
|
||||
|
This is an example for our Adafruit 16-channel PWM & Servo driver |
||||
|
Servo test - this will drive 8 servos, one after the other on the |
||||
|
first 8 pins of the PCA9685 |
||||
|
|
||||
|
Pick one up today in the adafruit shop! |
||||
|
------> http://www.adafruit.com/products/815
|
||||
|
|
||||
|
These drivers use I2C to communicate, 2 pins are required to |
||||
|
interface. |
||||
|
|
||||
|
Adafruit invests time and resources providing this open source code, |
||||
|
please support Adafruit and open-source hardware by purchasing |
||||
|
products from Adafruit! |
||||
|
|
||||
|
Written by Limor Fried/Ladyada for Adafruit Industries. |
||||
|
BSD license, all text above must be included in any redistribution |
||||
|
****************************************************/ |
||||
|
|
||||
|
#include <Wire.h> |
||||
|
#include <Adafruit_PWMServoDriver.h> |
||||
|
|
||||
|
// called this way, it uses the default address 0x40
|
||||
|
Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver(); |
||||
|
// you can also call it with a different address you want
|
||||
|
//Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver(0x41);
|
||||
|
// you can also call it with a different address and I2C interface
|
||||
|
//Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver(0x40, &Wire);
|
||||
|
|
||||
|
// Depending on your servo make, the pulse width min and max may vary, you
|
||||
|
// want these to be as small/large as possible without hitting the hard stop
|
||||
|
// for max range. You'll have to tweak them as necessary to match the servos you
|
||||
|
// have!
|
||||
|
|
||||
|
#define SERVOMIN 330 // this is the 'minimum' pulse length count (out of 4096) - increasing SERVOMIN decrease speed
|
||||
|
#define SERVOMAX 390 // this is the 'maximum' pulse length count (out of 4096)
|
||||
|
|
||||
|
// our servo # counter
|
||||
|
uint8_t servonum = 0; |
||||
|
|
||||
|
void setup() { |
||||
|
Serial.begin(9600); |
||||
|
Serial.println("8 channel Servo test!"); |
||||
|
|
||||
|
pwm.begin(); |
||||
|
|
||||
|
pwm.setPWMFreq(60); // Analog servos run at ~60 Hz updates
|
||||
|
|
||||
|
pinMode(8, OUTPUT); |
||||
|
delay(10); |
||||
|
} |
||||
|
|
||||
|
// you can use this function if you'd like to set the pulse length in seconds
|
||||
|
// e.g. setServoPulse(0, 0.001) is a ~1 millisecond pulse width. its not precise!
|
||||
|
void setServoPulse(uint8_t n, double pulse) { |
||||
|
double pulselength; |
||||
|
|
||||
|
pulselength = 1000000; // 1,000,000 us per second
|
||||
|
pulselength /= 60; // 60 Hz
|
||||
|
Serial.print(pulselength); Serial.println(" us per period"); |
||||
|
pulselength /= 4096; // 12 bits of resolution
|
||||
|
Serial.print(pulselength); Serial.println(" us per bit"); |
||||
|
pulse *= 1000000; // convert to us
|
||||
|
pulse /= pulselength; |
||||
|
Serial.println(pulse); |
||||
|
pwm.setPWM(n, 0, pulse); |
||||
|
} |
||||
|
|
||||
|
void loop() { |
||||
|
// Drive each servo one at a time
|
||||
|
Serial.println(servonum); |
||||
|
|
||||
|
|
||||
|
for(int x=0; x<8; x++) { |
||||
|
|
||||
|
pwm.setPWM(x, 0, SERVOMIN); |
||||
|
delay(1000); |
||||
|
pwm.setPWM(x, 0, ((SERVOMAX-SERVOMIN)/2)+SERVOMIN); |
||||
|
|
||||
|
delay(1000); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
} |
Loading…
Reference in new issue