305 lines
11 KiB
C++
305 lines
11 KiB
C++
//
|
|
// wirelessly connected cloud or crowd
|
|
// over WIFI over Internet over Mountains
|
|
// across Rivers and into the Universe
|
|
//
|
|
|
|
//
|
|
// tailored for "Saekki-Chigi4"
|
|
// 2026 04 13 - Seoul
|
|
//
|
|
|
|
//
|
|
// NOTES
|
|
//
|
|
// taskscheduler 기반으로 cnmat/osc/udp 로 esp8266에서 led를 on/off 하는 sub장치를 만드는데.. taskscheduler는 우선 필요없지만.. .. ? 그렇네.. + wifimanager를 넣어주고.. arduinoota도 기본으로 넣어주고.. taskscheduler는.. 그러니까... 모터 움직임 패턴을 읽어서.. 그대로 모터를 한번 돌려주는 걸로하고... 읽는 시간 rate 일정한 값 + 패턴 값 저장하는 어레이 2개.. 모터 2개 드라이브. roller2..
|
|
//
|
|
// 1 taskschduler + array + roller2 기반.. reset되면 몇 초 후에.. 패턴 1을 재생하도록.
|
|
// 2 여기에 osc_udp 추가해서.. 외부에서, 패턴을 실행시킬 수 있도록. (pd로 osc로 전송)
|
|
// 3 pd에서 패턴값과.. 기본 파라미터를 조정하는 메세지 주기.. (+ 패턴값 체크하는 기능도 있으면 좋음...)
|
|
//
|
|
// -- 우선은 여기까지 하면, 갈수 있을지도 --
|
|
//
|
|
// 4 여기에 wifimanager를 더해서.. 외부에서, 와이파이 설정도 하고, 상태 업데이트 할 수 있도록. (근데 이걸 위해서, 특수한 버튼 눌러야 한다면 flash버튼을 이용해 보던가.)
|
|
// 5 이 모듈이 접속할 웹 공간 준비. 도메인 + 서비스. 그곳에 world energy 패치 준비.. (pd 여도 좋음.) - 아니면, 웹페이지여도 좋음. / 여기서 WE가 취합되고, 평균되고, 발표됨. 각 모듈은 이 값을 읽어감. (여기까지가 기존의 셋업 -> 인터넷으로 옮겨간 상태임.)
|
|
//
|
|
|
|
//arduino
|
|
#include <Arduino.h>
|
|
|
|
//osc over UDP
|
|
#include <ESP8266WiFi.h>
|
|
#include <WiFiUdp.h>
|
|
#include <OSCMessage.h>
|
|
#include <OSCBundle.h>
|
|
#include <OSCData.h>
|
|
//
|
|
WiFiUDP Udp;
|
|
//
|
|
const IPAddress outIp(192,168,88,100);
|
|
const unsigned int outPort = 9999;
|
|
const unsigned int localPort = 8888;
|
|
OSCErrorCode error;
|
|
////
|
|
unsigned int ledState = LOW;
|
|
////
|
|
char ssid[] = "nosignal 2G";
|
|
char pass[] = "1111100000";
|
|
|
|
//task
|
|
#include <TaskScheduler.h>
|
|
Scheduler runner;
|
|
|
|
//-*-*-*-*-*-*-*-*-*-*-*-*-
|
|
// servo
|
|
#define MOTOR_1A (D6)
|
|
#define MOTOR_1B (D5)
|
|
int speed = 0;
|
|
void set_speed() {
|
|
int r = speed;
|
|
//
|
|
if (r >= 0) {
|
|
digitalWrite(MOTOR_1A, LOW);
|
|
analogWrite(MOTOR_1B, r);
|
|
} else {
|
|
digitalWrite(MOTOR_1B, LOW);
|
|
analogWrite(MOTOR_1A, r*(-1));
|
|
}
|
|
Serial.print("set_speed:");
|
|
Serial.println(r);
|
|
}
|
|
Task set_speed_task(0, TASK_ONCE, &set_speed, &runner, false);
|
|
//
|
|
void rest() {
|
|
analogWrite(MOTOR_1A, LOW);
|
|
analogWrite(MOTOR_1B, LOW);
|
|
}
|
|
Task rest_task(0, TASK_ONCE, &rest, &runner, false);
|
|
//
|
|
#define MOTOR_2A (D3)
|
|
#define MOTOR_2B (D2)
|
|
int speed2 = 0;
|
|
void set_speed2() {
|
|
int r = speed2;
|
|
//
|
|
if (r >= 0) {
|
|
digitalWrite(MOTOR_2A, LOW);
|
|
analogWrite(MOTOR_2B, r);
|
|
} else {
|
|
digitalWrite(MOTOR_2B, LOW);
|
|
analogWrite(MOTOR_2A, r*(-1));
|
|
}
|
|
Serial.print("set_speed2:");
|
|
Serial.println(r);
|
|
}
|
|
Task set_speed2_task(0, TASK_ONCE, &set_speed2, &runner, false);
|
|
//
|
|
void rest2() {
|
|
analogWrite(MOTOR_2A, LOW);
|
|
analogWrite(MOTOR_2B, LOW);
|
|
}
|
|
Task rest2_task(0, TASK_ONCE, &rest2, &runner, false);
|
|
|
|
//expressions
|
|
std::vector<float> yellowA1 = {0.266667,0.285714,0.295238,0.32381,0.352381,0.371429,0.409525,
|
|
0.2,0.228572,0.257143,0.276191,0.285715,0.314286,0.32381,0.352382,0.37143,
|
|
0.390477,0.238095,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0.171429,0.209524,0.257143,
|
|
0.276191,0.304763,0.333334,0.342858,-0.00952393,-0.00952393,-0.00952393,
|
|
-0.00952393,-0.00952393,-0.00952393,-0.00952393,-0.00952393,-0.00952393,
|
|
-0.00952393,-0.00952393}; //50
|
|
|
|
std::vector<float> yellowA2 = {0.0380987,0.0380987,0.0380987,0.0476224,0.0571462,0.0571462,0.0666699,
|
|
0.0761937,0.0952412,0.104765,0.123813,0.133337,0.161908,0.171432,0.200003,
|
|
0.238098,0.26667,0.304765,0.34286,0.371431,0.409526,0.523809,0.590475,
|
|
0.70476,0.809524,0.885714,0.666667,0.609525,0.552382,0.485716,0.428574,
|
|
0.390479,0.34286,0.314289,0.276194,0.26667,0.228575,0.209527,0.180956,
|
|
0.161909,0.152385,0.133337,0.123814,0.11429,0.11429,0.104766,0.0952425,
|
|
0.076195,0.076195,0.0761944}; //50
|
|
|
|
std::vector<float> yellowA3 = {0.885716,0.800003,0.685719,0.619054,-0.0190476,-0.0190476,-0.0190476,
|
|
0.92381,0.914286,0.857145,0.800003,0.733337,0.685719,-0.0285714,-0.0285714,
|
|
-0.0285714,0.904762,0.866668,0.809526,0.771431,0.71429,0.666672,0.666672,
|
|
-0.0285714,-0.0285714,-0.0285714,0.914287,0.866669,0.771432,0.733338}; //30
|
|
|
|
std::vector<float> yellowA4 = {0.580952,0.580952,0.580952,0.571429,0.571429,0.571429,0.571429,
|
|
0.571429,0.561905,0.561905,0.561905,0.561905,0.561905,0.561905,0.561905,
|
|
0.561905,0.561905,0.561905,0.561905,0.561905,0.561905,0.561905,0.561905,
|
|
0.561905,0.561905,0.561905,0.561905,0.561905,0.561905,0.561905}; //30
|
|
|
|
std::vector<float> yellowB1 = {0.685715,0.723811,0.800002,0.485714,0.519047,0.552381,0.580953,
|
|
0.609524,0.626191,0.642858,0.659525,0.676191,0.685715,0.399999,0.495238,
|
|
0.533333,0.571429,0.604762,0.638096,0.653969,0.669842,0.685715,0.695239,
|
|
0.704763,0.561905,0.666667,0.704763,0.714287,0.266665,0.323808,0.35238,
|
|
0.366666,0.380951,0.399999,0.423809,0.933336,0.952384,0.957145,0.961907,
|
|
0.609524,0.628572,0.47619,0.523809,0.523809,0.523809,0.438095,0.457142,
|
|
0.457142,0,0.361904}; //50
|
|
|
|
std::vector<float> yellowB2 = {0.0380952,0.0380952,0.0380952,0.047619,0.047619,0.0571427,0.0761902,
|
|
0.0952377,0.0952377,0.114285,0.142856,0.161904,0.180951,0.219046,0.247618,
|
|
0.266665,0.276189,0.30476,0.333331,0.371426,0.419045,0.476188,0.542854,
|
|
0.67619,0.761905,0.638095,0.542857,0.447616,0.409521,0.352379,0.333331,
|
|
0.30476,0.266665,0.247618,0.199999,0.180951,0.161904,0.133333,0.114285,
|
|
0.104761,0.085714,0.0761902,0.0666665,0.0666665,0.0571427,0.047619,
|
|
0.047619,0.047619,0.0380952,0.0190477}; //50
|
|
|
|
std::vector<float> yellowB3 = {0.742857,0.580951,0.466664,0.352378,0.276187,0.223806,0.885714,
|
|
0.552379,0.409521,0.352378,0.257139,0.20952,0.123805,0.0857093,0.914286,
|
|
0.599998,0.523807,0.447616,0.390473,0.323806,0.257139,0.20952,0.133329,
|
|
0.971429,0.723808,0.647618,0.561903,0.485712,0.371425,0.323806}; //30
|
|
|
|
std::vector<float> yellowB4 = {0.819048,0.819048,0.819048,0.819048,0.819048,0.819048,0.819048,
|
|
0.819048,0.819048,0.828571,0.828571,0.828571,0.838095,0.838095,0.847619,
|
|
0.847619,0.857143,0.857143,0.857143,0.857143,0.866666,0.866666,0.866666,
|
|
0.866666,0.866666,0.866666,0.857143,0.847619,0.838095,0.809524}; //30
|
|
|
|
//*-*-*-*-*-*-*-*-*-*-*-*-*
|
|
|
|
//task #0 : blink led
|
|
#define LED_PERIOD (11111)
|
|
#define LED_ONTIME (1)
|
|
#define LED_GAPTIME (222)
|
|
#define LED_PIN 2
|
|
extern Task blink_task;
|
|
void blink() {
|
|
//
|
|
static int count = 0;
|
|
count++;
|
|
//
|
|
switch (count % 4) {
|
|
case 0:
|
|
digitalWrite(LED_PIN, LOW); // first ON
|
|
blink_task.delay(LED_ONTIME);
|
|
break;
|
|
case 1:
|
|
digitalWrite(LED_PIN, HIGH); // first OFF
|
|
blink_task.delay(LED_GAPTIME);
|
|
break;
|
|
case 2:
|
|
digitalWrite(LED_PIN, LOW); // second ON
|
|
blink_task.delay(LED_ONTIME);
|
|
break;
|
|
case 3:
|
|
digitalWrite(LED_PIN, HIGH); // second OFF
|
|
blink_task.delay(LED_PERIOD - 2* LED_ONTIME - LED_GAPTIME);
|
|
break;
|
|
}
|
|
}
|
|
Task blink_task(0, TASK_FOREVER, &blink, &runner, true); // -> ENABLED, at start-up.
|
|
//task #1 : osc processing
|
|
void route_note(OSCMessage& msg, int offset) {
|
|
//swap_println("got route_note!");
|
|
// (1) --> /onoff
|
|
if (msg.fullMatch("/onoff", offset)) {
|
|
//
|
|
note.clear();
|
|
//
|
|
note.onoff = msg.getFloat(0);
|
|
// if (note.onoff != 0) note.onoff = 1;
|
|
}
|
|
// (2) --> /velocity
|
|
if (msg.fullMatch("/velocity", offset)) {
|
|
note.velocity = msg.getFloat(0);
|
|
}
|
|
// (3) --> /pitch
|
|
if (msg.fullMatch("/pitch", offset)) {
|
|
note.pitch = msg.getFloat(0);
|
|
}
|
|
// (4) --> /id
|
|
if (msg.fullMatch("/id", offset)) {
|
|
note.id = msg.getInt(0);
|
|
}
|
|
// (5) --> /x
|
|
if (msg.fullMatch("/x", offset)) {
|
|
note.x1 = msg.getFloat(0);
|
|
note.x2 = msg.getFloat(1);
|
|
note.x3 = msg.getFloat(2);
|
|
note.x4 = msg.getFloat(3);
|
|
note.ps = msg.getFloat(4);
|
|
}
|
|
}
|
|
extern Task osc_task;
|
|
void osc()
|
|
{
|
|
//osc
|
|
OSCBundle bundleIN;
|
|
int size;
|
|
if (SLIPSerial.available()) {
|
|
while(!SLIPSerial.endofPacket()) {
|
|
if( (size = SLIPSerial.available()) > 0) {
|
|
while(size--) {
|
|
bundleIN.fill(SLIPSerial.read());
|
|
}
|
|
}
|
|
}
|
|
if(!bundleIN.hasError()) {
|
|
// on '/note'
|
|
bundleIN.route("/note", route_note);
|
|
#if defined(ESP32)
|
|
static int a = 0;
|
|
screen_text = String(a) + " => \n" + String(bundleIN.timetag.seconds-2208988800UL) + "\n" + String(bundleIN.timetag.fractionofseconds);
|
|
a++;
|
|
#endif
|
|
}
|
|
}
|
|
}
|
|
Task osc_task(0, TASK_FOREVER, &osc, &runner, true); // -> ENABLED, at start-up.
|
|
|
|
|
|
//
|
|
void setup() {
|
|
|
|
//led
|
|
pinMode(LED_PIN, OUTPUT);
|
|
|
|
//pwm freq.
|
|
analogWriteFreq(40000);
|
|
|
|
//serial
|
|
Serial.begin(115200);
|
|
delay(100);
|
|
|
|
//info
|
|
Serial.println();
|
|
Serial.println();
|
|
Serial.println("\"hi, i m your postman.\"");
|
|
Serial.println("-");
|
|
Serial.println("- my id: " + String(MY_ID) + ", gid: " + String(MY_GROUP_ID) + ", call me ==> \"" + String(MY_SIGN) + "\"");
|
|
Serial.println("- mac address: " + WiFi.macAddress() + ", channel: " + String(WIFI_CHANNEL));
|
|
Serial.println("-");
|
|
|
|
//wifi - disabled
|
|
system_phy_set_max_tpw(0);
|
|
WiFiMode_t node_type = WIFI_STA;
|
|
WiFi.mode(node_type);
|
|
|
|
//esp-now
|
|
if (esp_now_init() != 0) {
|
|
Serial.println("Error initializing ESP-NOW");
|
|
return;
|
|
}
|
|
esp_now_set_self_role(ESP_NOW_ROLE_COMBO);
|
|
esp_now_register_send_cb(onDataSent);
|
|
esp_now_register_recv_cb(onDataReceive);
|
|
//
|
|
Serial.println("- ! (esp_now_add_peer) ==> add a 'broadcast peer' (FF:FF:FF:FF:FF:FF).");
|
|
uint8_t broadcastmac[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
|
|
esp_now_add_peer(broadcastmac, ESP_NOW_ROLE_COMBO, 1, NULL, 0);
|
|
|
|
Serial.println("-");
|
|
Serial.println("\".-.-.-. :)\"");
|
|
Serial.println();
|
|
|
|
//random seed
|
|
randomSeed(analogRead(0));
|
|
|
|
//tasks
|
|
rest_task.restartDelayed(500);
|
|
rest2_task.restartDelayed(500);
|
|
}
|
|
|
|
void loop() {
|
|
//
|
|
runner.execute();
|
|
//
|
|
}
|