Commit 5b75382f731b2f99054bde28e6519d7263d37a3a
1 parent
eabb3dc1
Exists in
master
and in
1 other branch
Added Channel/Control
Showing
27 changed files
with
352 additions
and
166 deletions
Show diff stats
app/CMakeLists.txt
... | ... | @@ -12,15 +12,14 @@ list(APPEND CMAKE_MODULE_PATH ${OF_ROOT}) |
12 | 12 | |
13 | 13 | include(openFrameworks) |
14 | 14 | |
15 | -#ofxaddon(ofxGui) | |
16 | -ofxaddon(ofxXmlSettings) | |
17 | -ofxaddon(ofxUI) | |
15 | +ofxaddon(ofxGui) | |
18 | 16 | |
19 | 17 | set(SOURCES |
20 | 18 | src/main.cpp |
21 | 19 | src/ofApp.cpp |
22 | - src/ArduinoUtils.cpp | |
23 | - # src/ArduinoControls.cpp | |
20 | + src/inoUtils.cpp | |
21 | + src/inoControl.cpp | |
22 | + src/inoChannel.cpp | |
24 | 23 | ) |
25 | 24 | |
26 | 25 | add_executable( | ... | ... |
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
app/res/ring.wav
No preview for this file type
app/res/settings.xml
app/src/ArduinoControls.cpp
... | ... | @@ -1,29 +0,0 @@ |
1 | -#include "ArduinoControls.h" | |
2 | -#include "ofMain.h" | |
3 | - | |
4 | -ArduinoControls::ArduinoControls(string device) : device(device) { | |
5 | - connect.addListener(this, &ArduinoControls::toggleConnection); | |
6 | - gui.setup(device); | |
7 | - gui.add(connect.setup("Connect", false)); | |
8 | - gui.add(color.setup("Color", | |
9 | - ofColor(100, 100, 140), | |
10 | - ofColor(0, 0), ofColor(255, 255))); | |
11 | - | |
12 | -} | |
13 | - | |
14 | -ArduinoControls::~ArduinoControls() { | |
15 | -} | |
16 | - | |
17 | -ofxGuiGroup * ArduinoControls::getGui() { | |
18 | - return &gui; | |
19 | -} | |
20 | - | |
21 | -void ArduinoControls::toggleConnection(bool & status) { | |
22 | - cout << "Connection to " << device; | |
23 | - if(status) { | |
24 | - cout << " On"; | |
25 | - } else { | |
26 | - cout << " Off"; | |
27 | - } | |
28 | - cout << endl; | |
29 | -} |
app/src/ArduinoControls.h
... | ... | @@ -1,17 +0,0 @@ |
1 | -#pragma once | |
2 | - | |
3 | -#include "ofMain.h" | |
4 | -#include "ofxGui.h" | |
5 | - | |
6 | -class ArduinoControls { | |
7 | -public: | |
8 | - ArduinoControls(string device); | |
9 | - ~ArduinoControls(); | |
10 | - ofxGuiGroup * getGui(); | |
11 | - void toggleConnection(bool & status); | |
12 | -private: | |
13 | - string device; | |
14 | - ofxGuiGroup gui; | |
15 | - ofxToggle connect; | |
16 | - ofxColorSlider color; | |
17 | -}; |
app/src/ArduinoUtils.cpp
... | ... | @@ -1,38 +0,0 @@ |
1 | -#include "ArduinoUtils.h" | |
2 | - | |
3 | -#include "ofMain.h" | |
4 | - | |
5 | -#if defined(__linux__) | |
6 | -const std::string patterns[] = { | |
7 | - "/dev/ttyACM", | |
8 | - "/dev/ttyUSB" | |
9 | -}; | |
10 | -#elif defined(__APPLE__) | |
11 | -const std::string patterns[] = { | |
12 | - "/dev/tty.usbmodem", | |
13 | - "/dev/tty.usbserial" | |
14 | -}; | |
15 | -#endif | |
16 | - | |
17 | -bool isArduinoPort(const string & path) { | |
18 | - for(string pattern : patterns) { | |
19 | - if(path.compare(0, pattern.size(), pattern) == 0) | |
20 | - return true; | |
21 | - } | |
22 | - return false; | |
23 | -} | |
24 | - | |
25 | -vector<string> getArduinoDevices() { | |
26 | - ofSerial serial; | |
27 | - vector<ofSerialDeviceInfo> deviceList = serial.getDeviceList(); | |
28 | - auto it = remove_if(deviceList.begin(), deviceList.end(), | |
29 | - [](ofSerialDeviceInfo & info) { | |
30 | - return ! isArduinoPort(info.getDevicePath()); | |
31 | - }); | |
32 | - deviceList.erase(it, deviceList.end()); | |
33 | - vector<string> paths; | |
34 | - for(ofSerialDeviceInfo dev : deviceList) { | |
35 | - paths.push_back(dev.getDevicePath()); | |
36 | - } | |
37 | - return paths; | |
38 | -} |
app/src/ArduinoUtils.h
... | ... | @@ -0,0 +1,52 @@ |
1 | +#include "inoChannel.h" | |
2 | +#include "heisenwave.h" | |
3 | + | |
4 | +void inoChannel::setup(string device) { | |
5 | + this->device = device; | |
6 | +} | |
7 | + | |
8 | +void inoChannel::exit() { | |
9 | + while(!commands.empty()) { | |
10 | + delete[] commands.front(); | |
11 | + commands.pop(); | |
12 | + } | |
13 | +} | |
14 | + | |
15 | +void inoChannel::identify() { | |
16 | + char *command = new char[device.size()+2]; | |
17 | + command[0] = HW_HELO; | |
18 | + command[1] = device.size(); | |
19 | + memcpy(&command[2], device.c_str(), device.size()); | |
20 | + commands.push(command); | |
21 | +} | |
22 | + | |
23 | +void inoChannel::startStream() { | |
24 | +} | |
25 | + | |
26 | +void inoChannel::stopStream() { | |
27 | +} | |
28 | + | |
29 | +void inoChannel::threadedFunction() { | |
30 | + lock(); | |
31 | + serial.setup(device, 115200); | |
32 | + serial.flush(); | |
33 | + while(isThreadRunning() && !(serial.available() >= 4)); | |
34 | + if(serial.available() >= 4) { | |
35 | + char buf[4]; | |
36 | + serial.readBytes((unsigned char*)buf, 4); | |
37 | + if(buf[0] != 'H' || buf[1] != 'W') { | |
38 | + // Serial Port is invalid | |
39 | + string status("Invalid"); | |
40 | + ofNotifyEvent(statusChange, status, this); | |
41 | + serial.close(); | |
42 | + return; | |
43 | + } | |
44 | + string status("Connected"); | |
45 | + ofNotifyEvent(statusChange, status, this); | |
46 | + } | |
47 | + while(isThreadRunning()) { | |
48 | + } | |
49 | + string status("Idle"); | |
50 | + ofNotifyEvent(statusChange, status, this); | |
51 | + serial.close(); | |
52 | +} | ... | ... |
... | ... | @@ -0,0 +1,21 @@ |
1 | +#pragma once | |
2 | + | |
3 | +#include "ofMain.h" | |
4 | + | |
5 | +class inoChannel : public ofThread { | |
6 | +public: | |
7 | + void setup(string device); | |
8 | + void exit(); | |
9 | + void threadedFunction(); | |
10 | + void identify(); | |
11 | + void startStream(); | |
12 | + void stopStream(); | |
13 | + int getVersion(); | |
14 | + | |
15 | + ofEvent<string> statusChange; | |
16 | + | |
17 | +private: | |
18 | + ofSerial serial; | |
19 | + string device; | |
20 | + queue<char*> commands; | |
21 | +}; | ... | ... |
... | ... | @@ -0,0 +1,54 @@ |
1 | +#include "inoControl.h" | |
2 | +#include "ofMain.h" | |
3 | + | |
4 | +inoControl::inoControl(string device) { | |
5 | + connect.addListener(this, &inoControl::toggleConnection); | |
6 | + gui.setup(device); | |
7 | + gui.add(status.setup("Status", "Setup...")); | |
8 | + gui.add(connect.setup("Connect", false)); | |
9 | + gui.add(settings.setup("Settings")); | |
10 | + settings.add(color.setup("Color", | |
11 | + ofColor(100, 100, 140), | |
12 | + ofColor(0, 0), ofColor(255, 255))); | |
13 | + | |
14 | + filePath = device; | |
15 | + ofStringReplace(filePath, "/", "_"); | |
16 | + filePath = "settings/" + filePath + ".xml"; | |
17 | + | |
18 | + if(ofFile::doesFileExist(filePath)) { | |
19 | + settings.loadFromFile(filePath); | |
20 | + } else { | |
21 | + ofFile newFile(ofToDataPath(filePath), ofFile::WriteOnly); | |
22 | + newFile.create(); | |
23 | + newFile.close(); | |
24 | + } | |
25 | + status = "Idle"; | |
26 | + | |
27 | + channel.setup(device); | |
28 | + ofAddListener( | |
29 | + channel.statusChange, | |
30 | + this, | |
31 | + &inoControl::onStatusChanged); | |
32 | +} | |
33 | + | |
34 | +inoControl::~inoControl() { | |
35 | + channel.exit(); | |
36 | + channel.waitForThread(); | |
37 | + settings.saveToFile(filePath); | |
38 | +} | |
39 | + | |
40 | +ofxGuiGroup * inoControl::getGui() { | |
41 | + return &gui; | |
42 | +} | |
43 | + | |
44 | +void inoControl::toggleConnection(bool & status) { | |
45 | + if(status) { | |
46 | + channel.startThread(); | |
47 | + } else { | |
48 | + channel.stopThread(); | |
49 | + } | |
50 | +} | |
51 | + | |
52 | +void inoControl::onStatusChanged(string & str) { | |
53 | + status = str; | |
54 | +} | ... | ... |
... | ... | @@ -0,0 +1,24 @@ |
1 | +#pragma once | |
2 | + | |
3 | +#include "ofMain.h" | |
4 | +#include "ofxGui.h" | |
5 | + | |
6 | +#include "inoChannel.h" | |
7 | + | |
8 | +class inoControl { | |
9 | +public: | |
10 | + inoControl(string device); | |
11 | + ~inoControl(); | |
12 | + ofxGuiGroup * getGui(); | |
13 | + void toggleConnection(bool & status); | |
14 | + void onStatusChanged(string & status); | |
15 | +private: | |
16 | + string filePath; | |
17 | + string device; | |
18 | + ofxGuiGroup gui; | |
19 | + ofxGuiGroup settings; | |
20 | + ofxToggle connect; | |
21 | + ofxLabel status; | |
22 | + ofxColorSlider color; | |
23 | + inoChannel channel; | |
24 | +}; | ... | ... |
... | ... | @@ -0,0 +1,38 @@ |
1 | +#include "inoUtils.h" | |
2 | + | |
3 | +#include "ofMain.h" | |
4 | + | |
5 | +#if defined(__linux__) | |
6 | +const std::string patterns[] = { | |
7 | + "/dev/ttyACM", | |
8 | + "/dev/ttyUSB" | |
9 | +}; | |
10 | +#elif defined(__APPLE__) | |
11 | +const std::string patterns[] = { | |
12 | + "/dev/tty.usbmodem", | |
13 | + "/dev/tty.usbserial" | |
14 | +}; | |
15 | +#endif | |
16 | + | |
17 | +bool isArduinoPort(const string & path) { | |
18 | + for(string pattern : patterns) { | |
19 | + if(path.compare(0, pattern.size(), pattern) == 0) | |
20 | + return true; | |
21 | + } | |
22 | + return false; | |
23 | +} | |
24 | + | |
25 | +vector<string> getArduinoDevices() { | |
26 | + ofSerial serial; | |
27 | + vector<ofSerialDeviceInfo> deviceList = serial.getDeviceList(); | |
28 | + auto it = remove_if(deviceList.begin(), deviceList.end(), | |
29 | + [](ofSerialDeviceInfo & info) { | |
30 | + return ! isArduinoPort(info.getDevicePath()); | |
31 | + }); | |
32 | + deviceList.erase(it, deviceList.end()); | |
33 | + vector<string> paths; | |
34 | + for(ofSerialDeviceInfo dev : deviceList) { | |
35 | + paths.push_back(dev.getDevicePath()); | |
36 | + } | |
37 | + return paths; | |
38 | +} | ... | ... |
app/src/main.cpp
... | ... | @@ -3,12 +3,6 @@ |
3 | 3 | |
4 | 4 | //======================================================================== |
5 | 5 | int main( ) { |
6 | - | |
7 | - ofSetupOpenGL(800,600, OF_WINDOW);// <-------- setup the GL context | |
8 | - | |
9 | - // this kicks off the running of my app | |
10 | - // can be OF_WINDOW or OF_FULLSCREEN | |
11 | - // pass in width and height too: | |
12 | - ofRunApp( new ofApp()); | |
13 | - | |
6 | + ofSetupOpenGL(800, 600, OF_WINDOW);// <-------- setup the GL context | |
7 | + ofRunApp(new ofApp()); | |
14 | 8 | } | ... | ... |
app/src/ofApp.cpp
1 | 1 | #include "ofApp.h" |
2 | -#include "ArduinoUtils.h" | |
3 | - | |
4 | -#define BUFFER_SIZE 128 | |
2 | +#include "inoUtils.h" | |
5 | 3 | |
6 | 4 | void ofApp::setup(){ |
7 | 5 | ofSetDataPathRoot("../res/"); |
8 | - ofSetVerticalSync(true); | |
6 | + ofSetVerticalSync(true); | |
9 | 7 | ofEnableSmoothing(); |
10 | 8 | ofBackground(ofColor::white); |
9 | + ofSetColor(ofColor::red); | |
11 | 10 | |
12 | - logo.load("heisenwave.png"); | |
13 | - | |
14 | - buffer = new float[BUFFER_SIZE]; | |
15 | - period = 10.0; | |
16 | - | |
17 | - gui = new ofxUICanvas(); | |
18 | - gui->addSlider("BACKGROUND", 0.0, 255.0, 255.0); | |
19 | - gui->addButton("DISCOVER", false); | |
20 | - gui->addWaveform("WAVE", buffer, BUFFER_SIZE, -2, 2, 700, 200); | |
21 | - gui->addSlider("PERIOD", 1.0, 20.0, &period); | |
22 | - gui->autoSizeToFitWidgets(); | |
23 | - ofAddListener(gui->newGUIEvent, this, &ofApp::guiEvent); | |
11 | + discoverBtn.addListener(this, &ofApp::discoverArduinos); | |
12 | + gui.setup(); | |
13 | + discoverBtn.setup("Discover"); | |
14 | + discoverArduinos(); | |
24 | 15 | } |
25 | 16 | |
26 | 17 | void ofApp::exit() { |
27 | - delete gui; | |
28 | - delete[] buffer; | |
18 | + for(auto p : controls) { | |
19 | + delete p.second; | |
20 | + } | |
29 | 21 | } |
30 | 22 | |
31 | 23 | void ofApp::update() { |
32 | - for(int i = 0; i < BUFFER_SIZE; ++i) { | |
33 | - buffer[i] = (float)sin( | |
34 | - ((double)i + ofGetElapsedTimef()*200) | |
35 | - / period / BUFFER_SIZE * 10); | |
36 | - } | |
37 | 24 | } |
38 | 25 | |
39 | 26 | void ofApp::draw() { |
40 | - //logo.draw(400-128,300-128); | |
27 | + ofSetPolyMode(OF_POLY_WINDING_ODD); | |
28 | + ofNoFill(); | |
29 | + ofSetLineWidth(1.5); | |
30 | + ofBeginShape(); | |
31 | + for(int i = 0; i <= 100; i++) { | |
32 | + ofVertex((float)i/100 * 800, (float)i/100 * 600); | |
33 | + } | |
34 | + ofEndShape(false); | |
35 | + if(showGui) { | |
36 | + gui.draw(); | |
37 | + } | |
41 | 38 | } |
42 | 39 | |
43 | 40 | void ofApp::keyPressed(int key) { |
41 | + if(key == 'h') { | |
42 | + showGui = !showGui; | |
43 | + } | |
44 | 44 | } |
45 | 45 | |
46 | 46 | void ofApp::keyReleased(int key) { } |
... | ... | @@ -52,17 +52,29 @@ void ofApp::windowResized(int w, int h) { } |
52 | 52 | void ofApp::gotMessage(ofMessage msg) { } |
53 | 53 | void ofApp::dragEvent(ofDragInfo dragInfo) { } |
54 | 54 | |
55 | -void ofApp::guiEvent(ofxUIEventArgs &e) { | |
56 | - if(e.getName() == "BACKGROUND") { | |
57 | - ofxUISlider *slider = e.getSlider(); | |
58 | - ofBackground(slider->getScaledValue()); | |
59 | - } else if(e.getName() == "DISCOVER") { | |
60 | - vector<string> devs = getArduinoDevices(); | |
61 | - for(string dev : devs) { | |
62 | - cout << "Arduino @ " << dev <<endl; | |
63 | - } | |
64 | - if(devs.empty()) { | |
65 | - cout << "No Arduinos discovered" << endl; | |
55 | +void ofApp::discoverArduinos() { | |
56 | + vector<string> devs = getArduinoDevices(); | |
57 | + for(auto ctrl = controls.begin(); ctrl != controls.end();) { | |
58 | + auto it = find(devs.begin(), devs.end(), ctrl->first); | |
59 | + if(it == devs.end()) { | |
60 | + delete ctrl->second; | |
61 | + controls.erase(ctrl++); | |
62 | + } else { | |
63 | + devs.erase(it); | |
64 | + ++ctrl; | |
66 | 65 | } |
67 | 66 | } |
67 | + for(string dev : devs) { | |
68 | + inoControl *ctrl = new inoControl(dev); | |
69 | + controls.insert({dev, ctrl}); | |
70 | + } | |
71 | + rebuildGui(); | |
72 | +} | |
73 | + | |
74 | +void ofApp::rebuildGui() { | |
75 | + gui.clear(); | |
76 | + gui.add(&discoverBtn); | |
77 | + for(auto ctrl : controls) { | |
78 | + gui.add(ctrl.second->getGui()); | |
79 | + } | |
68 | 80 | } | ... | ... |
app/src/ofApp.h
1 | 1 | #pragma once |
2 | 2 | |
3 | 3 | #include "ofMain.h" |
4 | -//#include "ofxGui.h" | |
5 | -#include "ofxUI.h" | |
4 | +#include "ofxGui.h" | |
6 | 5 | |
7 | -//#include "ArduinoControls.h" | |
6 | +#include "inoControl.h" | |
8 | 7 | |
9 | 8 | class ofApp : public ofBaseApp { |
10 | 9 | public: |
... | ... | @@ -24,12 +23,12 @@ public: |
24 | 23 | void dragEvent(ofDragInfo dragInfo); |
25 | 24 | void gotMessage(ofMessage msg); |
26 | 25 | |
27 | - ofxUICanvas *gui; | |
28 | - void guiEvent(ofxUIEventArgs &e); | |
29 | - | |
30 | - float *buffer; | |
31 | - float period; | |
32 | - | |
33 | - ofImage logo; | |
26 | + void discoverArduinos(); | |
27 | +private: | |
28 | + void rebuildGui(); | |
29 | + map<string, inoControl *> controls; | |
30 | + ofxPanel gui; | |
31 | + ofxButton discoverBtn; | |
32 | + bool showGui = true; | |
34 | 33 | }; |
35 | 34 | ... | ... |
tests/Echo/src/sketch.ino
tests/HelloWorld/src/sketch.ino
1 | -void setup() | |
2 | -{ | |
3 | - Serial.begin(9600); | |
4 | - Serial.print("HelloWorld"); | |
1 | +#include "heisenwave.h" | |
2 | + | |
3 | +#define NAME_SIZE 32 | |
4 | +#define BUFFER_SIZE 128 | |
5 | +#define MAX(a, b) (((a)>(b))?(a):(b)) | |
6 | +#define MIN(a, b) (((a)<(b))?(a):(b)) | |
7 | +char name[NAME_SIZE]; | |
8 | +bool streaming = false; | |
9 | +int tstamp = 0; | |
10 | +char buffer[BUFFER_SIZE]; | |
11 | + | |
12 | +void writeBytes(char *buffer, size_t len, bool block = false) { | |
13 | + for(size_t i = 0; i < len; ++i) { | |
14 | + Serial.write(buffer[i]); | |
15 | + } | |
16 | + if(block) { | |
17 | + Serial.flush(); | |
18 | + } | |
19 | +} | |
20 | + | |
21 | +void version() { | |
22 | + Serial.print('H'); | |
23 | + Serial.print('W'); | |
24 | + Serial.print(1); | |
25 | + Serial.print(0); | |
26 | +} | |
27 | + | |
28 | +void setup() { | |
29 | + Serial.begin(115200); | |
30 | + version(); | |
31 | + memset(name, 0, NAME_SIZE); | |
32 | +} | |
33 | + | |
34 | +void handleCommands() { | |
35 | + if(Serial.available() >= 1) { | |
36 | + char command = Serial.read(); | |
37 | + switch(command) { | |
38 | + case HW_HELO: | |
39 | + { | |
40 | + int len = Serial.read(); | |
41 | + Serial.readBytes(name, MIN(NAME_SIZE, len)); | |
42 | + for(int i = NAME_SIZE; i < len; ++i) { | |
43 | + Serial.read(); | |
44 | + } | |
45 | + Serial.write(HW_ACK); | |
46 | + } | |
47 | + case HW_START_STREAM: | |
48 | + streaming = true; | |
49 | + Serial.write(HW_ACK); | |
50 | + case HW_STOP_STREAM: | |
51 | + streaming = false; | |
52 | + Serial.write(HW_ACK); | |
53 | + } | |
54 | + } | |
5 | 55 | } |
6 | 56 | |
7 | -void loop() | |
8 | -{ | |
57 | +void loop() { | |
58 | + tstamp = (tstamp + 1) % 1000; | |
59 | + if(tstamp == 0 && streaming) { | |
60 | + writeBytes(name, NAME_SIZE); | |
61 | + } | |
62 | + handleCommands(); | |
9 | 63 | } | ... | ... |