Robots tapeurs

Je reprends les petits robots tapoteurs pour actionner un solénoïde frappant des cordes sur l'installation.

Ils sont commandés par un patch puredata de Dom en fonction de l'environnement sonore.

Le dernier code

/* Wemos_tapeur
  gepeto@du-libre.org 2018
  objet frappant , commande par Wifi / OSC
  la commande OSC est programmable
  // a cause de OSC sur purdata on garde que des float !
  sorties :  1, 2, 4, 5, 6, 7 //ok pour 1,2,4,5,6,7
  /tap   \(float\) \(float\) ms \(float\) duree \(float\) pwm-force"));
  /tap   ffff 6 200 2000 1000
  /tap 6  vide arrete 6
  /stop arrete tout
  /modforce 2 500 modif force de frappe du 2 en 500
 
  Pour entrer dans le setup il faut allumer l'ESP en touchant A0
  la led clignote rapidement
  on se connecte sur le SSID SNHACKTAP 192.168.4.1
  apres validation la led clignote doucement
 
  Matériel: ESP Wemos + driver wemos moteur + platine wemos alimentation
 
*/
#include <ESP8266WiFi.h>
#include <ESP8266WiFiMulti.h>
#include <ESP8266mDNS.h>
 
#include <WiFiUdp.h>
//#include <DNSServer.h>
// OSC
#include <OSCMessage.h>
#include <OSCBundle.h>
#include <OSCData.h>
//
///////////////////////////////////////////////////////////
// DEFINITION DU TAPEUR A MODIFIER //
//
//  nom TAPEUR-1 pour IP 192.168.0.121
//      TAPEUR-2 pour IP 192.168.0.122   etc
//
 
ESP8266WiFiMulti wifiMulti;
 
IPAddress tapeur_ip(192, 168, 43, 121);
//IPAddress tapeur_ip(192, 168, 0, 121);
const char* nomhost = "TAPEUR-2";
 
char osc_port[6] = "9005"; // si besoin
 
const char* ssid1 = "Xperia XA Dual_5321";
const char* password1 = "&1Dom3000";
const char* ssid2 = "SNHACK";
const char* password2 = "1234567890";
 
//const char* ssid2 = "NORD";
//const char* password2 = "1234567890";
//const char* ssid3 = "SUD";
//const char* password3 = "1234567890";
//const char* ssid4 = "kerminy";
//const char* password4 = "1234567890";
 
/////// FIN //////////////////////////////////////////////
//////////////////////////////////////////////////////////
IPAddress mask(255, 255, 255, 0);
IPAddress passerelle(192, 168, 0,80);
const char DEVICE_NAME[] = "SNHACKTAP";
int osc_port_int = 0;
unsigned long     frequence[9] = {0};
unsigned long     t_duree[9]   = {0} ;
int          pwm[9]       = {0};
int          sortie[9]    = {15, 15, 4, 0, 2, 14, 12, 13, 15};
//int          sortie[9]    = {16, 5, 4, 0, 2, 14, 12, 13, 15};
// 0,1,2... ok pour 1,2,4,5,6,7 pas 0 3 8
//D0-16
//D1 5
//D2 4 up (led)
//D3 0
//D4 2
//D5 14
//D6 12
//D7 13
//D8 15 down
//└─ $ ▶ ./osc.py send 192.168.0.121:9005 /tap 1 20 100 1000
 
unsigned long     t_debut[9]   = {0} ;
unsigned long     t_encours[9] = {0} ;
 
WiFiUDP Udp;     // A UDP instance to let us send and receive packets over UDP
//const IPAddress outIp(192, 168, 0, 161);     // remote IP to receive OSC
const IPAddress outIp(192, 168, 0, 181);     // remote IP to receive OSC
IPAddress _ip;
OSCErrorCode error;
 
//converts the pin to an osc address
char * numToOSCAddress(int pin) {
  static char s[10];
  int i = 9;
 
  s[i--] = '\0';
  do
  {
    s[i] = "0123456789"[pin % 10];
    --i;
    pin /= 10;
  }
  while (pin && i);
  s[i] = '/';
  return &s[i];
}
 
void arreter(OSCMessage &msg) {
  for (int i = 0; i <= 8; i++) { //  //ok pour 1,2,4,5,6,7
    analogWrite(sortie[i], 0);
    frequence[i] = 0;
    t_duree[i] = 0;
  }
}
 
void taper(OSCMessage &msg) {
  Serial.println("/tap");
  int pin = (int) msg.getFloat(0);
  if (pin == 1 || pin == 2 || pin == 4  || pin == 5 || pin == 6 || pin == 7 ) { // 1,2,4,5,6,7 ok
    frequence[pin] = (unsigned long)msg.getFloat(1);
    if (frequence[pin] > 0) {
      if (msg.isFloat(2)) {
        t_duree[pin] = (unsigned long)msg.getFloat(2);
      } else t_duree[pin] = 3;
 
      t_debut[pin] = millis();
      t_encours[pin] = t_debut[pin];
 
      if (msg.isFloat(3)) pwm[pin] = (int)msg.getFloat(3);
      else pwm[pin] = 1000;
    }
    //if (t_duree[pin] > 0 && 2*frequence[pin] > t_duree[pin]) t_duree[pin] = frequence[pin] + 10;
    //if (t_duree[pin] < 3) t_duree[pin] = 3;
    //t_duree[pin] += millis();
    Serial.println(pin);
    Serial.println(frequence[pin]);
    Serial.println(t_duree[pin]);
    Serial.println(pwm[pin]);
    //Serial.println(t_debut[pin] + t_duree[pin]);
    //Serial.println("=========");
 
  }
}
void modpwm(OSCMessage &msg) {
  Serial.println("/modforce");
  int pin = (int) msg.getFloat(0);
  if (pin == 1 || pin == 2 || pin == 4  || pin == 5 || pin == 6 || pin == 7 ) { // 1,2,4,5,6,7 ok
    long modforce = (unsigned long)msg.getFloat(1);
    if (modforce > 0 && modforce <= 1000 ) {
      pwm[pin] = (int)modforce;
      Serial.println(pwm[pin]);
    }
  }
}
void setup(void) {
  Serial.begin(115200);
  //set led pin as output
  pinMode(BUILTIN_LED, OUTPUT);
  //pinMode(Bouton_init, INPUT);
  //BoutonParam = HIGH;
  Serial.println((int32_t)ESP.getChipId());
  delay(1000);
  int BoutonParam = analogRead(A0);
  // start ticker with 0.5 because we start in AP mode and try to connect
  //ticker.attach(0.6, tick);// clignote
  // a cause de OSC sur purdata on garde que des float !
  Serial.println(F("sorties :  1, 2, 4, 5, 6, 7 ??")); //ok pour 1,2,4,5,6,7
  Serial.println(F("format: /tap   \(float\) \(float\) ms \(float\) duree \(float\) pwm-force"));
  Serial.println(F("format: /tap   ffff 6 200 1000 1000"));
  Serial.println(F("/tap 6  vide arrete 6"));
  Serial.println(F("/modforce 6  500 modif force de frappe du 6 en 500"));
  Serial.println(F("/stop arrete tout"));
  Serial.println(F("init des sorties"));
 
  for (int i = 0; i <= 8; i++) { //  //ok pour 1,2,4,5,6,7
    if (i == 0 || i == 3 || i == 8) continue ;
    pinMode(sortie[i], OUTPUT);
    analogWrite(sortie[i], 0);
  }
 
  WiFi.disconnect();
  WiFi.mode(WIFI_STA);
  wifiMulti.addAP(ssid1, password1);
  wifiMulti.addAP(ssid2, password2);
  //wifiMulti.addAP(ssid3, password3);
  //wifiMulti.addAP(ssid4, password4);
  Serial.print("tente ");
  Serial.println(ssid1);
  Serial.println(ssid2);
//  Serial.println(ssid3);
//  Serial.println(ssid4);
  WiFi.hostname(nomhost);      // DHCP Hostname (useful for finding device for static lease)
  WiFi.config(tapeur_ip, passerelle, mask);  // (DNS not required)
  while (wifiMulti.run() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  osc_port_int = atoi(osc_port);
  Serial.println(F("TOUT OK WiFi connected! IP address: "));
  Serial.println(WiFi.localIP());
  Serial.print(WiFi.hostname());
  Serial.println(F(".local"));
  Serial.print(F("sur port :"));
  Serial.println(osc_port);
  delay(100);
  Udp.begin(osc_port_int);
  Serial.print(F("Local port: "));
  Serial.println(Udp.localPort());
 
  // Set up mDNS responder:
  // - first argument is the domain name, in this example
  //   the fully-qualified domain name is "esp8266.local"
  // - second argument is the IP address to advertise
  //   we send our IP address on the WiFi network
  if (!MDNS.begin(WiFi.hostname())) {
    Serial.println("Error setting up MDNS responder!");
  }
  Serial.println("mDNS responder started");
 
}
void loop() {
  //////////// OSC ////////////////////////
  //reads and dispatches the incoming message
  OSCMessage msgIN;
 
  int size;
  //char puce_char[] = "  ";
  if ( (size = Udp.parsePacket()) > 0)
  {
    while (size--)
      msgIN.fill(Udp.read());
    if (!msgIN.hasError()) {
      msgIN.dispatch("/tap", taper);
      msgIN.dispatch("/modforce", modpwm);
      msgIN.dispatch("/stop", arreter);
      Serial.println(size);
    } else {
      error = msgIN.getError();
      Serial.print("error: ");
      Serial.println(error);
    }
    Udp.flush();
  }
 
  //////////////// boucle actions /////////////////
  //delay(300); /////////
  for (int i = 0; i <= 8; i++) { //  //ok pour 1,2,4,5,6,7
    if (i == 0 || i == 3 || i == 8) continue ;  // 1,2,4,5,6,7 ok
    unsigned long t_temps = millis();
    //Serial.println("");
    //Serial.println(t_temps);
    //Serial.println(t_debut[i]);
    //Serial.println(t_duree[i]);
    //Serial.println(t_debut[i] + t_duree[i]);
    //Serial.println("---");
    if (frequence[i] == 0) {
      analogWrite(sortie[i], 0);
      //Serial.println("OF");
      continue;
    }
    if (t_temps <= t_debut[i] + t_duree[i]) { // on est dans l action t_duree
      //Serial.print("o");
      //Serial.println(t_encours[i] + (frequence[i] ));
      if ( t_temps <= t_encours[i] + (frequence[i]) ) {  // debut cycle < prochain cycle
        //Serial.println("n");
        analogWrite(sortie[i], pwm[i]);
      } else if ( t_temps <= t_encours[i] + ( frequence[i] * 2) ) {
        //Serial.println("f");
        analogWrite(sortie[i], 0);                            // entre 2 cycle
      }
      else {
        t_encours[i] = millis();                   // recommence nouveau cycle
      }
    } else { // en dehors de l action
      analogWrite(sortie[i], 0);
    }
  }
}