let s make this simple.

This commit is contained in:
doohoyi 2019-12-10 16:42:48 +09:00
parent acbbf6aa69
commit 3c3d5a6e7b
14 changed files with 110 additions and 1071 deletions

View file

@ -1,39 +0,0 @@
This directory is intended for project header files.
A header file is a file containing C declarations and macro definitions
to be shared between several project source files. You request the use of a
header file in your project source file (C, C++, etc) located in `src` folder
by including it, with the C preprocessing directive `#include'.
```src/main.c
#include "header.h"
int main (void)
{
...
}
```
Including a header file produces the same results as copying the header file
into each source file that needs it. Such copying would be time-consuming
and error-prone. With a header file, the related declarations appear
in only one place. If they need to be changed, they can be changed in one
place, and programs that include the header file will automatically use the
new version when next recompiled. The header file eliminates the labor of
finding and changing all the copies as well as the risk that a failure to
find one copy will result in inconsistencies within a program.
In C, the usual convention is to give header files names that end with `.h'.
It is most portable to use only letters, digits, dashes, and underscores in
header file names, and at most one dot.
Read more about using header files in official GCC documentation:
* Include Syntax
* Include Operation
* Once-Only Headers
* Computed Includes
https://gcc.gnu.org/onlinedocs/cpp/Header-Files.html

View file

@ -1,95 +0,0 @@
#pragma once
//
// [ room protocol (message format) ]
//
// DDDDD ==> 5 decimal-digits.
// IIIWW ==> id (3 decimal-digits) * 100 + word (2 decimal-digits)
// id ==> 100~ : objects
// id ==> 200~ : agents (controller)
// id ==> 900~ : groups
// words ==> 1 ~ 99 ==> see 'words.h' for the details
// member identity
// objects
// speakers
#define ID_SPEAK_A (10600)
// (special agent)
#define ID_MONITOR (20100)
#define ID_CONDUCTOR (20200)
// (groups)
#define ID_EVERYONE (90100)
#define ID_SPEAKERS (90200)
// (choice)
#define IDENTITY ID_CONDUCTOR
//
#define LONELY_TO_DIE (30000)
//
#include <Arduino.h>
//
#include <painlessMesh.h>
extern painlessMesh mesh;
// firmata connectivity
#define FIRMATA_ON (0xF13A0001)
#define FIRMATA_OFF (0xF13A0002)
#define FIRMATA_USE FIRMATA_OFF
#if (IDENTITY == ID_KEYBED)
#undef FIRMATA_USE
#define FIRMATA_USE FIRMATA_ON
#endif
//NOTE: disabling AP beacon for speaker accompanied devices!
#define NODE_TYPE_AP_STA (0x40DE0001)
#define NODE_TYPE_STA_ONLY (0x40DE0002)
//by-default : STA_ONLY
#define NODE_TYPE NODE_TYPE_STA_ONLY
//guys w/o speakers : AP_STA
#if (IDENTITY == ID_GAS || IDENTITY == ID_DRUM || IDENTITY == ID_REEL || IDENTITY == ID_FLOAT || IDENTITY == ID_CONDUCTOR || IDENTITY == ID_MONITOR)
#undef NODE_TYPE
#define NODE_TYPE NODE_TYPE_AP_STA
#endif
// board
#define BOARD_NODEMCU_ESP12E (0xBD00 + 1)
#define BOARD_NODEMCU_ESP12N (0xBD00 + 2)
#define BOARD_NODEMCU_ESP32 (0xBD00 + 3)
//(choice)
#define BOARD_SELECT BOARD_NODEMCU_ESP12E
// mesh
#define MESH_SSID "cricket-crackers"
#define MESH_PASSWORD "11*1111/111"
#define MESH_PORT 5555
#define MESH_CHANNEL 5
// #define MESH_ANCHOR
//
// LED status indication
// operation modes
// 0 - booted. and running. no connection. scanning.
// 1 - + connected.
// notifying patterns
// 0 - steady on
// 1 - slow blinking (syncronized)
//
#if (BOARD_SELECT == BOARD_NODEMCU_ESP12E)
#define LED_PIN 2 // nodemcuv2
#elif (BOARD_SELECT == BOARD_NODEMCU_ESP32)
#define LED_PIN 13 // featheresp32
#endif
#define LED_PERIOD (1111)
#define LED_ONTIME (1)
// event handlers fo connection-related events
extern void gotMessageCallback(uint32_t from, String & msg); // REQUIRED
extern void gotChangedConnectionCallback();
// the system scheduler
extern Scheduler runner;
#include "words.h"

View file

@ -1,26 +0,0 @@
#define MSG_LENGTH_MAX 256
#define SPEAK_A_HELLO (ID_SPEAK_A + 1)
#define SPEAK_A_SLEEPING (ID_SPEAK_A + 2)
#define SPEAK_A_TIC (ID_SPEAK_A + 3)
#define SPEAK_A_TAC (ID_SPEAK_A + 4)
#define SPEAK_A_TOE (ID_SPEAK_A + 5)
#define SPEAK_A_PLAYMODE (ID_SPEAK_A + 6) // + XX : 0: Individual random, 1: Directional Propagation
#define SPEAK_A_PARA_SPEED (ID_SPEAK_A + 7) // + XX : speed of rhythm
#define SPEAK_A_PARA_SNDSET (ID_SPEAK_A + 8) // + XX : sound set select
//for group (all speakers)
#define SPEAKERS_HELLO (ID_SPEAKERS + 1)
#define SPEAKERS_SLEEPING (ID_SPEAKERS + 2)
#define SPEAKERS_TIC (ID_SPEAKERS + 3)
#define SPEAKERS_TAC (ID_SPEAKERS + 4)
#define SPEAKERS_TOE (ID_SPEAKERS + 5)
#define SPEAKERS_PLAYMODE (ID_SPEAKERS + 6) // + XX : 0: Individual random, 1: Directional Propagation
#define SPEAKERS_PARA_SPEED (ID_SPEAKERS + 7) // + XX : speed of rhythm
#define SPEAKERS_PARA_SNDSET (ID_SPEAKERS + 8) // + XX : sound set select
//common constants for all speakers
#define SPEAKERS_PLAYMODE_INDEP (ID_SPEAKERS + 50)
#define SPEAKERS_PLAYMODE_PROPA (ID_SPEAKERS + 51)
// #define SPEAKERS_LEADING (ID_SPEAKERS + 80)
// #define SPEAKERS_FOLLOWING (ID_SPEAKERS + 81)

View file

@ -1,46 +0,0 @@
This directory is intended for project specific (private) libraries.
PlatformIO will compile them to static libraries and link into executable file.
The source code of each library should be placed in a an own separate directory
("lib/your_library_name/[here are source files]").
For example, see a structure of the following two libraries `Foo` and `Bar`:
|--lib
| |
| |--Bar
| | |--docs
| | |--examples
| | |--src
| | |- Bar.c
| | |- Bar.h
| | |- library.json (optional, custom build options, etc) https://docs.platformio.org/page/librarymanager/config.html
| |
| |--Foo
| | |- Foo.c
| | |- Foo.h
| |
| |- README --> THIS FILE
|
|- platformio.ini
|--src
|- main.c
and a contents of `src/main.c`:
```
#include <Foo.h>
#include <Bar.h>
int main (void)
{
...
}
```
PlatformIO Library Dependency Finder will find automatically dependent
libraries scanning project source files.
More information about PlatformIO Library Dependency Finder
- https://docs.platformio.org/page/librarymanager/ldf.html

View file

@ -1,377 +0,0 @@
// tasks
extern Task loop_msg_reel_task;
extern Task loop_msg_float_task;
extern Task loop_msg_gas_task;
extern Task loop_msg_drum_task;
// room protocol
static char msg_cstr[MSG_LENGTH_MAX] = {0, };
void gotChangedConnectionCallback() { // REQUIRED
}
void gotMessageCallback(uint32_t from, String & msg) { // REQUIRED
Serial.println(msg);
int message = msg.substring(1, 6).toInt();
// town_onoff
static unsigned long timestamp = millis(); // init timestamp!
static bool town_onoff = false;
//
if (message == SPEAK_A_HELLO || message == SPEAK_B_HELLO || message == SPEAK_C_HELLO || message == SPEAK_D_HELLO || message == SPEAK_E_HELLO || message == SPEAK_F_HELLO) {
//
timestamp = millis(); // update timestamp!
// Serial.println("town-folks alive!");
//
if (town_onoff == false) {
town_onoff = true;
loop_msg_reel_task.restartDelayed(100);
loop_msg_float_task.restartDelayed(100);
loop_msg_gas_task.restartDelayed(100);
loop_msg_drum_task.restartDelayed(100);
}
}
// if there's NO SPEAK_X_HELLO for 1 min. turn off objects.
if (millis() - timestamp > 1000*20) {
town_onoff = false;
loop_msg_reel_task.disable();
loop_msg_float_task.disable();
loop_msg_gas_task.disable();
loop_msg_drum_task.disable();
//
// Serial.println("town-folks sleep!");
}
}
//msg_reel task
void loop_msg_reel() {
//
static String msg = "";
sprintf(msg_cstr, "[%05d]", REEL_TURN);
msg = String(msg_cstr);
mesh.sendBroadcast(msg);
Serial.println("TX : " + msg);
//
loop_msg_reel_task.restartDelayed(random(1000*60*1.5, 1000*60*2));
}
Task loop_msg_reel_task(0, TASK_ONCE, &loop_msg_reel);
//msg_float task
void loop_msg_float() {
//
static String msg = "";
sprintf(msg_cstr, "[%05d]", FLOAT_FLY);
msg = String(msg_cstr);
mesh.sendBroadcast(msg);
Serial.println("TX : " + msg);
//
loop_msg_float_task.restartDelayed(random(1000*60*2, 1000*60*2.5));
}
Task loop_msg_float_task(0, TASK_ONCE, &loop_msg_float);
//msg_gas task
void loop_msg_gas() {
//
static String msg = "";
sprintf(msg_cstr, "[%05d]", GAS_RING_RING_RING);
msg = String(msg_cstr);
mesh.sendBroadcast(msg);
Serial.println("TX : " + msg);
//
loop_msg_gas_task.restartDelayed(random(800, 3000));
}
Task loop_msg_gas_task(0, TASK_ONCE, &loop_msg_gas);
//msg_drum task
void loop_msg_drum() {
//
static String msg = "";
sprintf(msg_cstr, "[%05d]", DRUM_SCRATCH);
msg = String(msg_cstr);
mesh.sendBroadcast(msg);
Serial.println("TX : " + msg);
//
loop_msg_drum_task.restartDelayed(random(800, 3000));
}
Task loop_msg_drum_task(0, TASK_ONCE, &loop_msg_drum);
// sound theme
#define N_THEMES 14
int theme = 0;
// vspeed
int vspeed = 0;
// soundset
int soundset = 0;
//speakers soundset changer
// // speakers mode changer
// // //speakers tic task
// // speakers speed changer
extern Task speaker_a_tick_task;
void speaker_a_tick() {
//
int base_speed = 1000 + (vspeed * 10);
int random_portion = base_speed * 0.1;
//
static String msg = "";
sprintf(msg_cstr, "[%05d]", SPEAK_A_TIC);
msg = String(msg_cstr);
mesh.sendBroadcast(msg);
Serial.println("TX : " + msg);
//
speaker_a_tick_task.restartDelayed(base_speed + random(random_portion));
}
Task speaker_a_tick_task(0, TASK_ONCE, &speaker_a_tick);
extern Task playloop_task;
void playloop() {
static String msg = "";
//
Serial.print("current THEME => ");
Serial.println(theme);
//
if (theme == 0) {
//
// directional propagation + soundset 01~10 + vspeed 20
//
sprintf(msg_cstr, "[%05d:%02d]", SPEAKERS_PLAYMODE, SPEAKERS_PLAYMODE_PROPA);
msg = String(msg_cstr);
mesh.sendBroadcast(msg);
Serial.println("TX : SPEAKERS_PLAYMODE == SPEAKERS_PLAYMODE_PROPA");
speaker_a_tick_task.restartDelayed(10);
//
soundset = 1; // soundset ==> 1 ~ 99
sprintf(msg_cstr, "[%05d:%02d]", SPEAKERS_PARA_SNDSET, soundset); // soundset ==> give starting sound #..
msg = String(msg_cstr);
mesh.sendBroadcast(msg);
Serial.print("TX : SPEAKERS_PARA_SNDSET == ");
Serial.println(soundset);
Serial.println(msg);
//
vspeed = 0; // vspeed ==> 0 ~ 999
sprintf(msg_cstr, "[%05d:%03d]", SPEAKERS_PARA_SPEED, vspeed);
msg = String(msg_cstr);
mesh.sendBroadcast(msg);
Serial.print("TX : SPEAKERS_PARA_SPEED == ");
Serial.println(vspeed);
Serial.println(msg);
//
playloop_task.restartDelayed(30000);
//
} else if (theme == 1) {
//
vspeed = 75; // vspeed ==> 0 ~ 999
sprintf(msg_cstr, "[%05d:%03d]", SPEAKERS_PARA_SPEED, vspeed);
msg = String(msg_cstr);
mesh.sendBroadcast(msg);
Serial.print("TX : SPEAKERS_PARA_SPEED == ");
Serial.println(vspeed);
Serial.println(msg);
//
playloop_task.restartDelayed(30000);
//
} else if (theme == 2) {
//
vspeed = 0; // vspeed ==> 0 ~ 999
sprintf(msg_cstr, "[%05d:%03d]", SPEAKERS_PARA_SPEED, vspeed);
msg = String(msg_cstr);
mesh.sendBroadcast(msg);
Serial.print("TX : SPEAKERS_PARA_SPEED == ");
Serial.println(vspeed);
Serial.println(msg);
//
playloop_task.restartDelayed(40000);
//
} else if (theme == 3) {
//
vspeed = 500; // vspeed ==> 0 ~ 999
sprintf(msg_cstr, "[%05d:%03d]", SPEAKERS_PARA_SPEED, vspeed);
msg = String(msg_cstr);
mesh.sendBroadcast(msg);
Serial.print("TX : SPEAKERS_PARA_SPEED == ");
Serial.println(vspeed);
Serial.println(msg);
//
playloop_task.restartDelayed(30000);
//
} else if (theme == 4) {
//
// indep_random + soundset 01~10
//
sprintf(msg_cstr, "[%05d:%02d]", SPEAKERS_PLAYMODE, SPEAKERS_PLAYMODE_INDEP);
msg = String(msg_cstr);
mesh.sendBroadcast(msg);
Serial.println("TX : SPEAKERS_PLAYMODE == SPEAKERS_PLAYMODE_INDEP");
speaker_a_tick_task.disable();
//
vspeed = 0; // vspeed ==> 0 ~ 999
sprintf(msg_cstr, "[%05d:%03d]", SPEAKERS_PARA_SPEED, vspeed);
msg = String(msg_cstr);
mesh.sendBroadcast(msg);
Serial.print("TX : SPEAKERS_PARA_SPEED == ");
Serial.println(vspeed);
Serial.println(msg);
//
playloop_task.restartDelayed(30000);
//
} else if (theme == 5) {
//
vspeed = 150; // vspeed ==> 0 ~ 999
sprintf(msg_cstr, "[%05d:%03d]", SPEAKERS_PARA_SPEED, vspeed);
msg = String(msg_cstr);
mesh.sendBroadcast(msg);
Serial.print("TX : SPEAKERS_PARA_SPEED == ");
Serial.println(vspeed);
Serial.println(msg);
//
playloop_task.restartDelayed(30000);
//
} else if (theme == 6) {
//
vspeed = 200; // vspeed ==> 0 ~ 999
sprintf(msg_cstr, "[%05d:%03d]", SPEAKERS_PARA_SPEED, vspeed);
msg = String(msg_cstr);
mesh.sendBroadcast(msg);
Serial.print("TX : SPEAKERS_PARA_SPEED == ");
Serial.println(vspeed);
Serial.println(msg);
//
playloop_task.restartDelayed(10000);
//
} else if (theme == 7) {
//
vspeed = 0; // vspeed ==> 0 ~ 999
sprintf(msg_cstr, "[%05d:%03d]", SPEAKERS_PARA_SPEED, vspeed);
msg = String(msg_cstr);
mesh.sendBroadcast(msg);
Serial.print("TX : SPEAKERS_PARA_SPEED == ");
Serial.println(vspeed);
Serial.println(msg);
//
playloop_task.restartDelayed(40000);
//
} else if (theme == 8) {
//
// directional propagation + soundset 01~10 + vspeed 20
//
sprintf(msg_cstr, "[%05d:%02d]", SPEAKERS_PLAYMODE, SPEAKERS_PLAYMODE_PROPA);
msg = String(msg_cstr);
mesh.sendBroadcast(msg);
Serial.println("TX : SPEAKERS_PLAYMODE == SPEAKERS_PLAYMODE_PROPA");
speaker_a_tick_task.restartDelayed(10);
//
soundset = 11; // soundset ==> 1 ~ 99
sprintf(msg_cstr, "[%05d:%02d]", SPEAKERS_PARA_SNDSET, soundset); // soundset ==> give starting sound #..
msg = String(msg_cstr);
mesh.sendBroadcast(msg);
Serial.print("TX : SPEAKERS_PARA_SNDSET == ");
Serial.println(soundset);
Serial.println(msg);
//
vspeed = 0; // vspeed ==> 0 ~ 999
sprintf(msg_cstr, "[%05d:%03d]", SPEAKERS_PARA_SPEED, vspeed);
msg = String(msg_cstr);
mesh.sendBroadcast(msg);
Serial.print("TX : SPEAKERS_PARA_SPEED == ");
Serial.println(vspeed);
Serial.println(msg);
//
playloop_task.restartDelayed(30000);
//
} else if (theme == 9) {
//
vspeed = 300; // vspeed ==> 0 ~ 999
sprintf(msg_cstr, "[%05d:%03d]", SPEAKERS_PARA_SPEED, vspeed);
msg = String(msg_cstr);
mesh.sendBroadcast(msg);
Serial.print("TX : SPEAKERS_PARA_SPEED == ");
Serial.println(vspeed);
Serial.println(msg);
//
playloop_task.restartDelayed(20000);
//
} else if (theme == 10) {
//
vspeed = 0; // vspeed ==> 0 ~ 999
sprintf(msg_cstr, "[%05d:%03d]", SPEAKERS_PARA_SPEED, vspeed);
msg = String(msg_cstr);
mesh.sendBroadcast(msg);
Serial.print("TX : SPEAKERS_PARA_SPEED == ");
Serial.println(vspeed);
Serial.println(msg);
//
playloop_task.restartDelayed(30000);
//
} else if (theme == 11) {
//
vspeed = 200; // vspeed ==> 0 ~ 999
sprintf(msg_cstr, "[%05d:%03d]", SPEAKERS_PARA_SPEED, vspeed);
msg = String(msg_cstr);
mesh.sendBroadcast(msg);
Serial.print("TX : SPEAKERS_PARA_SPEED == ");
Serial.println(vspeed);
Serial.println(msg);
//
playloop_task.restartDelayed(20000);
//
} else if (theme == 12) {
//
// indep_random + soundset 01~10
//
sprintf(msg_cstr, "[%05d:%02d]", SPEAKERS_PLAYMODE, SPEAKERS_PLAYMODE_INDEP);
msg = String(msg_cstr);
mesh.sendBroadcast(msg);
Serial.println("TX : SPEAKERS_PLAYMODE == SPEAKERS_PLAYMODE_INDEP");
speaker_a_tick_task.disable();
//
vspeed = 0; // vspeed ==> 0 ~ 999
sprintf(msg_cstr, "[%05d:%03d]", SPEAKERS_PARA_SPEED, vspeed);
msg = String(msg_cstr);
mesh.sendBroadcast(msg);
Serial.print("TX : SPEAKERS_PARA_SPEED == ");
Serial.println(vspeed);
Serial.println(msg);
//
playloop_task.restartDelayed(40000);
//
} else if (theme == 13) {
//
vspeed = 300; // vspeed ==> 0 ~ 999
sprintf(msg_cstr, "[%05d:%03d]", SPEAKERS_PARA_SPEED, vspeed);
msg = String(msg_cstr);
mesh.sendBroadcast(msg);
Serial.print("TX : SPEAKERS_PARA_SPEED == ");
Serial.println(vspeed);
Serial.println(msg);
//
playloop_task.restartDelayed(20000);
//
}
// theme : 0 ~ (N_THEMES - 1)
theme++;
if (theme >= N_THEMES) {
theme = 0;
}
}
Task playloop_task(0, TASK_ONCE, &playloop);
//
void setup_member() {
//
runner.addTask(loop_msg_reel_task);
runner.addTask(loop_msg_float_task);
runner.addTask(loop_msg_gas_task);
runner.addTask(loop_msg_drum_task);
//
runner.addTask(speaker_a_tick_task);
//
runner.addTask(playloop_task);
playloop_task.restartDelayed(100);
}

View file

@ -1,126 +0,0 @@
// i2c
#include <Wire.h>
#include "speakers/i2c_protocol.h"
// tasks
extern Task sing_task;
extern Task indep_random_task;
extern Task direc_propa_task;
// soundset
int soundset = 1; // starting # of the set. (10 files will be selected.)
// playmode
int playmode = SPEAKERS_PLAYMODE_INDEP;
// vspeed
int vspeed = 0;
// room protocol
static char msg_cstr[MSG_LENGTH_MAX] = {0, };
void gotChangedConnectionCallback() { // REQUIRED
}
void gotMessageCallback(uint32_t from, String & msg) { // REQUIRED
Serial.println(msg);
int message = msg.substring(1, 6).toInt();
// this speaker event
if (playmode == SPEAKERS_PLAYMODE_PROPA) {
if (message == SPEAK_A_TIC) {
Serial.println("SPEAK_A_TIC");
int r = 100 + random(vspeed * 10);
sing_task.restartDelayed(r);
direc_propa_task.restartDelayed(r);
}
}
// speakers group : SPEAKERS_PLAYMODE
if (message == SPEAKERS_PLAYMODE) {
int para = msg.substring(7, 9).toInt(); // get +XX parameter..
// only allow valid inputs
if (para == SPEAKERS_PLAYMODE_INDEP) {
playmode = para;
indep_random_task.restartDelayed(100);
}
else if (para == SPEAKERS_PLAYMODE_PROPA) {
playmode = para;
indep_random_task.disable();
}
}
// speakers group : SPEAKERS_PARA_SNDSET
if (message == SPEAKERS_PARA_SNDSET) {
int para = msg.substring(7, 9).toInt(); // get +XX parameter..
// only allow valid inputs
if (para >= 1 && para < 100) { // 1 ~ 99
soundset = para;
}
}
// speakers group : SPEAKERS_PARA_SPEED
if (message == SPEAKERS_PARA_SPEED) {
int para = msg.substring(7, 10).toInt(); // get +XXX parameter..
// only allow valid inputs
if (para >= 0 && para < 1000) { // 0 ~ 999
vspeed = para;
}
}
}
// saying hello
void greeting() {
static String msg = "";
sprintf(msg_cstr, "[%05d]", SPEAK_A_HELLO);
msg = String(msg_cstr);
mesh.sendBroadcast(msg);
Serial.println("TX : " + msg);
}
Task saying_greeting(10000, TASK_FOREVER, &greeting);
//playmode #1 : independent random playmode
void indep_random() {
int base_speed = 1000 + (vspeed * 10);
int random_portion = base_speed * 0.1;
//
sing_task.restartDelayed(100);
indep_random_task.restartDelayed(base_speed + random(random_portion)); //re-schedule myself.
}
Task indep_random_task(0, TASK_ONCE, &indep_random);
//playmode #2 : directional propagation playmode
void direc_propa() {
static String msg = "";
sprintf(msg_cstr, "[%05d]", SPEAK_B_TIC);
msg = String(msg_cstr);
mesh.sendBroadcast(msg);
Serial.println("TX : SPEAK_B_TIC");
}
Task direc_propa_task(0, TASK_ONCE, &direc_propa);
// sing!
void sing() {
//
static int song_select = 1;
//
song_select = random(soundset, (soundset + 10)); // every sound set has 10 sounds. x ~ x+9
// "P#SSS@AAAA" - P: P (play), SSS: song #, A: amp. (x 1000)
// "SXXXXXXXXX" - S: S (stop)
sprintf(cmdstr, "P#%03d@%04d", song_select, 800); // play song #1, with amplitude
Wire.beginTransmission(I2C_ADDR);
Wire.write(cmdstr, CMD_LENGTH);
Wire.endTransmission();
}
Task sing_task(0, TASK_ONCE, &sing);
//setup_member
void setup_member() {
//i2c master
Wire.begin();
//tasks
runner.addTask(saying_greeting);
saying_greeting.enable();
//
runner.addTask(sing_task);
//
runner.addTask(indep_random_task);
runner.addTask(direc_propa_task);
//
indep_random_task.restartDelayed(100);
}

View file

@ -1,12 +0,0 @@
#pragma once
//i2c address
#define I2C_ADDR 3
//i2c protocol
#define CMD_LENGTH 10
#define CMD_BUFF_LEN (CMD_LENGTH + 1)
char cmdstr[CMD_BUFF_LEN] = "P#SSS@AAAA";
// "P#SSS@AAAA" - P: P (play), SSS: song #, A: amp. (x 1000)
// "SXXXXXXXXX" - S: S (stop)

View file

@ -1,7 +0,0 @@
#!/bin/bash
#NOTE: u might want to wait a bit before running this script..
# 'right after' upload system reports that the port is not ready yet!
# so, we don't support here.. 'upload-n-monitor.sh' option.
pio device monitor -p /dev/cu.usbmodem32231601 -b 9600

View file

@ -1,28 +0,0 @@
; PlatformIO Project Configuration File
;
; Build options: build flags, source filter
; Upload options: custom upload port, speed and extra flags
; Library options: dependencies, extra library storages
; Advanced options: extra scripting
;
; Please visit documentation for the other options and examples
; https://docs.platformio.org/page/projectconf.html
[platformio]
env_default = teensy35
[common]
lib_deps =
721@3.0.2 ; TaskScheduler
[env:teensy35]
platform = teensy@3.6.0
board = teensy35
framework = arduino
lib_deps = ${common.lib_deps}
[env:teensy36]
platform = teensy@3.6.0
board = teensy36
framework = arduino
lib_deps = ${common.lib_deps}

View file

@ -1,206 +0,0 @@
//HACK: let auto-poweroff speakers stay turned ON! - (creative muvo mini)
#define IDLE_FREQ 22000
#define IDLE_AMP 0 // --> creative muvo 2 doesn't need this. they just stay on!
//teensy audio
#include <Audio.h>
#include <Wire.h>
#include <SPI.h>
#include <SD.h>
#include <SerialFlash.h>
//teensy 3.5 with SD card
#define SDCARD_CS_PIN BUILTIN_SDCARD
#define SDCARD_MOSI_PIN 11 // not actually used
#define SDCARD_SCK_PIN 13 // not actually used
// GUItool: begin automatically generated code
AudioPlaySdWav playSdWav1; //xy=224,265
AudioSynthWaveformSine sine1; //xy=236,361
AudioMixer4 mixer2; //xy=497,328
AudioMixer4 mixer1; //xy=499,245
AudioAmplifier amp1; //xy=633,245
AudioAmplifier amp2; //xy=634,328
AudioOutputAnalogStereo dacs1; //xy=788,284
AudioConnection patchCord1(playSdWav1, 0, mixer1, 0);
AudioConnection patchCord2(playSdWav1, 1, mixer2, 0);
AudioConnection patchCord3(sine1, 0, mixer1, 1);
AudioConnection patchCord4(sine1, 0, mixer2, 1);
AudioConnection patchCord5(mixer2, amp2);
AudioConnection patchCord6(mixer1, amp1);
AudioConnection patchCord7(amp1, 0, dacs1, 0);
AudioConnection patchCord8(amp2, 0, dacs1, 1);
// GUItool: end automatically generated code
//task
#include <TaskScheduler.h>
Scheduler runner;
//song #
int song_now = 0; //0~99
//
void sound_player_start()
{
//filename buffer - 8.3 naming convension! 8+1+3+1 = 13
char filename[13] = "NN.WAV";
//search for the sound file
int limit = (song_now % 100); // 0~99
filename[0] = '0' + (limit / 10); // [N]N.WAV
filename[1] = '0' + (limit % 10); // N[N].WAV
//TEST
Serial.println(filename);
//start the player!
//NOTE: block out 're-triggering'
if (playSdWav1.isPlaying() == false) {
playSdWav1.play(filename);
}
//mark the indicator : HIGH: ON
// digitalWrite(13, HIGH);
//to wait a bit for updating isPlaying()
delay(10);
}
void sound_player_stop() {
//stop the player.
if (playSdWav1.isPlaying() == true) {
playSdWav1.stop();
}
}
void sound_player_check() {
if (playSdWav1.isPlaying() == false) {
//mark the indicator : LOW: OFF
digitalWrite(13, LOW);
//let speaker leave turned ON!
sine1.amplitude(IDLE_AMP);
}
else {
//let speaker leave turned ON!
sine1.amplitude(0);
}
}
//
Task sound_player_start_task(0, TASK_ONCE, sound_player_start);
Task sound_player_stop_task(0, TASK_ONCE, sound_player_stop);
Task sound_player_check_task(0, TASK_FOREVER, sound_player_check, &runner, true);
//i2c
#include <Wire.h>
#include "../i2c_protocol.h"
void receiveEvent(int numBytes) {
//numBytes : how many bytes received(==available)
// Serial.println("[i2c] on receive!");
int nb = Wire.readBytes(cmdstr, CMD_LENGTH);
Serial.print("[i2c] cmdstr : ");
Serial.println(cmdstr);
if (CMD_LENGTH == nb) { // receive cmdstr.
//convert to String
String msg = String(cmdstr);
//parse command string.
char first = msg.charAt(0);
if (first == 'P') {
//
// "P#SSS@AAAA" - P: P (play), SSS: song #, A: amp. (x 1000)
//
String str_song = msg.substring(2,5); // 234
String str_gain = msg.substring(6,10); // 6789
song_now = str_song.toInt();
float amp_gain = str_gain.toFloat() * 0.001;
//
amp1.gain(amp_gain);
amp2.gain(amp_gain);
sound_player_start_task.restart();
//
} else {
//
// "SXXXXXXXXX" - S: S (stop)
//
sound_player_stop_task.restart();
amp1.gain(1.0);
amp2.gain(1.0);
//
}
}
}
// SD TEST
void printDirectory(File dir, int numTabs) {
while(true) {
File entry = dir.openNextFile();
if (!entry) {
// no more files
//Serial.println("**nomorefiles**");
break;
}
for (uint8_t i=0; i<numTabs; i++) {
Serial.print('\t');
}
Serial.print(entry.name());
if (entry.isDirectory()) {
Serial.println("/");
printDirectory(entry, numTabs+1);
} else {
// files have sizes, directories do not
Serial.print("\t\t");
Serial.println(entry.size(), DEC);
}
entry.close();
}
}
//
File root;
void setup() {
//serial monitor
Serial.begin(9600);
delay(50);
//i2c
Wire.begin(I2C_ADDR);
Wire.onReceive(receiveEvent);
//Wire.onRequest(requestEvent);
//SD - AudioPlaySdWav @ teensy audio library needs SD.begin() first. don't forget/ignore!
//+ let's additionally check contents of SD.
if (!SD.begin(BUILTIN_SDCARD)) {
Serial.println("[sd] initialization failed!");
return;
}
Serial.println("[sd] initialization done.");
root = SD.open("/");
printDirectory(root, 0);
//audio
AudioMemory(20);
mixer1.gain(0,1.0);
mixer1.gain(1,1.0);
mixer1.gain(2,0);
mixer1.gain(3,0);
mixer2.gain(0,1.0);
mixer2.gain(1,1.0);
mixer2.gain(2,0);
mixer2.gain(3,0);
amp1.gain(1.0);
amp2.gain(1.0);
//let auto-poweroff speakers stay turned ON!
sine1.frequency(IDLE_FREQ);
//led
pinMode(13, OUTPUT);
digitalWrite(13, LOW); // LOW: OFF
//player task
runner.addTask(sound_player_start_task);
runner.addTask(sound_player_stop_task);
//
Serial.println("[setup] done.");
}
void loop() {
runner.execute();
}

View file

@ -1,3 +0,0 @@
#!/bin/bash
pio run -t upload

View file

@ -1,16 +1,16 @@
; PlatformIO Project Configuration File ; < NOTE >
;
; Build options: build flags, source filter ; to enable verbose output add option -->
; Upload options: custom upload port, speed and extra flags ; $ platformio run --verbose
; Library options: dependencies, extra library storages
; Advanced options: extra scripting ; to make this permanent for the proj. -->
; ; $ platformio settings set force_verbose Yes
; Please visit documentation for the other options and examples
; https://docs.platformio.org/page/projectconf.html ; then confirm the change -->
; $ platformio settings get
[platformio] [platformio]
default_envs = nodemcuv2 default_envs = nodemcuv2
; src_dir = src_gps_serial_monitor_oled
[common] [common]
framework = arduino framework = arduino
@ -18,42 +18,28 @@ lib_deps =
SPI SPI
Wire Wire
64 ; ArduinoJson 64 ; ArduinoJson
; 64@5.13.4 ; ArduinoJson
1269 ; Painless Mesh 1269 ; Painless Mesh
; 1269@1.3.0 ; Painless Mesh src_filter =
135@1.2.9 ; Adafruit SSD1306
13 ; Adafruit GFX Library
22 ; Adafruit HX8357 Library
377 ; Adafruit STMPE610
307 ; Firmata
; we had very similar issue like --> https://gitlab.com/painlessMesh/painlessMesh/issues/159
; but according to the discussion.. this should not happen again.. since that should be fixed @ 1.2.7 and i was using 1.2.8. no?
; so.. somehow commented other version requirements.. (dependent libs.)
; now.. it seems.. works fine..?
; but no clear mind. what was it? and why now ok?
[env:nodemcuv2] [env:nodemcuv2]
platform = espressif8266 platform = espressif8266
board = nodemcuv2 board = nodemcuv2
framework = ${common.framework} framework = ${common.framework}
upload_speed = 921600
lib_deps = lib_deps =
ESP8266WiFi ESP8266WiFi
Servo(esp8266) Servo(esp8266)
; 305@1.2.0 ; ESPAsyncTCP
${common.lib_deps} ${common.lib_deps}
upload_speed = 921600
[env:huzzah] [env:huzzah]
platform = espressif8266 platform = espressif8266
board = huzzah board = huzzah
framework = ${common.framework} framework = ${common.framework}
upload_speed = 921600
lib_deps = lib_deps =
ESP8266WiFi ESP8266WiFi
Servo(esp8266) Servo(esp8266)
; 305@1.2.0 ; ESPAsyncTCP
${common.lib_deps} ${common.lib_deps}
upload_speed = 921600
[env:featheresp32] [env:featheresp32]
build_unflags = -std=gnu++11 build_unflags = -std=gnu++11
@ -61,15 +47,7 @@ build_flags = -std=gnu++14 ; AsyncTCP wants this.
platform = espressif32 platform = espressif32
board = featheresp32 board = featheresp32
framework = ${common.framework} framework = ${common.framework}
upload_speed = 921600
lib_deps = lib_deps =
1826@1.0.3 ; AsyncTCP 1826@1.0.3 ; AsyncTCP
${common.lib_deps} ${common.lib_deps}
upload_speed = 921600
; < NOTE >
; to enable verbose output type in the terminal -->
; $ platformio settings set force_verbose Yes
; then confirm the change -->
; $ platformio settings get

View file

@ -1,26 +1,84 @@
// //
// Exhibition @ exhibition-space // wirelessly connected cloud (Wireless Mesh Networking)
// <one and twelve one-hundred-eighth seconds at the prince's room> // MIDI-like
// // spacial
// Feb. 11 @ 2019 // sampler keyboard
// //
// the common sense
#include "common.h"
#if (IDENTITY == ID_SPEAK_A)
#include "../members/speaker_a.cpp"
// //
// COSMO40 @ Incheon w/ Factory2
// RTA @ Seoul w/ Post Territory Ujeongguk
//
//
// 2019 12 10
//
// (part-1) esp8266 : 'postman' (the mesh network nodes)
//
// this module will build up a mesh cloud.
//
// for now, ESP-MESH is out there.
// which is probably more complete impl. of this kind.
// but that's only for esp32, not for esp8266
// we want to use esp8266, so, we will use painlessMesh
// which is also good.
//
// for painlessMesh, a node is a JSON 'postman'
// 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.
//
// 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.
//
//==========<configuration>===========
// #define DISABLE_AP
//==========</configuration>==========
//============<parameters>============
#define MESH_SSID "cricket-crackers"
#define MESH_PASSWORD "cc*vvvv/kkk"
#define MESH_PORT 5555
#define MESH_CHANNEL 5
// #define MESH_ANCHOR
#define MSG_LENGTH_MAX 256
#define LONELY_TO_DIE (30000)
//============<parameters>============
//
// LED status indication
// phase 0
// - LED => steady on
// - booted. and running. no connection. scanning.
// phase 1
// - LED => slow blinking (syncronized)
// - + connected.
#if defined(ARDUINO_ESP8266_NODEMCU) // nodemcuv2
#define LED_PIN 2
#elif defined(ARDUINO_ESP8266_ESP12) // huzzah
#define LED_PIN 2
#elif defined(ARDUINO_FEATHER_ESP32) // featheresp32
#define LED_PIN 13
#endif #endif
#define LED_PERIOD (1111)
#define LED_ONTIME (1)
//
#include <Arduino.h>
//
#include <painlessMesh.h>
// painless mesh // painless mesh
painlessMesh mesh; painlessMesh mesh;
// firmata
#if (FIRMATA_USE == FIRMATA_ON)
#include <Firmata.h>
#endif
//scheduler //scheduler
Scheduler runner; Scheduler runner;
@ -30,23 +88,17 @@ bool isConnected = false;
//prototypes //prototypes
void taskStatusBlink_steadyOn(); void taskStatusBlink_steadyOn();
void taskStatusBlink_slowblink_insync(); void taskStatusBlink_slowblink_insync();
void taskStatusBlink_fastblink();
void taskStatusBlink_steadyOff(); void taskStatusBlink_steadyOff();
//the task //the task
Task statusblinks(0, 1, &taskStatusBlink_steadyOn); // at start, steady on. default == disabled. ==> setup() will enable. Task statusblinks(0, 1, &taskStatusBlink_steadyOn); // at start, steady on. default == disabled. ==> setup() will enable.
// when disconnected, steadyon. // when disconnected, and trying, steadyon.
void taskStatusBlink_steadyOn() { void taskStatusBlink_steadyOn() {
onFlag = true; onFlag = true;
} }
// blink per 1s. sync-ed. // when connected, blink per 1s. sync-ed. (== default configuration)
void taskStatusBlink_slowblink_insync() { void taskStatusBlink_slowblink_insync() {
// toggler // toggler
if (onFlag) { onFlag = !onFlag;
onFlag = false;
}
else {
onFlag = true;
}
// on-time // on-time
statusblinks.delay(LED_ONTIME); statusblinks.delay(LED_ONTIME);
// re-enable & sync. // re-enable & sync.
@ -55,9 +107,7 @@ void taskStatusBlink_slowblink_insync() {
statusblinks.enableDelayed(LED_PERIOD - (mesh.getNodeTime() % (LED_PERIOD*1000))/1000); //re-enable with sync-ed delay statusblinks.enableDelayed(LED_PERIOD - (mesh.getNodeTime() % (LED_PERIOD*1000))/1000); //re-enable with sync-ed delay
} }
} }
void taskStatusBlink_fastblink() { // when connected, steadyoff. (== alternative configuration)
}
// when connected, steadyoff. (?)
void taskStatusBlink_steadyOff() { void taskStatusBlink_steadyOff() {
onFlag = false; onFlag = false;
} }
@ -78,10 +128,14 @@ void nothappyalone() {
// okay. i m fed up. bye the world. // okay. i m fed up. bye the world.
Serial.println("okay. i m fed up. bye the world."); Serial.println("okay. i m fed up. bye the world.");
Serial.println(); Serial.println();
#if (BOARD_SELECT == BOARD_NODEMCU_ESP12E) #if defined(ESP8266)
ESP.reset(); ESP.reset();
#elif (BOARD_SELECT == BOARD_NODEMCU_ESP32) #elif defined(ESP32)
ESP.restart(); // esp32 doesn't support 'reset()' yet... (restart() is framework-supported, reset() is more forced hardware-reset-action) ESP.restart();
// esp32 doesn't support 'reset()' yet...
// (restart() is framework-supported, reset() is more forced hardware-reset-action)
#else
#error unknown
#endif #endif
} }
} }
@ -92,8 +146,9 @@ Task nothappyalone_task(1000, TASK_FOREVER, &nothappyalone, &runner, true); // b
// mesh callbacks // mesh callbacks
void receivedCallback(uint32_t from, String & msg) { // REQUIRED void receivedCallback(uint32_t from, String & msg) { // REQUIRED
// let the member device know. // give it to I2C device
gotMessageCallback(from, msg); /////
Serial.print("Got one.");
} }
void changedConnectionCallback() { void changedConnectionCallback() {
// check status -> modify status LED // check status -> modify status LED
@ -114,30 +169,26 @@ void changedConnectionCallback() {
// //
isConnected = false; isConnected = false;
} }
// let the member device know. // let I2C device know
gotChangedConnectionCallback(); /////
Serial.println("Conn. change.");
} }
void newConnectionCallback(uint32_t nodeId) { void newConnectionCallback(uint32_t nodeId) {
changedConnectionCallback(); changedConnectionCallback();
} }
void setup_member();
void setup() { void setup() {
//led //led
pinMode(LED_PIN, OUTPUT); pinMode(LED_PIN, OUTPUT);
//mesh //mesh
WiFiMode_t node_type = WIFI_AP_STA; WiFiMode_t node_type = WIFI_AP_STA;
#if (NODE_TYPE == NODE_TYPE_STA_ONLY) #if defined(DISABLE_AP)
system_phy_set_max_tpw(0); system_phy_set_max_tpw(0);
node_type = WIFI_STA; node_type = WIFI_STA;
#endif #endif
#if (FIRMATA_USE == FIRMATA_ON)
mesh.setDebugMsgTypes( ERROR );
#elif (FIRMATA_USE == FIRMATA_OFF)
// mesh.setDebugMsgTypes(ERROR | DEBUG | CONNECTION); // mesh.setDebugMsgTypes(ERROR | DEBUG | CONNECTION);
mesh.setDebugMsgTypes( ERROR | STARTUP ); mesh.setDebugMsgTypes( ERROR | STARTUP );
#endif
mesh.init(MESH_SSID, MESH_PASSWORD, &runner, MESH_PORT, node_type, MESH_CHANNEL); mesh.init(MESH_SSID, MESH_PASSWORD, &runner, MESH_PORT, node_type, MESH_CHANNEL);
// //
@ -145,7 +196,7 @@ void setup() {
// void init(String ssid, String password, uint16_t port = 5555, WiFiMode_t connectMode = WIFI_AP_STA, uint8_t channel = 1, uint8_t hidden = 0, uint8_t maxconn = MAX_CONN); // void init(String ssid, String password, uint16_t port = 5555, WiFiMode_t connectMode = WIFI_AP_STA, uint8_t channel = 1, uint8_t hidden = 0, uint8_t maxconn = MAX_CONN);
// //
#ifdef MESH_ANCHOR #if defined(MESH_ANCHOR)
mesh.setContainsRoot(true); mesh.setContainsRoot(true);
#endif #endif
//callbacks //callbacks
@ -157,20 +208,12 @@ void setup() {
runner.addTask(statusblinks); runner.addTask(statusblinks);
statusblinks.enable(); statusblinks.enable();
#if (FIRMATA_USE == FIRMATA_ON)
Firmata.setFirmwareVersion(0,1);
Firmata.attach(ANALOG_MESSAGE, analogWriteCallback);
Firmata.begin(57600);
#elif (FIRMATA_USE == FIRMATA_OFF)
//serial //serial
Serial.begin(9600); Serial.begin(9600);
delay(100); delay(100);
Serial.println("setup done."); Serial.println("hi, postman ready.");
Serial.print("IDENTITY: "); #if defined(DISABLE_AP)
Serial.println(IDENTITY);
#if (NODE_TYPE == NODE_TYPE_STA_ONLY)
Serial.println("INFO: we are in the WIFI_STA mode!"); Serial.println("INFO: we are in the WIFI_STA mode!");
#endif
#endif #endif
//understanding what is 'the nodeId' ==> last 4 bytes of 'softAPmacAddress' //understanding what is 'the nodeId' ==> last 4 bytes of 'softAPmacAddress'
@ -203,22 +246,16 @@ void setup() {
// nodeId (hex) : 2D370A07 // nodeId (hex) : 2D370A07
// MAC : B6, E6, 2D, 37, A, 7 // MAC : B6, E6, 2D, 37, A, 7
//setup_member //i2c
setup_member(); Serial.println("TODO. we need to setup I2C.");
} }
void loop() { void loop() {
runner.execute(); runner.execute();
mesh.update(); mesh.update();
#if (BOARD_SELECT == BOARD_NODEMCU_ESP32) #if defined(ESP32)
digitalWrite(LED_PIN, onFlag); // value == true is ON. digitalWrite(LED_PIN, onFlag); // value == true is ON.
#else #else
digitalWrite(LED_PIN, !onFlag); // value == false is ON. so onFlag == true is ON. (pull-up) digitalWrite(LED_PIN, !onFlag); // value == false is ON. so onFlag == true is ON. (pull-up)
#endif #endif
#if (FIRMATA_USE == FIRMATA_ON)
while (Firmata.available()) {
Firmata.processInput();
}
#endif
} }

View file

@ -1,11 +0,0 @@
This directory is intended for PIO Unit Testing and project tests.
Unit Testing is a software testing method by which individual units of
source code, sets of one or more MCU program modules together with associated
control data, usage procedures, and operating procedures, are tested to
determine whether they are fit for use. Unit testing finds problems early
in the development cycle.
More information about PIO Unit Testing:
- https://docs.platformio.org/page/plus/unit-testing.html