Wiki

Reso-nance numérique | Arts et cultures libres

Outils du site


projets:chimeres-orchestra:code-arduino:accueil

Différences

Ci-dessous, les différences entre deux révisions de la page.

Lien vers cette vue comparative

Les deux révisions précédentes Révision précédente
Prochaine révision
Révision précédente
projets:chimeres-orchestra:code-arduino:accueil [2015/03/30 15:42]
resonance [Code Arduino]
projets:chimeres-orchestra:code-arduino:accueil [2017/02/10 17:46] (Version actuelle)
resonance [Arduino Chimères OSC]
Ligne 1: Ligne 1:
 ====== Code Arduino ====== ====== Code Arduino ======
    
 +A tester ([[http://antoine.villeret.free.fr/?p=719|source]]) :\\
 +  * [[http://inotool.org/]] pour téléverser les programmes sur des Arduinos
  
-==== Serial / Arduino / PwmMotor library ====+<code bash> 
 +#!/bin/bash 
 +for arduino in /dev/ttyACM* ; 
 +do 
 +ino upload -m micro -p $arduino 
 +sleep 1 
 +done 
 +</code> 
 + 
 + 
 +===== Arduino Chimères OSC ===== 
 +  * Fichiers : {{:projets:chimeres-orchestra:code-arduino:chimeresorchestra-arduino-201702.zip|}} 
 + 
 +Réception des données via le protocole OSC. 
 + 
 +++++ chimeres-osc | 
 +<code cpp> 
 +/* 
 + * Chimères Orchestra 
 + * ================= 
 + * Robots drummers in public space by Reson-nance Numérique 
 + *  
 + * Website: 
 + * http://reso-nance.org/chimeres-orchestra  
 + * 
 + * Setup:  
 + * Ethernet (OSC) > Ethernet Shield > Arduino MEGA > Power Shield MOSFETS > DC Motors 
 + *  
 + * Wiring: 
 + * Ethernet Shield  Arduino MEGA  Power Shield 
 + * ===============  ============  ============ 
 + * 10               10 (53)      
 + * 11               11 (51) 
 + * 12               12 (50) 
 + * 13               13 (52) 
 + * 5V               5V 
 + * GND              GND           GND 
 +                  2             3 
 +                  3             5 
 +                  5             6 
 +                  6             9 
 +                  7             10 
 +                  8             11 
 + *  
 + * OSC message:  
 + * /arm Id (int 0-5), PWM (int 0-255), Delay (int 0-100) 
 + *  
 +*/ 
 + 
 +#include <SPI.h> 
 +#include <Ethernet.h> 
 +#include <ArdOSC.h> 
 + 
 +#include "PwmMotor.h" 
 + 
 +// ---- NETWORK ---- // 
 +byte myIp[] = { 192, 168, 0, 105 }; // IP 
 +int serverPort = 9105; // Receive port 
 +byte myMac[] = {  0xED, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; // MAC address 
 +// 101 UDOO 
 +// 102 { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED } 
 +// 103 { 0xEE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED } 
 +// 104 { 0xDD, 0xAD, 0xBE, 0xEF, 0xFE, 0xED } 
 +// 105 { 0xED, 0xAD, 0xBE, 0xEF, 0xFE, 0xED } 
 +// 106 { 0xCD, 0xAD, 0xBE, 0xEF, 0xFE, 0xED } 
 + 
 +char oscmsg[]="/arm"; 
 + 
 +OSCServer server; // to receive messages 
 + 
 +// ---- CONFIGURATIONS ---- // 
 +const int PINS[] = {2,3,5,6,7,8}; // pins Mosfets Shield (for MEGA because Ethernet Shield use 10,11,12,13 pin and 4th pin for SD Card) 
 +const int TIME_MAX = 120; 
 +const int NB = 6; 
 +const int TEMPO = 10; // sampling tempo 
 +const boolean DEBUG = true; 
 + 
 +// ---- MOTORS --------- // 
 +int motor_id, motor_pwm, motor_time; 
 +PwmMotor motors[NB]; 
 +unsigned long current = 0; 
 + 
 +// ---- SETUP ----------- // 
 +void setup() { 
 + Ethernet.begin(myMac,myIp);  
 + server.begin(serverPort); 
 + server.addCallback(oscmsg, &get_osc); // callback function (receive) 
 + 
 + if (DEBUG) Serial.begin(38400); 
 + 
 + for (int i=0; i < NB; i++) { 
 +     motors[i].init(PINS[i], TIME_MAX, DEBUG); 
 +  } 
 +
 + 
 +// ---- PROGRAM ----------- // 
 +void loop() { 
 +  // UPDATE TIME 
 +  current = millis(); 
 + 
 +  if(server.availableCheck()>0){ 
 +    // alive  
 +    } 
 + 
 +  // MOTOR OFF 
 +  for (int i=0; i < NB; i++) { 
 +     if( motors[i].isOn() ) motors[i].off(current); 
 +  } 
 + 
 +  delay(TEMPO); 
 +
 + 
 +// Get OSC Message 
 +void get_osc(OSCMessage *_mes){ 
 +  motor_id=_mes->getArgInt32(0); 
 +  motor_pwm=_mes->getArgInt32(1); 
 +  motor_time=_mes->getArgInt32(2); 
 + 
 +  if (DEBUG) { 
 +    Serial.print(motor_id); 
 +    Serial.print(motor_pwm); 
 +    Serial.println(motor_time); 
 +  } 
 +   
 +  // MOTOR ON 
 +  if( motors[motor_id].isOn() == false ) motors[motor_id].on(current, motor_pwm, motor_time); 
 +
 +</code> 
 +++++ 
 +===== Idem avec capteur de présence (série) ===== 
 +  * Fichiers : {{:projets:chimeres-orchestra:code-arduino:chimeresorchestra_arduino_sensor_20161104.zip|}} 
 + 
 + 
 +++++ chimeres_capteur | 
 +<code cpp> 
 +// Chimères Orchestra 
 +// Raspberry Pi > Pd > Serial > Arduino MEGA > MOSFETS 
 +// Digital sensor to activate 
 + 
 +#include "PwmMotor.h" 
 + 
 +// ---- CONFIGURATIONS ---- // 
 +int pins[] = {3,5,6,9,10,11}; // pins Shield Mosfets 
 +int time_max = 150; 
 +boolean DEBUG = false; 
 + 
 +// ---- VARIABLES --------- // 
 +int id, pwm, time; 
 +const int nb = 6; 
 +PwmMotor motors[nb]; 
 +unsigned long current = 0; 
 + 
 +unsigned long button_interval = 50; 
 +unsigned long button_previous = 0; 
 +int button_state = 0; 
 +int button_last_state = 0; 
 +int button_pin = 2; //2,4,7,8,12,13 
 + 
 + 
 +// ---- PROGRAM ----------- // 
 +void setup() { 
 +  Serial.begin(38400); 
 +   for (int i; i < nb; i++) { 
 +     motors[i].init(pins[i], time_max, DEBUG); 
 +  } 
 +
 + 
 +void loop() { 
 +  current = millis(); 
 +   
 +  // Sensor 
 +  if(current - button_previous > button_interval) { // sampling 
 +      button_previous = current;  
 +      button_state = digitalRead(button_pin); 
 +      if (button_state != button_last_state) {       // if the state has changed 
 +        Serial.println(button_state); 
 +      } 
 +      button_last_state = button_state; 
 +  } 
 + 
 +  // ON 
 +  while (Serial.available()) { 
 +     id = Serial.parseInt();  
 +     pwm = Serial.parseInt(); 
 +     time = Serial.parseInt(); 
 +     if (Serial.read() == '\n') { 
 +       if( motors[id].isOn() == false )  motors[id].on(current, pwm, time); 
 +     } 
 +   } 
 +   
 +  // OFF 
 +  for (int i; i < nb; i++) { 
 +     if( motors[i].isOn() ) motors[i].off(current); 
 +  } 
 +   
 +  delay(5); 
 +
 +</code> 
 +++++ 
 +===== Serial / Arduino / PwmMotor library =====
   * Fichiers : {{:projets:chimeres-orchestra:code-arduino:chimeres_serial_interval_pwm.zip|}}   * Fichiers : {{:projets:chimeres-orchestra:code-arduino:chimeres_serial_interval_pwm.zip|}}
  
Ligne 13: Ligne 214:
  
 // ---- CONFIGURATIONS ---- // // ---- CONFIGURATIONS ---- //
-int pins[] = {3,5,6,9,10,11};+int pins[] = {2,3,4,5,6,7};
 int time_max = 150; int time_max = 150;
 boolean DEBUG = false; boolean DEBUG = false;
Ligne 360: Ligne 561:
      }      }
   }   }
 +}
 +</code>
 +++++
 +
 +
 +===== Dublin 06/2012 =====
 +  * Code répéteur autonome (avec piezo) 
 +  * Fichiers : {{:projets:chimeres-orchestra:code-arduino:chimeresorchestra_0_04.zip|}}
 +
 +++++ Code autonome |
 +<code cpp>
 +// Not tested !
 +// TO DO : verify input sensor and automatic, verify sequences modes
 +
 +// ******************************************* //
 +// Chimères Orchestra
 +// Robotic drums in public space
 +// In the "Hack the city" exhibition, Science Gallery, Dublin
 +// http://jeromeabel.net/art/chimeres-orchestra
 +// Jérome Abel - 22/06/2012
 +// GNU/GPL v3
 +// ******************************************* //
 +
 +// LIEU
 +// 0 : Gallery, 1 : Meeting house square (left side), 2 : Meeting house square (right side)
 +int LOCATION = 0; 
 +
 +// SOLENOIDS
 +const int NUMBER = 5;
 +int solenoids_pins [][NUMBER] =
 +{
 +  {5,2,7,6,8}, // Gallery
 +  {4,6,8,12,5}, // Meeting house square (left side)
 +  {4,6,12,7,5}, // Meeting house square (right side)
 +};
 +
 +// DEBUG
 +boolean DEBUG = true;
 +
 +// AUTOMATIC TIME
 +//int auto_interval = 15*60000; // 15 minutes
 +int auto_interval = 20000; // 15 minutes
 +int auto_duration = 5000;
 +
 +// PIEZO
 +const int p_threshold = 80;
 +const int p_debounce = 100; // antirebond
 +const int p_interval = 12000; // after 8 seconds, rhythms stop
 +const int p_interval_min = 8000; // minimum
 +const int p_interval_max = 25000; // maximum
 +
 +const int p_declenchement_seq = 8; // number of hits to start rhythms 
 +const int p_pin = A0; // sensor pin
 +
 +// ATTACK TIME
 +int on = 35; // default setting
 +int s_attack_on = on; // default setting
 +int s_attack_on_min = 30;
 +int s_attack_on_max = 45;
 +
 +int off = 90;// default setting
 +int s_attack_off = off ; 
 +int s_attack_off_min = 80;
 +int s_attack_off_max = 110;
 +
 +int seq_interval = s_attack_on + s_attack_off;
 +
 +// ******************* RHYTHMS ********************* //
 +
 +// SEQUENCES 
 +boolean seq[][4] = 
 +{
 +{0,0,0,0}, // 0
 +{1,0,0,0}, // 1
 +{0,1,0,0}, // 2
 +{0,0,1,0}, // 3
 +{0,0,0,1}, // 4
 +{1,1,0,0}, // 5
 +{1,0,1,0}, // 6
 +{1,0,0,1}, // 7
 +{0,1,1,0}, // 8
 +{0,1,0,1}, // 9
 +{0,0,1,1}, // 10
 +{1,1,1,0}, // 11
 +{0,1,1,1}, // 12
 +{1,1,1,1}  // 13
 +};
 +
 +int patterns[][4] = 
 +{
 +{5,5,5,5}, //0
 +{4,4,4,12},
 +{0,1,1,1},
 +{1,1,1,1},
 +{1,1,1,2},
 +{2,2,3,2}, 
 +{3,3,3,3}, 
 +{4,4,4,4},
 +{7,5,5,5},
 +{5,5,5,0},
 +{3,5,3,5},
 +{1,7,1,7},
 +{0,12,0,13},
 +{4,5,4,0},
 +{9,9,4,9},
 +{2,6,6,2},
 +{7,1,7,1}, 
 +{12,0,12,0}, 
 +{13,13,13,0}, // 18
 +
 +// EXTRA
 +{12,0,0,0}, // 19
 +{0,0,0,5},
 +{0,0,0,9},
 +{2,5,0,0},
 +{0,3,0,3},
 +{3,0,5,0},
 +{6,6,0,0},
 +{0,0,0,13},
 +{0,0,0,8},
 +{0,0,0,11},
 +{0,0,12,0}, 
 +{0,1,0,1}, 
 +{0,0,1,1}, 
 +{0,1,1,0},
 +{2,0,2,0}, 
 +{0,0,2,5}, 
 +{1,0,11,0},
 +{0,13,11,0} //36
 +};
 +// *************************************************** //
 +int seq_counter = 0;
 +int seq_counter_pattern = 0;
 +
 +int seq_tempo = 0;
 +int solenoids_seq[6];
 +boolean auto_sequence = false;
 +int sequence_mode = 0;
 +
 +// TIME
 +unsigned long currentMillis = 0;
 +unsigned long previousMillis = 0;
 +int interval = 1000;
 +unsigned long auto_time = 0;
 +
 +// TAP TEMPO
 +unsigned long p_taptempo = 0;
 +float p_taptempo_average = 0;
 +float p_taptempo_total = 0;
 +float p_last_taptempo = 0;
 +
 +// PIEZO
 +int p_reading = 0;
 +boolean p_state = false;
 +boolean p_state_last = false;
 +long p_time = 0; 
 +int p_counter = 0;
 +long p_counter_time = 0;
 + 
 +// SEQUENCE
 +long alternate_time = 0; 
 +int random_seq = random(24,32);
 +int random_attack_time = random(16,32);
 +
 +
 +// ****************** getPiezo() ************************* //
 +boolean getPiezo(){
 +  p_reading = analogRead(p_pin);   
 +  if (p_reading >= p_threshold && currentMillis - p_time >= p_debounce) 
 +  {
 +    p_counter++; 
 +    
 +    if (DEBUG) 
 +    {
 +      Serial.println("============");  
 +      Serial.println("Knock!");  
 +      Serial.print("PIEZO COUNTER:");
 +      Serial.println(p_counter);
 +    }
 +    
 +    if (p_counter > 1) 
 +    {
 +      p_last_taptempo = p_taptempo;
 +      p_taptempo = currentMillis - p_time;
 +      if (DEBUG) 
 +      {
 +         Serial.print("TAPTEMPO:");
 +         Serial.println(p_taptempo);
 +      }
 +      p_taptempo_total = (int)p_taptempo + (int)p_last_taptempo;
 +      if (p_counter > 2)
 +      {
 +        p_taptempo_average = p_taptempo_total / 2 ;
 +        if (DEBUG)
 +        {
 +          Serial.print("AVERAGE:");
 +          Serial.println(p_taptempo_average);
 +        }
 +       }
 +     }
 +    
 +     p_time = currentMillis;
 +     return true;   
 +  } 
 +  else { return false;}
 +}
 +
 +// ***************** single_attack() **************** //
 +void single_attack(int pin){
 + digitalWrite(pin, HIGH); 
 + delay(s_attack_on);
 + digitalWrite(pin, LOW); 
 + delay(s_attack_off);
 +}
 +
 +// ****************** chenillard() ****************** //
 +void chenillard(){  
 +  if (DEBUG) Serial.println("CHENILLARD");
 +  for (int i = 0; i < NUMBER ; i++) {
 +    single_attack(solenoids_pins[LOCATION][i]);
 +    delay(250);
 +  }
 +}
 +  
 +// ****************** SETUP ************************* //
 +void setup() {
 +  randomSeed(analogRead(1));
 +  
 +  Serial.begin(9600);
 +  for (int i = 0; i < NUMBER ; i++) {
 +    pinMode(solenoids_pins[LOCATION][i], OUTPUT);
 +    solenoids_seq[i] = random(13);
 +  }
 +  delay(1000);
 +  chenillard();
 +}
 +
 +// ****************** LOOP ************************* //
 +void loop() {  
 +  currentMillis = millis();
 +  
 +  // start automatic
 +  if (currentMillis - auto_time > auto_interval){
 +    auto_sequence = true;
 +    sequence_mode = 1;//random(2);
 +    auto_time = currentMillis;
 +    seq_counter_pattern=0;
 +    seq_counter=0;
 +    if (DEBUG) Serial.println("AUTO:ON");
 +  }
 +  
 +   // stop automatic
 +  if (auto_sequence && currentMillis - auto_time > auto_duration){
 +    auto_sequence = false;
 +
 +    if (DEBUG) Serial.println("AUTO:OFF");
 +  }
 +
 +  // getPiezo
 + // if (!auto_sequence) p_state = getPiezo();
 +
 +  // p_interval, counter
 +  if (!auto_sequence && currentMillis - p_time > p_interval ){
 +    p_counter=0;
 +    p_taptempo_total = 0;
 +    p_taptempo_average = 0;
 +    seq_counter=0;
 +    seq_counter_pattern=0;
 +  }
 +  
 +  // single_attack with the piezo
 +  if (p_counter > 0 && p_counter < p_declenchement_seq && p_state) 
 +  {
 +    int pin = solenoids_pins[LOCATION][random(NUMBER)];
 +    if (DEBUG) { 
 +      Serial.print("ATTACK PIN:");
 +      Serial.println(pin);
 +    }
 +    single_attack(pin);
 +  }
 +  
 +  // start rhythms with a "chenillard"
 +  if (p_counter == p_declenchement_seq) 
 +  {
 +    chenillard();
 +    sequence_mode = random(2);
 +  }
 +  
 +  if (p_counter >= p_declenchement_seq || auto_sequence )
 +  {
 +    if (!auto_sequence) seq_tempo = seq_interval * (p_taptempo_average / 1000); // change the tempo with piezo tap tempo
 +    else seq_tempo = seq_interval;
 +    
 +    if (currentMillis - previousMillis > seq_tempo )
 +    { 
 +      if (DEBUG)
 +      { 
 +        Serial.print("SEQ COUNTER :");
 +        Serial.println(seq_counter);
 +      }
 +    
 +      // random attack time on/off every [8-32] steps
 +      if (seq_counter % random_attack_time == 0)
 +      {
 +       random_attack_time = random(8,32);
 +       if (random(100) > 60) { // 40% of random
 +         s_attack_on = random (s_attack_on_min, s_attack_on_max);
 +         s_attack_off = random (s_attack_off_min, s_attack_off_max);
 +       }
 +       else {
 +         s_attack_on = on;
 +         s_attack_on = off;
 +       }
 +       seq_interval = s_attack_on + s_attack_off; // update sequence interval
 +      }
 +          
 +      // SEQUENCE MODE 0 (random)
 +      if (sequence_mode == 0) 
 +      {
 +        // random sequences every [24-32] steps
 +        if (seq_counter % random_seq == 0)
 +        {
 +         random_seq = random(24,32);
 +         for (int i = random(2); i < random(4,6) ; i++) 
 +         {
 +           solenoids_seq[i] = random(14);
 +         }
 +        }
 +    
 +        // ON : sequences for each pins
 +        for (int i = 0; i <  NUMBER ; i++) {
 +          digitalWrite(solenoids_pins[LOCATION][i], seq[solenoids_seq[i]][seq_counter % 4]); 
 +        }    
 +        delay(s_attack_on);
 +      }
 +    
 +      // SEQUENCE MODE 1 (less random, more human)
 +      if (sequence_mode == 1)
 +      {
 +        // random patterns every [24-32] steps
 +        if (seq_counter % random_seq == 0)
 +        {
 +         random_seq = random(32,64);
 +         for (int i = random(2); i < random(4,6) ; i++) 
 +         {
 +           int choice = random(3);
 +           if (choice == 0)  solenoids_seq[i] = random(19);
 +           else if (choice == 1) solenoids_seq[i] = random(19,36);
 +         }
 +        }
 +        
 +        // ON : sequences for each pins
 +        for (int i = 0; i <  NUMBER ; i++) 
 +        {
 +          digitalWrite(solenoids_pins[LOCATION][i], seq[patterns[solenoids_seq[i]][seq_counter_pattern % 4]][seq_counter % 4]);
 +          if (DEBUG) 
 +          {
 +           Serial.println ("=========="); 
 +           Serial.print ("INDEX"); 
 +           Serial.print (i); 
 +           Serial.print (" - SOLENOID : "); 
 +           Serial.print (solenoids_pins[LOCATION][i]); 
 +           Serial.print (" - PATTERN :"); 
 +           Serial.print (solenoids_seq[i]); 
 +           Serial.print (" - SEQ : "); 
 +           Serial.print (patterns[solenoids_seq[i]][seq_counter_pattern % 4]); 
 +           Serial.print (" - DIGITAL WRITE: "); 
 +           Serial.println (seq[patterns[solenoids_seq[i]][seq_counter_pattern % 4]][seq_counter % 4]); 
 +          }
 +          
 +          if (seq_counter % 4 == 0)
 +          { 
 +            seq_counter_pattern++;
 +          }
 +        }    
 +        delay(s_attack_on); 
 +      }
 +    
 +      // OFF : all off
 +      for (int i = 0; i <  NUMBER ; i++) {
 +        digitalWrite(solenoids_pins[LOCATION][i], 0); 
 +      }
 +      delay(s_attack_off);  
 +    
 +      seq_counter++;
 +      
 +      previousMillis = currentMillis;
 +    } // end seq_tempo
 +  } // end start rythms
 +  
 +  delay(5);  // delay to avoid overloading the serial port buffer
 } }
 </code> </code>
 ++++ ++++
/home/resonancg/www/wiki/data/attic/projets/chimeres-orchestra/code-arduino/accueil.1427722977.txt.gz · Dernière modification: 2015/03/30 15:42 de resonance