====== B3 - version 2 ======
Version sans fils, avec de plus petits solenoides, led plus puissantes (3W) et batterie intégrée.
Sources : https://git.framasoft.org/resonance/b3/tree/master
===== Électronique =====
**Idée de départ**
{{:projets:b3:v2:b3-v2.jpg?1000|}}
**09/03/2017**
{{:projets:b3:v2:b3-v2-20170309.jpg?800|}}
===== Code ESP8266 =====
* Installation et configuration sur notre page dédiée : [[materiel:esp8266:accueil|ESP8266]]
==== v1 ====
* Fichiers : {{ :projets:b3:v2:b3_wemosd1_udp.zip |}}
Communication en UDP, réception d'une seule valeur pour l'instant avec Pure Data pour contrôler le temps d'allumage des solénoides. (voir sources). Les modules ESP8266 se connectent à un réseau Wi-Fi "linksys" créé par un routeur Wi-Fi avec une adresse IP statique.
++++ Code Arduino |
/*
* B3
* Control solenoids and lights through Wi-Fi network (UDP)
* Website : http://reso-nance.org/projets/b3/accueil
*
* Setup : Pure Data > "linksys" Wi-Fi router > ESP8266 modules
* Message : Id (0,1,2) Delay (0-120).
* ID 0 = pin 11, ID 1 = pin 12, ID 2 = pin 13
*
* Author : Jerome Abel / http://jeromeabel.net
* Licence : GNU/GPL3
*/
#include
#include
#include "Solenoid.h"
const boolean DEBUG = false;
// NETWORK SETUP
char ssid[] = "linksys"; // Name of the Wi-Fi network
char pass[] = ""; // No password
IPAddress ip(192, 168, 0, 111); // Local IP (static)
IPAddress gateway(192, 168, 0, 1); // Router IP
const unsigned int localPort = 8888; // Local Port
// OTHER SETUP
IPAddress subnet(255, 255, 255, 0);
char packetBuffer[255]; // Incoming
String data[2]; // Store incoming data
int status = WL_IDLE_STATUS;
WiFiUDP udp;
// ---- CONFIGURATIONS ---- //
const int PINS[] = {12, 13, 14}; // Pins for ESP8266 Wemos like 11, 12, 13 Arduino pins
const int DELAY_MAX = 50;
const int NB = 3;
const int TEMPO = 10; // Sampling tempo
// ---- SOLENOIDS --------- //
Solenoid solenoids[NB];
int solenoid_id, solenoid_delay;
unsigned long current = 0;
void setup() {
// Output
for (int i=0; i < NB; i++) {
solenoids[i].init(PINS[i], DELAY_MAX, DEBUG);
}
// WiFi Connection
WiFi.config(ip, gateway, subnet); // Static IP Address
WiFi.begin(ssid, pass);
while (WiFi.status() != WL_CONNECTED)
{
delay(500);
}
// UDP Connection
udp.begin(localPort);
if (DEBUG)
{
Serial.begin(115200);
Serial.print("IP: ");
Serial.println(WiFi.localIP());
}
}
void loop() {
// UPDATE TIME
current = millis();
// Read data if available
int packetSize = udp.parsePacket();
if (packetSize)
{
// Read the packet into packetBuffer
int len = udp.read(packetBuffer, 255);
if (len > 0) packetBuffer[len] = 0;
// Parse with space delimiter ' ' and fill data[]
String strData(packetBuffer);
splitString(strData, ' ');
solenoid_id = data[0].toInt(); // get ID
solenoid_delay = data[1].toInt(); // get Delay
// SOLENOID ON
if( solenoids[solenoid_id].isOn() == false ) solenoids[solenoid_id].on(current, solenoid_delay);
}
// SOLENOID OFF
for (int i=0; i < NB; i++) {
if( solenoids[i].isOn() ) solenoids[i].off(current);
}
}
// Méthode pour découper le message avec un séparateur (ou "parser")
// Split string messages with a separator character
void splitString(String message, char separator) {
int index = 0;
int cnt = 0;
do {
index = message.indexOf(separator);
// s'il y a bien un caractère séparateur
if(index != -1) {
// on découpe la chaine et on stocke le bout dans le tableau
data[cnt] = message.substring(0,index);
cnt++;
// on enlève du message le bout stocké
message = message.substring(index+1, message.length());
} else {
// après le dernier espace
// on s'assure que la chaine n'est pas vide
if(message.length() > 0) {
data[cnt] = message.substring(0,index); // dernier bout
cnt++;
}
}
} while(index >=0); // tant qu'il y a bien un séparateur dans la chaine
}
++++
==== v2 - nov 2017 ====
++++ Code Arduino |
/*
* B3
* Control solenoids and LEDs through Wi-Fi network (UDP)
* Website: http://reso-nance.org/projets/b3/accueil
*
* Setup: Pure Data > "linksys" Wi-Fi router > ESP8266 modules
* Messages Solenoids: Id (0,1,2) Delay (0-120).
* Messages Leds: Id (3,4,5) Pwm (0-255)
*
* Arduino | Wemos Mapping
* D0 3
* D1 1
* D2 16
* D3 5
* D4 4
* D5/D13 14
* D6/D12 12
* D7/D11 13
* D8 0 (Pull-up)
* D9 2 (Pull-up, buildin led)
* D10 15 (Pull-down)
*
* Author : Jerome Abel / http://jeromeabel.net
* Licence : GNU/GPL3
*/
#include
#include
#include "Solenoid.h"
const boolean DEBUG = true;
// NETWORK SETUP TPLINK
/*
* char ssid[] = "tplink1"; // Name of the Wi-Fi network
IPAddress ip(192, 168, 0, 111); // Local IP (static)
IPAddress gateway(192, 168, 0, 1); // Router IP
*/
// NETWORK SETUP LINKSYS
char ssid[] = "linksys"; // Name of the Wi-Fi network
IPAddress ip(192, 168, 1, 111); // Local IP (static)
IPAddress gateway(192, 168, 1, 1); // Router IP
char pass[] = ""; // No password
const unsigned int localPort = 8888; // Local Port
// OTHER SETUP
IPAddress subnet(255, 255, 255, 0);
char packetBuffer[255]; // Incoming
String data[2]; // Store incoming data
int status = WL_IDLE_STATUS;
WiFiUDP udp;
// ---- CONFIGURATIONS ---- //
const int LEDS[] = {13, 12, 14}; // Arduino: D11, D12, D13
const int PINS[]= {1, 5, 4};// Arduino: D1, D3, D4
const int DELAY_MAX = 50;
const int NB = 3;
const int TEMPO = 10; // Sampling tempo
// ---- SOLENOIDS --------- //
Solenoid solenoids[NB];
int id, solenoid_delay;
unsigned long current = 0;
void setup() {
// Output solenoids
for (int i=0; i < NB; i++) {
solenoids[i].init(PINS[i], DELAY_MAX, DEBUG);
}
// Output LEDs
for (int i=0; i < NB; i++) {
pinMode(LEDS[i], OUTPUT);
digitalWrite(LEDS[i], HIGH); // OFF (LEDS)
}
// WiFi Connection
WiFi.config(ip, gateway, subnet); // Static IP Address
WiFi.begin(ssid, pass);
while (WiFi.status() != WL_CONNECTED)
{
delay(500);
}
// UDP Connection
udp.begin(localPort);
if (DEBUG)
{
Serial.begin(115200);
Serial.print("IP: ");
Serial.println(WiFi.localIP());
}
}
void loop() {
// UPDATE TIME
current = millis();
// Read data if available
int packetSize = udp.parsePacket();
if (packetSize)
{
// Read the packet into packetBuffer
int len = udp.read(packetBuffer, 255);
if (len > 0) packetBuffer[len] = 0;
// Parse with space delimiter ' ' and fill data[]
String strData(packetBuffer);
splitString(strData, ' ');
id = data[0].toInt(); // get ID
// SOLENOID ON
if (id > 2) {
solenoid_delay = data[1].toInt(); // get Delay
if( solenoids[id-3].isOn() == false ) solenoids[id-3].on(current, solenoid_delay);
}
// LEDS ON
else {
analogWrite(LEDS[id], data[1].toInt() * 4 );
}
}
// SOLENOID OFF
for (int i=0; i < NB; i++) {
if( solenoids[i].isOn() ) solenoids[i].off(current);
}
}
// Méthode pour découper le message avec un séparateur (ou "parser")
// Split string messages with a separator character
void splitString(String message, char separator) {
int index = 0;
int cnt = 0;
do {
index = message.indexOf(separator);
// s'il y a bien un caractère séparateur
if(index != -1) {
// on découpe la chaine et on stocke le bout dans le tableau
data[cnt] = message.substring(0,index);
cnt++;
// on enlève du message le bout stocké
message = message.substring(index+1, message.length());
} else {
// après le dernier espace
// on s'assure que la chaine n'est pas vide
if(message.length() > 0) {
data[cnt] = message.substring(0,index); // dernier bout
cnt++;
}
}
} while(index >=0); // tant qu'il y a bien un séparateur dans la chaine
}
++++
===== Code Pure Data =====
* Fichiers de tests : {{ :projets:b3:v2:puredata.zip |}}
{{:projets:b3:v2:b3-help.png?|}}
{{:projets:b3:v2:dsc_9039.jpg?800|}}
===== Fabrication =====
{{ :projets:b3:v2:dsc_7423.jpg?400|}}
{{ :projets:b3:v2:dsc_9035.jpg?400|}}
{{ :projets:b3:v2:dsc_9043.jpg?400|}}
{{:projets:b3:v2:dsc_9036.jpg?400|}}
----
===== Vidéo =====
{{:projets:b3:v2:test-nov-2017.webm|}}