postman<->teensy comm. updated (I2C --> Serial)
This commit is contained in:
parent
615a6eeab9
commit
50bac35c13
7 changed files with 533 additions and 296 deletions
226
osc/main_taskscheduler.cpp
Normal file
226
osc/main_taskscheduler.cpp
Normal file
|
|
@ -0,0 +1,226 @@
|
|||
//
|
||||
// wirelessly connected cloud (Wireless Mesh Networking)
|
||||
//
|
||||
|
||||
//
|
||||
// Conversations about the ROOT @ SEMA warehouses, Seoul
|
||||
//
|
||||
|
||||
//
|
||||
// 2021 02 15
|
||||
//
|
||||
// (part-2) teensy35 : 'client:osc' (osc over slip --> mesh post)
|
||||
//
|
||||
|
||||
//arduino
|
||||
#include <Arduino.h>
|
||||
|
||||
//osc (already included in "framework-arduinoteensy")
|
||||
#include <OSCBundle.h>
|
||||
#include <SLIPEncodedUSBSerial.h>
|
||||
SLIPEncodedUSBSerial SLIPSerial(Serial);
|
||||
|
||||
//post definition
|
||||
#include "../../post.h"
|
||||
|
||||
//postman's uart
|
||||
#define POSTMAN_SERIAL (Serial3)
|
||||
|
||||
//
|
||||
void midinote(OSCMessage& msg, int offset) {
|
||||
// matches will happen in the order. that the bundle is packed.
|
||||
static int pitch = 0;
|
||||
static int velocity = 0;
|
||||
static int onoff = 0;
|
||||
static int x1 = 0;
|
||||
static int x2 = 0;
|
||||
static int x3 = 0;
|
||||
static int x4 = 0;
|
||||
static int ps = 0;
|
||||
// (1) --> /onoff
|
||||
if (msg.fullMatch("/onoff", offset)) {
|
||||
//
|
||||
pitch = 0;
|
||||
velocity = 0;
|
||||
onoff = 0;
|
||||
//
|
||||
onoff = msg.getInt(0);
|
||||
if (onoff != 0) onoff = 1;
|
||||
}
|
||||
// (2) --> /velocity
|
||||
if (msg.fullMatch("/velocity", offset)) {
|
||||
velocity = msg.getInt(0);
|
||||
if (velocity < 0) velocity = 0;
|
||||
// if (velocity > 127) velocity = 127;
|
||||
if (velocity > 999) velocity = 999;
|
||||
}
|
||||
// (3) --> /pitch
|
||||
if (msg.fullMatch("/pitch", offset)) {
|
||||
pitch = msg.getInt(0);
|
||||
if (pitch < 0) pitch = 0;
|
||||
// if (pitch > 127) pitch = 127;
|
||||
if (pitch > 999) pitch = 999;
|
||||
}
|
||||
// (4) --> /x
|
||||
if (msg.fullMatch("/x", offset)) {
|
||||
x1 = msg.getInt(0);
|
||||
x2 = msg.getInt(1);
|
||||
x3 = msg.getInt(2);
|
||||
x4 = msg.getInt(3);
|
||||
ps = msg.getInt(4);
|
||||
|
||||
char letter[POST_BUFF_LEN] = "";
|
||||
snprintf(letter, POST_BUFF_LEN, "[%03d%03d%01dX%05d%05d%05d%05d%02d]",
|
||||
pitch,
|
||||
velocity,
|
||||
onoff,
|
||||
x1,
|
||||
x2,
|
||||
x3,
|
||||
x4,
|
||||
ps);
|
||||
POSTMAN_SERIAL.print(letter);
|
||||
}
|
||||
}
|
||||
|
||||
//task
|
||||
#include <TaskScheduler.h>
|
||||
Scheduler runner;
|
||||
void osc_listen () {
|
||||
//
|
||||
static OSCBundle bundleIN;
|
||||
int size = 0;
|
||||
while (!SLIPSerial.endofPacket()) {
|
||||
if ((size = SLIPSerial.available()) > 0) {
|
||||
while(size--) {
|
||||
bundleIN.fill(SLIPSerial.read());
|
||||
}
|
||||
}
|
||||
}
|
||||
//
|
||||
if(!bundleIN.hasError()) {
|
||||
bundleIN.route("/note", midinote);
|
||||
//
|
||||
bundleIN.empty();
|
||||
}
|
||||
}
|
||||
Task osc_listen_task(0, TASK_FOREVER, osc_listen, &runner, true); // aInterval == 0 >>> immediately re-schedule ?
|
||||
//
|
||||
// OSCBundle bundleIN;
|
||||
// int size;
|
||||
//
|
||||
// while(!SLIPSerial.endofPacket())
|
||||
// if( (size =SLIPSerial.available()) > 0)
|
||||
// {
|
||||
// while(size--)
|
||||
// bundleIN.fill(SLIPSerial.read());
|
||||
// }
|
||||
//
|
||||
// if(!bundleIN.hasError())
|
||||
// bundleIN.dispatch("/led", LEDcontrol);
|
||||
//
|
||||
|
||||
void postman_talk () {
|
||||
//
|
||||
static bool insync = false;
|
||||
if (insync == false) {
|
||||
int size;
|
||||
if ((size = POSTMAN_SERIAL.available()) > 0) {
|
||||
char last = '.';
|
||||
while(size--) {
|
||||
// get the last byte
|
||||
last = POSTMAN_SERIAL.read();
|
||||
}
|
||||
// expectable last of the messages
|
||||
if (last == ']' || last == '}') {
|
||||
insync = true;
|
||||
}
|
||||
}
|
||||
} else if (insync == true) {
|
||||
|
||||
if (POSTMAN_SERIAL.available() > POST_LENGTH) {
|
||||
char cstr[POST_BUFF_LEN] = "................................";
|
||||
// fetch all the bytes
|
||||
POSTMAN_SERIAL.readBytes(cstr, POST_LENGTH);
|
||||
// protocol checks
|
||||
char first = cstr[0];
|
||||
char last = cstr[POST_LENGTH-1];
|
||||
if (first != '[' && first != '{') {
|
||||
insync = false;
|
||||
return; //error!!
|
||||
}
|
||||
if (last != ']' && last != '}') {
|
||||
insync = false;
|
||||
return; //error!!
|
||||
}
|
||||
|
||||
//// OK -> parse && compose & send OSC message!
|
||||
|
||||
String msg = String(cstr);
|
||||
|
||||
// hello frame ( '{' + 30 bytes + '}' )
|
||||
// : {123456789012345678901234567890}
|
||||
|
||||
// hello frame
|
||||
// : {123456789012345678901234567890}
|
||||
// : {IIIA111111222222333333444444__}
|
||||
// : III - ID_KEY
|
||||
// .substring(1, 4);
|
||||
// : 1 - data of 6 letters
|
||||
// .substring(9, 14);
|
||||
// : 2 - data of 6 letters
|
||||
// .substring(14, 19);
|
||||
// : 3 - data of 6 letters
|
||||
// .substring(19, 24);
|
||||
// : 4 - data of 6 letters
|
||||
// .substring(24, 29);
|
||||
|
||||
// received a hello.
|
||||
String str_id = msg.substring(1, 4);
|
||||
int id = str_id.toInt();
|
||||
|
||||
//
|
||||
OSCMessage hello("/hello");
|
||||
hello.add(id);
|
||||
|
||||
//
|
||||
String str_aa = msg.substring(4, 5);
|
||||
|
||||
//
|
||||
if (str_aa == "A") {
|
||||
//
|
||||
String str_h1 = msg.substring(5, 11);
|
||||
String str_h2 = msg.substring(11, 17);
|
||||
String str_h3 = msg.substring(17, 23);
|
||||
String str_h4 = msg.substring(23, 29);
|
||||
|
||||
//
|
||||
hello.add(str_h1.toInt());
|
||||
hello.add(str_h2.toInt());
|
||||
hello.add(str_h3.toInt());
|
||||
hello.add(str_h4.toInt());
|
||||
}
|
||||
|
||||
//
|
||||
SLIPSerial.beginPacket();
|
||||
hello.send(SLIPSerial);
|
||||
SLIPSerial.endPacket();
|
||||
hello.empty();
|
||||
}
|
||||
}
|
||||
}
|
||||
Task postman_talk_task(0, TASK_FOREVER, postman_talk, &runner, true); // aInterval == 0 >>> immediately re-schedule ?
|
||||
|
||||
//
|
||||
void setup() {
|
||||
//osc
|
||||
SLIPSerial.begin(57600);
|
||||
|
||||
//
|
||||
POSTMAN_SERIAL.begin(115200);
|
||||
}
|
||||
|
||||
//
|
||||
void loop() {
|
||||
runner.execute();
|
||||
}
|
||||
|
|
@ -15,6 +15,8 @@ env_default = teensy36
|
|||
lib_deps =
|
||||
721@3.0.2 ; TaskScheduler
|
||||
|
||||
; osc -> (already included in "framework-arduinoteensy")
|
||||
|
||||
[env:teensy35]
|
||||
platform = teensy@3.6.0
|
||||
board = teensy35
|
||||
|
|
|
|||
239
osc/src/main.cpp
239
osc/src/main.cpp
|
|
@ -1,129 +1,41 @@
|
|||
//
|
||||
// wirelessly connected cloud (Wireless Mesh Networking)
|
||||
// MIDI-like
|
||||
// spacial
|
||||
// sampler keyboard
|
||||
//
|
||||
|
||||
//
|
||||
// Forest all/around @ MMCA, Seoul
|
||||
// Conversations about the ROOT @ SEMA warehouses, Seoul
|
||||
//
|
||||
|
||||
//
|
||||
// 2019 12 11
|
||||
// 2021 02 15
|
||||
//
|
||||
// (part-2) teensy35 : 'client:osc' (osc over slip --> mesh post)
|
||||
//
|
||||
// especially, MIDI-like.
|
||||
// collect following OSC msg.
|
||||
//
|
||||
// "/note/onoff"
|
||||
// "/note/velocity"
|
||||
// "/note/key"
|
||||
//
|
||||
// and build a MIDI-like letter post.
|
||||
// and give it to the postman
|
||||
//
|
||||
|
||||
//
|
||||
// --[post]--> "sampler"
|
||||
//
|
||||
// letter frame ( '[' + 30 bytes + ']' )
|
||||
// : [123456789012345678901234567890]
|
||||
// 'MIDI' letter frame
|
||||
// : [123456789012345678901234567890]
|
||||
// : [KKKVVVG.......................]
|
||||
// : KKK - Key
|
||||
// .substring(1, 4);
|
||||
// : VVV - Velocity (volume/amp.)
|
||||
// .substring(4, 7);
|
||||
// : G - Gate (note on/off)
|
||||
// .substring(7, 8);
|
||||
//
|
||||
|
||||
//
|
||||
// 2021 01 10
|
||||
//
|
||||
|
||||
// : [_______X......................]
|
||||
// : X - Extension starter 'X'
|
||||
// .substring(8, 9);
|
||||
|
||||
// "/note/x1" (4 digit)
|
||||
// "/note/x2" (4 digit)
|
||||
// "/note/x3" (3 digit)
|
||||
// "/note/x4" (3 digit)
|
||||
// "/note/x5" (2 digit)
|
||||
// "/note/x6" (2 digit)
|
||||
// "/note/x7" (2 digit)
|
||||
// "/note/x8" (2 digit)
|
||||
|
||||
// Extension (X == 'X')
|
||||
// : [_______X1111222233344455667788]
|
||||
// : 1 - data of 4 letters
|
||||
// .substring(9, 13);
|
||||
// : 2 - data of 4 letters
|
||||
// .substring(13, 17);
|
||||
// : 3 - data of 3 letters
|
||||
// .substring(17, 20);
|
||||
// : 4 - data of 3 letters
|
||||
// .substring(20, 23);
|
||||
// : 5 - data of 2 letters
|
||||
// .substring(23, 25);
|
||||
// : 6 - data of 2 letters
|
||||
// .substring(25, 27);
|
||||
// : 7 - data of 2 letters
|
||||
// .substring(27, 29);
|
||||
// : 8 - data of 2 letters
|
||||
// .substring(29, 31);
|
||||
|
||||
//arduino
|
||||
#include <Arduino.h>
|
||||
|
||||
//osc
|
||||
//osc (already included in "framework-arduinoteensy")
|
||||
#include <OSCBundle.h>
|
||||
#include <SLIPEncodedUSBSerial.h>
|
||||
SLIPEncodedUSBSerial SLIPSerial(Serial);
|
||||
|
||||
//i2c
|
||||
#include <Wire.h>
|
||||
//post definition
|
||||
#include "../../post.h"
|
||||
|
||||
//postman's uart
|
||||
#define POSTMAN_SERIAL (Serial3)
|
||||
|
||||
// --[post]--> "sampler"
|
||||
#include "../../sampler/post_sampler.h"
|
||||
void receiveEvent(int howMany) {
|
||||
// nothing to expect.. but.. let's just print out..
|
||||
// while (Wire.available())
|
||||
// Serial.print(Wire.read());
|
||||
// Serial.println();
|
||||
}
|
||||
// well. i don't know how fast should i be able to send msg.. to the net..
|
||||
// first test, and then.. if needed. will come back.
|
||||
bool new_letter = false;
|
||||
char letter_outro[POST_BUFF_LEN] = "................................";
|
||||
void letter_outro_clear() {
|
||||
// clear the letter buff
|
||||
letter_outro[0] = '[';
|
||||
for (int i = 1; i < POST_LENGTH-1; i++) letter_outro[i] = '.';
|
||||
letter_outro[POST_LENGTH-1] = ']';
|
||||
}
|
||||
void requestEvent() {
|
||||
if (new_letter) {
|
||||
Wire.write(letter_outro, POST_LENGTH);
|
||||
new_letter = false;
|
||||
} else {
|
||||
Wire.write(" "); // no letter to send
|
||||
}
|
||||
}
|
||||
void I2CPrint(const String & str); // for DEBUG w/ I2C
|
||||
#include "../../post.h"
|
||||
|
||||
//
|
||||
void setup() {
|
||||
//i2c
|
||||
Wire.begin(I2C_ADDR);
|
||||
Wire.onRequest(requestEvent);
|
||||
Wire.onReceive(receiveEvent);
|
||||
|
||||
//osc
|
||||
SLIPSerial.begin(57600);
|
||||
|
||||
//
|
||||
POSTMAN_SERIAL.begin(115200);
|
||||
}
|
||||
|
||||
//
|
||||
|
|
@ -136,10 +48,7 @@ void midinote(OSCMessage& msg, int offset) {
|
|||
static int x2 = 0;
|
||||
static int x3 = 0;
|
||||
static int x4 = 0;
|
||||
static int x5 = 0;
|
||||
static int x6 = 0;
|
||||
static int x7 = 0;
|
||||
static int x8 = 0;
|
||||
static int ps = 0;
|
||||
// (1) --> /onoff
|
||||
if (msg.fullMatch("/onoff", offset)) {
|
||||
//
|
||||
|
|
@ -154,14 +63,12 @@ void midinote(OSCMessage& msg, int offset) {
|
|||
if (msg.fullMatch("/velocity", offset)) {
|
||||
velocity = msg.getInt(0);
|
||||
if (velocity < 0) velocity = 0;
|
||||
// if (velocity > 127) velocity = 127;
|
||||
if (velocity > 999) velocity = 999;
|
||||
}
|
||||
// (3) --> /pitch
|
||||
if (msg.fullMatch("/pitch", offset)) {
|
||||
pitch = msg.getInt(0);
|
||||
if (pitch < 0) pitch = 0;
|
||||
// if (pitch > 127) pitch = 127;
|
||||
if (pitch > 999) pitch = 999;
|
||||
}
|
||||
// (4) --> /x
|
||||
|
|
@ -170,13 +77,10 @@ void midinote(OSCMessage& msg, int offset) {
|
|||
x2 = msg.getInt(1);
|
||||
x3 = msg.getInt(2);
|
||||
x4 = msg.getInt(3);
|
||||
x5 = msg.getInt(4);
|
||||
x6 = msg.getInt(5);
|
||||
x7 = msg.getInt(6);
|
||||
x8 = msg.getInt(7);
|
||||
ps = msg.getInt(4);
|
||||
|
||||
// while (new_letter != false) {}; // <-- sort of semaphore.. but it doesn't work yet.. buggy.
|
||||
sprintf(letter_outro, "[%03d%03d%01dX%04d%04d%03d%03d%02d%02d%02d%02d]",
|
||||
char letter[POST_BUFF_LEN] = "";
|
||||
snprintf(letter, POST_BUFF_LEN, "[%03d%03d%01dX%05d%05d%05d%05d%02d]",
|
||||
pitch,
|
||||
velocity,
|
||||
onoff,
|
||||
|
|
@ -184,20 +88,18 @@ void midinote(OSCMessage& msg, int offset) {
|
|||
x2,
|
||||
x3,
|
||||
x4,
|
||||
x5,
|
||||
x6,
|
||||
x7,
|
||||
x8);
|
||||
new_letter = true;
|
||||
ps);
|
||||
POSTMAN_SERIAL.print(letter);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
void loop() {
|
||||
static String str = "";
|
||||
|
||||
//osc
|
||||
OSCBundle bundleIN;
|
||||
int size;
|
||||
if (SLIPSerial.available()) {
|
||||
while(!SLIPSerial.endofPacket()) {
|
||||
if( (size = SLIPSerial.available()) > 0) {
|
||||
while(size--) {
|
||||
|
|
@ -208,28 +110,85 @@ void loop() {
|
|||
if(!bundleIN.hasError()) {
|
||||
bundleIN.route("/note", midinote);
|
||||
}
|
||||
// else {
|
||||
// str = "error! : " + String(bundleIN.getError());
|
||||
// I2CPrint(str);
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
//==========<I2CPrint>==========
|
||||
// utility func. -> for DEBUG w/ I2C
|
||||
char buff[POST_LENGTH] = "";
|
||||
void I2CPrint(const String & str) {
|
||||
const char * buff = str.c_str();
|
||||
int len = str.length();
|
||||
// while (new_letter != false) {};
|
||||
letter_outro[0] = '[';
|
||||
if (len > (POST_LENGTH - 2)) len = (POST_LENGTH - 2);
|
||||
for (int i = 0; i < len; i++) {
|
||||
letter_outro[i+1] = buff[i];
|
||||
//postman (serial comm.)
|
||||
static bool insync = false;
|
||||
if (insync == false) {
|
||||
while (POSTMAN_SERIAL.available() > 0) {
|
||||
// check the last byte
|
||||
char last = POSTMAN_SERIAL.read();
|
||||
// expectable last of the messages
|
||||
if (last == ']' || last == '}') {
|
||||
insync = true;
|
||||
}
|
||||
for (int j = len; j < (POST_LENGTH - 2); j++) {
|
||||
letter_outro[j+1] = '_';
|
||||
}
|
||||
letter_outro[POST_LENGTH-1] = ']';
|
||||
new_letter = true;
|
||||
}
|
||||
if (POSTMAN_SERIAL.available() > POST_LENGTH) {
|
||||
char cstr[POST_BUFF_LEN] = "................................";
|
||||
// fetch all the bytes
|
||||
POSTMAN_SERIAL.readBytes(cstr, POST_LENGTH);
|
||||
// protocol checks
|
||||
char first = cstr[0];
|
||||
char last = cstr[POST_LENGTH-1];
|
||||
if (first != '[' && first != '{') {
|
||||
insync = false;
|
||||
}
|
||||
if (last != ']' && last != '}') {
|
||||
insync = false;
|
||||
}
|
||||
|
||||
//// OK -> parse && compose & send OSC message!
|
||||
|
||||
String msg = String(cstr);
|
||||
|
||||
// hello frame ( '{' + 30 bytes + '}' )
|
||||
// : {123456789012345678901234567890}
|
||||
|
||||
// hello frame
|
||||
// : {123456789012345678901234567890}
|
||||
// : {IIIA111111222222333333444444__}
|
||||
// : III - ID_KEY
|
||||
// .substring(1, 4);
|
||||
// : 1 - data of 6 letters
|
||||
// .substring(9, 14);
|
||||
// : 2 - data of 6 letters
|
||||
// .substring(14, 19);
|
||||
// : 3 - data of 6 letters
|
||||
// .substring(19, 24);
|
||||
// : 4 - data of 6 letters
|
||||
// .substring(24, 29);
|
||||
|
||||
// received a hello.
|
||||
String str_id = msg.substring(1, 4);
|
||||
int id = str_id.toInt();
|
||||
|
||||
//
|
||||
OSCMessage hello("/hello");
|
||||
hello.add(id);
|
||||
|
||||
//
|
||||
String str_aa = msg.substring(4, 5);
|
||||
|
||||
//
|
||||
if (str_aa == "A") {
|
||||
//
|
||||
String str_h1 = msg.substring(5, 11);
|
||||
String str_h2 = msg.substring(11, 17);
|
||||
String str_h3 = msg.substring(17, 23);
|
||||
String str_h4 = msg.substring(23, 29);
|
||||
|
||||
//
|
||||
hello.add(str_h1.toInt());
|
||||
hello.add(str_h2.toInt());
|
||||
hello.add(str_h3.toInt());
|
||||
hello.add(str_h4.toInt());
|
||||
}
|
||||
|
||||
//
|
||||
SLIPSerial.beginPacket();
|
||||
hello.send(SLIPSerial);
|
||||
SLIPSerial.endPacket();
|
||||
hello.empty();
|
||||
}
|
||||
}
|
||||
//==========</I2CPrint>=========
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@
|
|||
//============</list of reserved keys>===========
|
||||
|
||||
//============<identity key>============
|
||||
#define ID_KEY ROUNDLY_E_KEY
|
||||
#define ID_KEY ROUNDLY_I_KEY
|
||||
//============</identity key>===========
|
||||
|
||||
//============<parameters>============
|
||||
|
|
@ -229,12 +229,45 @@ void rest() {
|
|||
}
|
||||
Task rest_task(1000, TASK_FOREVER, &rest);
|
||||
|
||||
//sendhello - with 4 int // up to 6 letters for each
|
||||
void sendhello (int hey0 = 0, int hey1 = 0, int hey2 = 0, int hey3 = 0) {
|
||||
char msg_cstr[32+1] = "{/././././././././././././././.}";
|
||||
snprintf(msg_cstr, 32+1, "{%03dA%06d%06d%06d%06d__}", ID_KEY, hey0, hey1, hey2, hey3);
|
||||
mesh.sendBroadcast(String(msg_cstr));
|
||||
}
|
||||
|
||||
//
|
||||
String letter_ps = "00";
|
||||
|
||||
//
|
||||
extern Task hello_task;
|
||||
void hello() {
|
||||
//
|
||||
sendhello(
|
||||
stepper.currentPosition(),
|
||||
stepper.distanceToGo(),
|
||||
stepper.distanceToGo(),
|
||||
stepper.distanceToGo()
|
||||
);
|
||||
//
|
||||
int ps_int = letter_ps.toInt();
|
||||
if (ps_int > 0) {
|
||||
hello_task.restartDelayed(ps_int * 100);
|
||||
}
|
||||
}
|
||||
Task hello_task(0, TASK_ONCE, &hello);
|
||||
|
||||
// mesh callbacks
|
||||
void receivedCallback(uint32_t from, String & msg) { // REQUIRED
|
||||
Serial.print("got msg.: ");
|
||||
Serial.println(msg);
|
||||
//parse now.
|
||||
|
||||
String str_type = msg.substring(0, 1);
|
||||
|
||||
// [letter...] >>> START
|
||||
if (str_type == "[") {
|
||||
|
||||
//parse letter string.
|
||||
|
||||
// letter frame ( '[' + 30 bytes + ']' )
|
||||
|
|
@ -258,37 +291,36 @@ void receivedCallback(uint32_t from, String & msg) { // REQUIRED
|
|||
int velocity = str_velocity.toInt(); // 0 ~ 127
|
||||
int gate = str_gate.toInt();
|
||||
|
||||
//is it for me?
|
||||
if (key == ID_KEY) {
|
||||
|
||||
// : [_______X......................]
|
||||
// : X - Extension starter 'X'
|
||||
// .substring(8, 9);
|
||||
// Extension (X == 'X')
|
||||
// : [_______X1111222233344455667788]
|
||||
// : 1 - data of 4 letters
|
||||
// .substring(9, 13);
|
||||
// : 2 - data of 4 letters
|
||||
// .substring(13, 17);
|
||||
// : 3 - data of 3 letters
|
||||
// .substring(17, 20);
|
||||
// : 4 - data of 3 letters
|
||||
// .substring(20, 23);
|
||||
// : 5 - data of 2 letters
|
||||
// .substring(23, 25);
|
||||
// : 6 - data of 2 letters
|
||||
// .substring(25, 27);
|
||||
// : 7 - data of 2 letters
|
||||
// .substring(27, 29);
|
||||
// : 8 - data of 2 letters
|
||||
// : [_______X11111222223333344444PS]
|
||||
// : 1 - data of 5 letters
|
||||
// .substring(9, 14);
|
||||
// : 2 - data of 5 letters
|
||||
// .substring(14, 19);
|
||||
// : 3 - data of 5 letters
|
||||
// .substring(19, 24);
|
||||
// : 4 - data of 5 letters
|
||||
// .substring(24, 29);
|
||||
// : PS - 2 letter
|
||||
// .substring(29, 31);
|
||||
|
||||
String str_ext = msg.substring(8, 9);
|
||||
String str_x1 = msg.substring(9, 13);
|
||||
String str_x2 = msg.substring(13, 17);
|
||||
String str_x3 = msg.substring(17, 20);
|
||||
String str_x4 = msg.substring(20, 23);
|
||||
String str_x5 = msg.substring(23, 25);
|
||||
String str_x6 = msg.substring(25, 27);
|
||||
String str_x7 = msg.substring(27, 29);
|
||||
String str_x8 = msg.substring(29, 31);
|
||||
//
|
||||
String str_x1 = msg.substring(9, 14);
|
||||
String str_x2 = msg.substring(14, 19);
|
||||
String str_x3 = msg.substring(19, 24);
|
||||
String str_x4 = msg.substring(24, 29);
|
||||
// p. s.
|
||||
letter_ps = msg.substring(29, 31);
|
||||
if (letter_ps.toInt() > 0) {
|
||||
hello_task.restartDelayed(10);
|
||||
}
|
||||
|
||||
if (str_ext == "X") {
|
||||
int step_target_multiplier = str_x3.toInt(); // -99 ~ 999
|
||||
|
|
@ -296,14 +328,61 @@ void receivedCallback(uint32_t from, String & msg) { // REQUIRED
|
|||
step_duration = str_x2.toInt(); // -999 ~ 9999
|
||||
}
|
||||
|
||||
//is it for me?
|
||||
if (key == ID_KEY) {
|
||||
//
|
||||
if (gate == 1) {
|
||||
stepping_task.restartDelayed(10);
|
||||
} else if (gate == 0) {
|
||||
rest_task.restartDelayed(10);
|
||||
}
|
||||
}
|
||||
}
|
||||
//END <<< [letter...]
|
||||
|
||||
//{hello...} >>> START
|
||||
else if (str_type == "{") {
|
||||
// hello frame ( '{' + 30 bytes + '}' )
|
||||
// : {123456789012345678901234567890}
|
||||
|
||||
// hello frame
|
||||
// : {123456789012345678901234567890}
|
||||
// : {IIIA111111222222333333444444__}
|
||||
// : III - ID_KEY
|
||||
// .substring(1, 4);
|
||||
// : 1 - data of 6 letters
|
||||
// .substring(9, 14);
|
||||
// : 2 - data of 6 letters
|
||||
// .substring(14, 19);
|
||||
// : 3 - data of 6 letters
|
||||
// .substring(19, 24);
|
||||
// : 4 - data of 6 letters
|
||||
// .substring(24, 29);
|
||||
|
||||
// received a hello.
|
||||
String str_id = msg.substring(1, 4);
|
||||
int id = str_id.toInt();
|
||||
|
||||
//is it for me?
|
||||
if (id == ID_KEY) {
|
||||
|
||||
//
|
||||
String str_aa = msg.substring(4, 5);
|
||||
|
||||
//
|
||||
String str_h1 = msg.substring(5, 11);
|
||||
String str_h2 = msg.substring(11, 17);
|
||||
String str_h3 = msg.substring(17, 23);
|
||||
String str_h4 = msg.substring(23, 29);
|
||||
|
||||
//
|
||||
if (str_aa == "A") {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
//END <<< {hello...}
|
||||
|
||||
}
|
||||
void changedConnectionCallback() {
|
||||
Serial.println(mesh.getNodeList().size());
|
||||
|
|
@ -437,6 +516,7 @@ void setup() {
|
|||
//tasks
|
||||
runner.addTask(stepping_task);
|
||||
runner.addTask(rest_task);
|
||||
runner.addTask(hello_task);
|
||||
|
||||
rest_task.restartDelayed(500);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,17 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include "../post.h"
|
||||
|
||||
//
|
||||
// letter frame ( '[' + 30 bytes + ']' )
|
||||
// : [123456789012345678901234567890]
|
||||
// 'MIDI' letter frame
|
||||
// : [123456789012345678901234567890]
|
||||
// : [KKKVVVG.......................]
|
||||
// : KKK - Key
|
||||
// .substring(1, 4);
|
||||
// : VVV - Velocity (volume/amp.)
|
||||
// .substring(4, 7);
|
||||
// : G - Gate (note on/off)
|
||||
// .substring(7, 8);
|
||||
//
|
||||
|
|
@ -144,7 +144,7 @@ Task sample_player_check_task(0, TASK_FOREVER, sample_player_check, &runner, tru
|
|||
|
||||
//i2c
|
||||
#include <Wire.h>
|
||||
#include "../post_sampler.h"
|
||||
#include "../../post.h"
|
||||
// DISABLED.. due to bi-directional I2C hardship. ==> use UART.
|
||||
// void requestEvent() {
|
||||
// Wire.write(" "); // no letter to send
|
||||
|
|
|
|||
113
src/main.cpp
113
src/main.cpp
|
|
@ -1,16 +1,13 @@
|
|||
//
|
||||
// wirelessly connected cloud (Wireless Mesh Networking)
|
||||
// MIDI-like
|
||||
// spacial
|
||||
// sampler keyboard
|
||||
//
|
||||
|
||||
//
|
||||
// Forest all/around @ MMCA, Seoul
|
||||
// Conversation about the ROOT @ SEMA warehouses, Seoul
|
||||
//
|
||||
|
||||
//
|
||||
// 2019 12 10
|
||||
// 2021 02 15
|
||||
//
|
||||
// (part-1) esp8266 : 'postman' (the mesh network nodes)
|
||||
//
|
||||
|
|
@ -26,15 +23,14 @@
|
|||
// we can broadcast/unicast/recv. msg. w/ meshID and nodelist
|
||||
// so, let's just use it.
|
||||
//
|
||||
// but one specific thing is that we will use I2C comm. to feed this postman.
|
||||
// and I2C is a FIXED-length msg.
|
||||
// so, at least, we need to fix this length of the msg.
|
||||
// otherwise, we need to do variable-length comm. like uart. to feed/fetch msg. from postman.
|
||||
// but one specific thing is that we had used I2C comm. to feed this postman.
|
||||
// and I2C was a FIXED-length msg.
|
||||
//
|
||||
// well, okay. but, let's just do.. I2C. and fix a length.
|
||||
// maybe, ... 32 bytes?
|
||||
// so, then, this postman will read/write I2C channel. always.. 32 bytes.
|
||||
// and then, this 32 bytes will be flying in the clouds.
|
||||
// but we will use UART instead of I2C, because I2C was not feasible for true bi-directional comm. between teensy <-> esp8266
|
||||
// that's a thing of board-specific. in general it should be ok. but this particular case, it was hard to solve.
|
||||
//
|
||||
// yet, we were very satisfied with previous 'fixed length (32 bytes)' comm.
|
||||
// so even though we are free to use variable-length messages, since using UART comm., we want to stick to that 'fixed-length' frame defs.
|
||||
//
|
||||
|
||||
//==========<configurations>===========
|
||||
|
|
@ -46,12 +42,8 @@
|
|||
// we need who can do AP..
|
||||
// ==> TODO! just prepare some 'dummy' postmans around. w/ AP activated.
|
||||
//
|
||||
// 'DISABLE_I2C_REQ'
|
||||
// --> a quirk.. due to bi-directional I2C hardship.
|
||||
// ideally, we want to make this sampler node also speak.
|
||||
// but, I2C doesn't work. maybe middleware bug.. we later want to change to diff. proto.
|
||||
// for example, UART or so.
|
||||
// ==> BEWARE! yet, still we need to take off this.. for 'osc' node.
|
||||
// 'DISABLE_I2C_REQ' (DEPRECATED)
|
||||
// --> DEPRECATED: we are not using I2C anymore.
|
||||
//
|
||||
// 'SET_ROOT'
|
||||
// 'SET_CONTAINSROOT'
|
||||
|
|
@ -64,7 +56,6 @@
|
|||
//==========<preset>===========
|
||||
// (1) the backbone AP
|
||||
#if 0
|
||||
#define DISABLE_I2C_REQ
|
||||
#define SET_CONTAINSROOT
|
||||
// (2) osc client (the ROOT)
|
||||
#elif 0
|
||||
|
|
@ -77,7 +68,6 @@
|
|||
// (3) sampler client
|
||||
#elif 1
|
||||
#define DISABLE_AP
|
||||
#define DISABLE_I2C_REQ
|
||||
//
|
||||
#endif
|
||||
//==========</preset>==========
|
||||
|
|
@ -88,6 +78,7 @@
|
|||
#define MESH_PORT 5555
|
||||
#define MESH_CHANNEL 5
|
||||
#define LONELY_TO_DIE (1000)
|
||||
#define MONITORING_SERIAL (Serial1) //you should use, external uart2usb converter to monitor messages...
|
||||
//============</parameters>===========
|
||||
|
||||
//
|
||||
|
|
@ -116,8 +107,8 @@
|
|||
//arduino
|
||||
#include <Arduino.h>
|
||||
|
||||
//i2c
|
||||
#include <Wire.h>
|
||||
//protocol
|
||||
// #include <Wire.h>
|
||||
#include "../post.h"
|
||||
|
||||
//painlessmesh
|
||||
|
|
@ -165,14 +156,14 @@ void nothappyalone() {
|
|||
// oh.. i m lost the signal(==connection)
|
||||
if (isConnected_prev != isConnected && isConnected == false) {
|
||||
lonely_time_start = millis();
|
||||
Serial.println("oh.. i m lost!");
|
||||
MONITORING_SERIAL.println("oh.. i m lost!");
|
||||
}
|
||||
// .... how long we've been lonely?
|
||||
if (isConnected == false) {
|
||||
if (millis() - lonely_time_start > LONELY_TO_DIE) {
|
||||
// okay. i m fed up. bye the world.
|
||||
Serial.println("okay. i m fed up. bye the world.");
|
||||
Serial.println();
|
||||
MONITORING_SERIAL.println("okay. i m fed up. bye the world.");
|
||||
MONITORING_SERIAL.println();
|
||||
#if defined(ESP8266)
|
||||
ESP.reset();
|
||||
#elif defined(ESP32)
|
||||
|
|
@ -191,61 +182,58 @@ void nothappyalone() {
|
|||
Task nothappyalone_task(100, TASK_FOREVER, ¬happyalone); // by default, ENABLED.
|
||||
|
||||
//task #2 : regular post collection
|
||||
#if !defined(DISABLE_I2C_REQ)
|
||||
void collect_post() {
|
||||
//
|
||||
static char letter_outro[POST_BUFF_LEN] = "................................";
|
||||
// ask a letter and collect the feedback.
|
||||
Wire.requestFrom(I2C_ADDR, POST_LENGTH);
|
||||
// error flag
|
||||
bool letter_is_good = false;
|
||||
// check the first byte
|
||||
char first = '.';
|
||||
// automatically match start byte.
|
||||
while (Wire.available()) {
|
||||
first = Wire.read();
|
||||
if (first == '[') {
|
||||
// client want to give me a letter.
|
||||
while (Serial.available()) {
|
||||
first = Serial.read();
|
||||
if (first == '[' || first == '{') {
|
||||
// client want to give me a letter or hello.
|
||||
letter_outro[0] = first;
|
||||
// matched!
|
||||
letter_is_good = true;
|
||||
break;
|
||||
} else if (first == ' ') {
|
||||
// client says nothing to send.
|
||||
Serial.print("."); // nothing to send.
|
||||
MONITORING_SERIAL.print("."); // nothing to send.
|
||||
return;
|
||||
}
|
||||
}
|
||||
//
|
||||
if (letter_is_good == false) {
|
||||
// no more letters, but no valid char.
|
||||
Serial.print("?"); // wrong client.
|
||||
MONITORING_SERIAL.print("?"); // wrong client.
|
||||
return;
|
||||
} else if (letter_is_good == true) {
|
||||
// get more contents
|
||||
for (int i = 1; i < (POST_LENGTH-1); i++) {
|
||||
if (Wire.available()) {
|
||||
letter_outro[i] = Wire.read();
|
||||
if (Serial.available()) {
|
||||
letter_outro[i] = Serial.read();
|
||||
} else {
|
||||
// hmm.. letter is too short.
|
||||
letter_outro[i] = '.'; // fill-out with dots.
|
||||
Serial.print("$"); // too $hort msg.
|
||||
MONITORING_SERIAL.print("$"); // too $hort msg.
|
||||
letter_is_good = false;
|
||||
}
|
||||
}
|
||||
// the last byte
|
||||
char last = '.';
|
||||
if (Wire.available()) {
|
||||
letter_outro[POST_LENGTH-1] = last = Wire.read();
|
||||
if (last != ']') {
|
||||
if (Serial.available()) {
|
||||
letter_outro[POST_LENGTH-1] = last = Serial.read();
|
||||
if (last != ']' && last != '}') {
|
||||
// hmm.. last byte is strange
|
||||
Serial.print("#"); // last byte error.
|
||||
MONITORING_SERIAL.print("#"); // last byte error.
|
||||
letter_is_good = false;
|
||||
}
|
||||
} else {
|
||||
// hmm.. letter is too short.
|
||||
letter_outro[POST_LENGTH-1] = '.'; // fill-out with dots.
|
||||
Serial.print("$"); // too $hort msg.
|
||||
MONITORING_SERIAL.print("$"); // too $hort msg.
|
||||
letter_is_good = false;
|
||||
}
|
||||
// terminal char.
|
||||
|
|
@ -258,33 +246,30 @@ void collect_post() {
|
|||
// or, post it.
|
||||
if (isConnected == true) {
|
||||
mesh.sendBroadcast(String(letter_outro));
|
||||
Serial.print("sendBroadcast: ");
|
||||
Serial.println(letter_outro);
|
||||
MONITORING_SERIAL.print("sendBroadcast: ");
|
||||
MONITORING_SERIAL.println(letter_outro);
|
||||
} else {
|
||||
Serial.print("_"); // disconnected.
|
||||
MONITORING_SERIAL.print("_"); // disconnected.
|
||||
}
|
||||
}
|
||||
Task collect_post_task(10, TASK_FOREVER, &collect_post, &runner, true); // by default, ENABLED
|
||||
//MAYBE... 10ms is too fast? move this to the loop() then?
|
||||
#endif
|
||||
|
||||
// mesh callbacks
|
||||
void receivedCallback(uint32_t from, String & msg) { // REQUIRED
|
||||
Serial.print("got msg.: ");
|
||||
Serial.println(msg);
|
||||
MONITORING_SERIAL.print("got msg.: ");
|
||||
MONITORING_SERIAL.println(msg);
|
||||
// truncate any extra. letters.
|
||||
msg = msg.substring(0, POST_LENGTH); // (0) ~ (POST_LENGTH-1)
|
||||
// send whatever letter we postmans trust other postman.
|
||||
Wire.beginTransmission(I2C_ADDR);
|
||||
#if defined(ARDUINO_NodeMCU_32S)
|
||||
Wire.write((const uint8_t*)msg.c_str(), POST_LENGTH);
|
||||
Serial.write((const uint8_t*)msg.c_str(), POST_LENGTH);
|
||||
#else
|
||||
Wire.write(msg.c_str(), POST_LENGTH);
|
||||
Serial.write(msg.c_str(), POST_LENGTH);
|
||||
#endif
|
||||
Wire.endTransmission();
|
||||
}
|
||||
void changedConnectionCallback() {
|
||||
Serial.println(mesh.getNodeList().size());
|
||||
MONITORING_SERIAL.println(mesh.getNodeList().size());
|
||||
// check status -> modify status LED
|
||||
if (mesh.getNodeList().size() > 0) {
|
||||
// (still) connected.
|
||||
|
|
@ -292,7 +277,7 @@ void changedConnectionCallback() {
|
|||
statusblinks.set(LED_PERIOD, 2, &taskStatusBlink_slowblink_insync);
|
||||
// statusblinks.set(0, 1, &taskStatusBlink_steadyOff);
|
||||
statusblinks.enable();
|
||||
Serial.println("connected!");
|
||||
MONITORING_SERIAL.println("connected!");
|
||||
//
|
||||
isConnected = true;
|
||||
runner.addTask(nothappyalone_task);
|
||||
|
|
@ -305,13 +290,12 @@ void changedConnectionCallback() {
|
|||
//
|
||||
isConnected = false;
|
||||
}
|
||||
// let I2C device know
|
||||
/////
|
||||
Serial.println("hi. client, we ve got a change in the net.");
|
||||
//
|
||||
MONITORING_SERIAL.println("hi. client, we ve got a change in the net.");
|
||||
}
|
||||
void newConnectionCallback(uint32_t nodeId) {
|
||||
Serial.println(mesh.getNodeList().size());
|
||||
Serial.println("newConnectionCallback.");
|
||||
MONITORING_SERIAL.println(mesh.getNodeList().size());
|
||||
MONITORING_SERIAL.println("newConnectionCallback.");
|
||||
changedConnectionCallback();
|
||||
}
|
||||
|
||||
|
|
@ -344,7 +328,7 @@ void setup() {
|
|||
mesh.onReceive(&receivedCallback);
|
||||
mesh.onNewConnection(&newConnectionCallback);
|
||||
mesh.onChangedConnections(&changedConnectionCallback);
|
||||
Serial.println(mesh.getNodeList().size());
|
||||
MONITORING_SERIAL.println(mesh.getNodeList().size());
|
||||
|
||||
//tasks
|
||||
runner.addTask(statusblinks);
|
||||
|
|
@ -388,8 +372,11 @@ void setup() {
|
|||
// nodeId (hex) : 2D370A07
|
||||
// MAC : B6, E6, 2D, 37, A, 7
|
||||
|
||||
//i2c master
|
||||
Wire.begin();
|
||||
//esp8266(serial.swap) <-> teensy(serial3)
|
||||
delay(1000);
|
||||
Serial.swap();
|
||||
delay(100);
|
||||
// Serial.println("hi, uart. ping?");
|
||||
}
|
||||
|
||||
void loop() {
|
||||
|
|
|
|||
Loading…
Reference in a new issue