LST le Star Trk

Étoile de mer intergalactique, sans doute

Messages entrants dans le module :

commande des LED :

/LTS/LED <led nb> <0 ou 1> led nb de 0 à 4, 255 commande toutes les leds

commande du voyant :

/LTS/VOY <0 à 255>

réglages de la molette :

/LTS/MPG/S2 <set point 0 – 57600> // place l'encodeur à une valeur donnée
/LTS/MPG/S3 <set point 0 – 65535> // place le potentiomètre virtuel à une valeur donnée
/LTS/MPG/M3 <minimum> <maximum> // fixe les butées mini et maxi du potentiomètre virtuel 0 – 65535

Messages sortant du module :

Bouton sur la boîte :

/LTS/BAS <inter> <BP>

Nunchuck :

/LTS/NCK <BP rond><BP carré><joystickX><joystickY><accelX><accelY><accelZ>

Joystick beige :

/LTS/JOY <joyX><joyY><BP1><BP2><BPsur manche>

speedKing :

/LTS/GP1 <haut><bas><gauche><droite><gachette>

joystickNoir :

/LTS/GP2 <haut><bas><gauche><droite><BP rouge>

NesPad :

/LTS/NES <haut><bas><gauche><droite><select><start><B><A>

Encodeur rotatif :

/LTS/MPG <vitesse angulaire> <position sur 40 tours (0-57600)><position potentiomètre à
butées><accélération angulaire> 

Si la roue est en mouvement, envoi de sa position relative toutes les 50 ms

Récepteur RFID :

/LTS/TAG <MSB> <Byte> <Byte> <LSB>

si plusieurs tags présents envoie successivement chaque tag

pédale d'expression

Ajout mai 2024

/LTS/PED [0-255]

/LTS/JAK [BP1] [BP2] [BP3] [BP4]

Active sensing :

/LTS/sens <int> 

envoie une valeur qui s’incrémente toutes les secondes. + l’état des boutons et des potentiometres à tour de rôle toutes les secondes

raccordements MAX6956

port HMI
12 Joystick Taïwanais (noir avec gros BP jaune)
13 Joystick Taïwanais
14 joystick Taïwanais
15 joystick Taïwanais
16 joystick Taïwanais
17 Speed King
18 Speed King
19 Speed King
20 Speed King
21 Speed King
22 3 BP du joystick beige
23 3 BP du joystick beige
24 3 BP du Joystick beige
26 BP face avant
26 BP face avant
27 LED 0
28 LED 1
29 Led 2
30 Led 3
31 Led 4

sortie D3 : LED rouge gros voyant PWM

ajout pédale d'expression (mai 2024)

  • installation d'une prise XLR5 sur la face arrière
  • fiche male raccordée à une pédale d'expression contenant un minipro
  • sortie cable I2C par trou jack exp
  • 4 autres jacks modifiés pour entrées 4 BP
  • fonctionnement en 5 volt (prise XLR5 toujours en 9V)
  • adresse pour la pédale : 0x0C (differente de pedale GTC et gyropédale GTC)
  • ajout d'une entrée midi impossible (RAM trop petite)

pour rappel : pédales GTC = 0x0A et 0x0B ==> compatibles

0x1 carte mère = OK

max6956(0x46)=OK

nunchuck 0x52 = OK

lecteur RFID 0x5 = OK

molette 0x4 = OK

adresse pour la pédale : 0x0C

microprogramme

pedal

// nano mini pro 16MHz 328P "n 5V, reglé sur 5V dans l'IDE
//sur bus @12 0xC

#include <Wire.h>
#include <Bounce2.h>
#define BP0 4
#define BP1 5
#define BP2 6
#define BP3 7
// Instantiate a Bounce object with a 15 millisecond debounce time
Bounce bouncer0 = Bounce( BP0, 15 );
Bounce bouncer1 = Bounce( BP1 , 15 );
Bounce bouncer2 = Bounce( BP2, 15 );
Bounce bouncer3 = Bounce( BP3 , 15 );

uint8_t dataToSend[] = {0, 0, 0}; // analog ped value, BP's(bitwrite), dummy

int tempVal = 0;
long meanVal = 0;
long counter = 0;



void setup() {
  pinMode(BP0, INPUT);
  pinMode(BP1, INPUT);
  pinMode(BP2, INPUT);
  pinMode(BP3, INPUT);
  digitalWrite(BP0, HIGH);
  digitalWrite(BP1, HIGH);
  digitalWrite(BP2, HIGH);
  digitalWrite(BP3, HIGH);
  //Serial.begin (57600);
  Wire.begin(0xC);                // join i2c bus with address #C (12)
  Wire.onRequest(requestEvent); // register event
}

void loop() {
  // Update the debouncer
  bouncer0.update ( );
  bouncer1.update ( );
  bouncer2.update ( );
  bouncer3.update ( );
  // Get the update value
  bitWrite(dataToSend[1], 0, 1 - (1 & bouncer0.read()) );
  bitWrite(dataToSend[1], 1, 1 - (1 & bouncer1.read()) );
  bitWrite(dataToSend[1], 2, 1 - (1 & bouncer2.read()) );
  bitWrite(dataToSend[1], 3, 1 - (1 & bouncer3.read()) );
  //if(counter < 200000){
  //  meanVal += analogRead(A0);
  //  counter++;
  //}
  delay(1);
}

void requestEvent()
{
  //tempVal = meanVal/counter;
  tempVal = map(analogRead(A0), 0, 1024, 0, 255);
  tempVal = constrain(tempVal, 0, 255);
  dataToSend[0] = uint8_t(tempVal);
  Wire.write(dataToSend, 2);
}

main

//uno on board
//pour 1.8.5 max
//réseau I2C : Master@0x1,RFID@0x3 MPG@0x4, MAX6956@0x46, Nunchuck@0x52, pedale expression@0xC
//ajout pedale expression en I2C
#define pedal
//#define midiInput MIDI NE FONCTIONNE PAS CAR MEMOIRE RAM TROP CHARGEE
// ajout RFID reader en I2C
  //detecteur RFID sur OSC
  //lecteur RFID sur bus I2C
  //Minitel sur port série NON
// mise à jour pour 1.0.1
// ajouter envoi de BP avec active sens
// 3 entrées en reserve et 4 LED sur MAX6956
// 2 port manette db9
// 1 port gamepad
// 1 nunchuck

#include <Wire.h>
#include <SPI.h>
#include <Ethernet.h>
#include <ArdOSC.h>
#include <NESpad.h>
#define reset 9 // reset du wiznet, active low

#ifdef midiInput
#define serial_activate 8 // mise en service du midi in
#include <MIDI.h>
MIDI_CREATE_DEFAULT_INSTANCE();
unsigned int noteStateCh[128]; // 16ch x 128 notes, un bit par note ==> 256 octets
long int timeNoNoteSafety;
int NoteStatesPrev;
//byte isNRPN = 0;
//byte NRPN[] = {0, 0, 0, 0, 0};
//long int timeNRPN = 0;
//byte NRPNsending = 0;

char oscAdrMinCC[] = "/LTS/Min/CC";
//char oscAdrMinNRPN[] = "/LTS/Min/NRPN";
char oscAdrMinNon[] = "/LTS/Min/Non";
char oscAdrMinNof[] = "/LTS/Min/Nof";
char oscAdrMinPC[] = "/LTS/Min/PC";
char oscAdrMinATc[] = "/LTS/Min/ATc";
//char oscAdrMinATp[] = "/LTS/Min/ATp";
char oscAdrMinPB[] = "/LTS/Min/PB";
char oscAdrNoNoteSafety[] = "/LTS/noNoteSafety"; //<ch0 à 7> <ch8 à 15> deux bytes, chaque bit correspond à l'état d'un cana#endif
#endif
// put your own strobe(2)/clock(4)/data(7) pin numbers here -- see the pinout in readme.txt
/*
NES Joystick connector pinout:

                  (1) GND    <- Brown
White -> +5V (5)  (2) CLOCK  <- Red
          NC (6)  (3) STROBE <- Orange
          NC (7)  (4) DATA   <- Yellow
*/          
NESpad nintendo = NESpad(2,4,7);
byte padState = 0;
byte padState_prev = 0;
#include <Statistic.h>
Statistic joyX; 
Statistic joyY; 
Statistic AxisX; 
Statistic AxisY; 
Statistic AxisZ; 

int z_button1 = 1;
int c_button1 = 1;
int joy_x_axis1 = 127;
int joy_y_axis1 = 127;
int accel_x_axis1 = 0;
int accel_y_axis1 = 0;
int accel_z_axis1 = 0;

int JoyX = 0;
int JoyY = 0;
int JoyX_prev = 0;
int JoyY_prev = 0;
long timeX = 0;

//////////////////////////////
unsigned long time_roue = 0;
long int  data1 = 0; // incrementale
long int  data1_prev = 0; // pour le calcul de l'acceleration angulaire
unsigned int  data2 = 0; // absolue
unsigned int  data2_prev = 0; // pour détecter un changement de valeur
long int  data3 = 0; // pot 360 points avec butées (0 et maxData3)
long int  data3_prev = 0; // pour détecter un changement de valeur
unsigned int minData3 = 0; //par defaut reglé à 0 points
unsigned int maxData3 = 600; //par defaut reglé à 600 points
long int data4 = 0;
byte jetonMPG = 0;
//
long int timeRFID = 0;
byte buf[] = {0,0,0,0,0,0,0};
byte buf_prev[] = {0,0,0,0,0,0,0};
//
uint8_t outbuf1[6];     // array to store Nunchuck output
int cnt = 0;

int AsensNb  = 0;
unsigned long time_send_AS = 0;
unsigned long time_send_NUN = 0;
byte c_button1_prev = 0;
byte z_button1_prev = 0;
int  accel_x_axis1_prev = 0;
int  accel_y_axis1_prev = 0;
int  accel_z_axis1_prev = 0;
int joy_x_axis1_prev = 0;
int joy_y_axis1_prev = 0;
uint8_t Xcenter = 121;
uint8_t Ycenter = 126;

byte myMac[] = { 0x10, 0x35, 0x11, 0x11, 0x88, 0x88 };
byte myIp[]  = { 192, 168, 0, 188};
byte destIp[] =  { 192, 168, 0, 255 };
int  destPort    = 6666;
int  serverPort  = 1510;
OSCServer server;
OSCMessage *rcvMes;

OSCClient client;
char oscAdrLED[]  = "/LTS/LED";
char oscAdrVOY[]  = "/LTS/VOY";
char oscAdrAsens[]  = "/LTS/sens";
char oscAdrNunchuck[]  = "/LTS/NCK";
char oscAdrNesPad[] = "/LTS/NES"; //entrée
char oscAdrGamePad1[] = "/LTS/GP1"; //entrée
char oscAdrGamePad2[] = "/LTS/GP2"; //entrée
char oscAdrJoystick[] = "/LTS/JOY"; //joystick + 3BP
char oscAdrBase[] = "/LTS/BAS"; //les 2 BP sur la base
char oscAdrRFID[]  = "/LTS/TAG"; //numero du TAG
char oscAdrMPG[]    = "/LTS/MPG"; //encodeur rotatif (Manual Pulse Generator)
char oscAdrMPGS2[]   = "/LTS/MPG/S2"; 
char oscAdrMPGS3[]   = "/LTS/MPG/S3"; 
char oscAdrMPGM3[]   = "/LTS/MPG/M3"; 
char oscAdrSetup[]   = "/LTS/SETUP";//indique les etats des satelites au demarrage
char oscAdrPedal[]   = "/LTS/PED"; //volume 0 à 255 (les 4 boutons latéraux sont traités comme des BP avec oscAdrDin[]
char oscAdrDin[]  = "/LTS/JAK"; //entrée jack
//ATU/////////////////////////
byte ATU = 0; // innibition des sorties
long veille_ATU = 0; // mesure du temps entre 2 reception de /ATU
byte send_ANO = 0; // mémorisation de l'envoi du all-note-off
byte send_ANO_ATU = 0; // mémorisation de l'envoi du all-note-off en cas  de ATU = 0
byte ANO_done = 0;
//LED/////////////////////////
byte LedOnOff[]   = {0,0,0,0,0};
////////////////////////////BP state and debouncer
byte A = 0;
byte B = 0;
byte C = 0;
byte BP_state[]                   = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
byte BP_laststate[]               = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
byte statebit[]                   = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
byte BP_prev[]                    = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
unsigned long lastDebounceTime[]  = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
byte debounceDelay = 20;
long present_time = millis();
unsigned long time_send = 0;
byte input_to_send = 0;


//unsigned long IDnum = 0;
byte sendZero = 1; 

////////////////////////////
//pedal stuff
byte pedalPresent = 0;
uint8_t pedalVal = 0;
uint8_t prevPedalVal = 0;
uint8_t BPSideVal = 0;
long timeSendPedal = millis();
long timeCheck = 0;
////////////////////////////

void setup ()
{
  #ifdef midiInput
  pinMode(serial_activate, OUTPUT);  
  digitalWrite(serial_activate,LOW);//désactive l'entrée série venant du minitel
  MIDI.setHandleNoteOn(handleNoteOn);  // Put only the name of the function
  MIDI.setHandleNoteOff(handleNoteOff);
  MIDI.setHandleControlChange(handleControlchange);
  MIDI.setHandlePitchBend(handlePitchBend);
  MIDI.setHandleProgramChange(programChange);
  MIDI.setHandleAfterTouchChannel(afterTouchChannel);
  //MIDI.setHandleAfterTouchPoly(afterTouchPoly);
  #endif

  pinMode(3,OUTPUT); //LED rouge en PWM
  analogWrite(3,0);
  //Serial.begin (38400);//debugg
  Wire.begin (0x01);        // join i2c bus with address//deja initialisé par nfc
  nunchuck_init (); // send the initilization handshake
  max6956_init (0x46);
    //séquence de reset du wiznet
  pinMode(reset, OUTPUT);
  delay(1000); //temps pour que l'esclave I2C demarre
  digitalWrite(reset, HIGH);
  delay(100);
  digitalWrite(reset, LOW);
  delay(100);
  digitalWrite(reset, HIGH);
  delay(300); 
  Ethernet.begin(myMac ,myIp);  
  server.begin(serverPort);
  delay(2000);
  OSCMessage mes;
    mes.setAddress(destIp, destPort);
    mes.beginMessage(oscAdrSetup);
    mes.addArgString("LTS loading");
    client.send(&mes);
    mes.flush();
    //set callback functions & oscaddress   
  server.addCallback(oscAdrLED,&funcLED);
  server.addCallback(oscAdrVOY,&funcVOY);
  server.addCallback("/ATU",&funcATU); 
  //server.addCallback("/ANO",&funcANO); 
  server.addCallback(oscAdrMPGS2,&funcS2MPG); 
  server.addCallback(oscAdrMPGS3,&funcS3MPG); 
  server.addCallback(oscAdrMPGM3,&funcMAX3MPG); 
  for (byte i = 0;i<255;i++) {
    analogWrite(3,i);
    delay(30);
  }
  LedOnOff[0]   = 1;
  LedOnOff[1]   = 1;
  LedOnOff[2]   = 1;
  LedOnOff[3]   = 1;
  LedOnOff[4]   = 1;
  LED_to_MAX6956();

  //Statistic
  joyX.clear();
  joyY.clear(); 
  AxisX.clear();
  AxisY.clear();
  AxisZ.clear();
  delay(200);
  LedOnOff[0]   = 0;
  LedOnOff[1]   = 0;
  LedOnOff[2]   = 0;
  LedOnOff[3]   = 0;
  LedOnOff[4]   = 0;
  LED_to_MAX6956();
   analogWrite(3,0);
   veille_ATU = millis();
 // readNunchuck_setup();
 // Xcenter = outbuf1[0];
 // Ycenter = outbuf1[1];
 //Serial.write("setup done");

   //check for pedal
  Wire.requestFrom(0xC, 2); // request 3 byte
  while (Wire.available() )
  {
    byte tempPedalVal = Wire.read(); //dummy
    pedalPresent = 1;
  }
  delay(5);
  if (pedalPresent == 1) {
    OSCMessage mes;
    mes.setAddress(destIp, destPort);
    mes.beginMessage(oscAdrSetup);
    mes.addArgString("Pedal connected");
    client.send(&mes);
    mes.flush();
  }
  else {
    //Serial.println("WARNING Pedal not connected");
    OSCMessage mes;
    mes.setAddress(destIp, destPort);
    mes.beginMessage(oscAdrSetup);
    mes.addArgString("WARNING Pedal not connected");
    client.send(&mes);
    mes.flush();
  }
#ifdef midiInput
  // Initiate MIDI communications, listen to all channels
  MIDI.begin(MIDI_CHANNEL_OMNI);
  digitalWrite(serial_activate, HIGH);//activation du midi in
#endif
}

I2C

void max6956_init (byte add)
{
  Wire.beginTransmission (add); // transmit to inputs
  Wire.write (0x02);         // sends register address (global current)
  Wire.write (0x01);         // sends set global current to 10x1.5mA = 15mA.  
  Wire.endTransmission ();   // stop transmitting

  Wire.beginTransmission (add); // transmit to inputs
  Wire.write (0x04);         // sends register address (config)
  Wire.write (0x01);         // sends set transition detect = 0 /global current set = 1 / normal op.
  Wire.endTransmission ();   // stop transmitting

  Wire.beginTransmission (add); // transmit to inputs
  Wire.write (0x09);         // sends register address (port config)
  Wire.write ((byte)0x00);
  Wire.write ((byte)0x00); 
  Wire.write (0xFF);         // sends set port 12-31 inputs with PullUp R
  Wire.write (0xFF);
  Wire.write (0xFF);
  Wire.write (0x3F);              // port 27 = LED0...port 31 = LED4
  Wire.write ((byte)0x00);              // set last 5 ports as led drivers   
  Wire.endTransmission ();   // stop transmitting
}

void nunchuck_init ()
{

  Wire.beginTransmission (0x52);    // transmit to device 0x52
  Wire.write (0x40);        // sends memory address
  Wire.write ((byte)0x00);      // sends sent a zero.  
  Wire.endTransmission ();  // stop transmitting
}

void send_zero ()
{
  Wire.beginTransmission (0x52);    // transmit to device 0x52
  Wire.write ((byte)0x00);      // sends one byte
  Wire.endTransmission ();  // stop transmitting
}

void readNunchuck() {
    Wire.requestFrom (0x52, 6); // request data from nunchuck
  while (Wire.available ())
    {
      outbuf1[cnt] = nunchuk_decode_byte (Wire.read ());    // receive byte as an integer
      //digitalWrite (ledPin, HIGH);    // sets the LED on
      cnt++;
    }

  // If we received the 6 bytes, then go print them
  if (cnt >= 5)
    {
      print ();
    }

  cnt = 0;
  send_zero (); // send the request for next bytes
  //delay (5);  
}

void readNunchuck_setup() {
    Wire.requestFrom (0x52, 6); // request data from nunchuck
  while (Wire.available ())
    {
      outbuf1[cnt] = nunchuk_decode_byte (Wire.read ());    // receive byte as an integer
      cnt++;
    }


  cnt = 0;
  send_zero (); // send the request for next bytes
  //delay (5);  
}

void Get_inputs(byte add) { //les 15 entrées TOR
  {
  Wire.beginTransmission (add); // transmit to device 
  Wire.write (0x4C); //8 ports 12-19
  Wire.endTransmission ();   // stop transmitting
  Wire.requestFrom((byte)add, (byte)1); // request 1 byte
  while (Wire.available() )
    {
       A = Wire.read();
    }
A = ~A; // traitement (BP cablés en logique négative)

  Wire.beginTransmission (add); // transmit to device 
  Wire.write (0x54); //8 ports 20-27
  Wire.endTransmission ();   // stop transmitting
  Wire.requestFrom((byte)add, (byte)1); // request 1 byte
  while (Wire.available() )
    {
       B = Wire.read();
    }
B = ~B; // traitement (BP cablés en logique négative)


 for(byte i = 0; i<8; i++)
{
  statebit[i]   = bitRead(A, i);
  statebit[i+8] = bitRead(B, i);
}
 for(byte i = 0; i<16; i++)
  if(statebit[i] != BP_prev[i]) 
  {
    lastDebounceTime[i] = millis();
  }

  else{}
}
present_time = millis();
for(byte i = 0; i<16; i++)
 {  
  if ((present_time - lastDebounceTime[i]) > debounceDelay)  { 
      BP_state[i] = statebit[i]; 
     }
   else{}  
 }

 //le port gamepad 1

   if (BP_laststate[0] != BP_state[0] ||
       BP_laststate[1] != BP_state[1] ||
       BP_laststate[2] != BP_state[2] ||
       BP_laststate[3] != BP_state[3] ||
       BP_laststate[4] != BP_state[4]
      ) {
    GP1toOSC();
    for(byte i = 0; i < 5; i++) {
    BP_laststate[i] = BP_state[i]; 
     }
      }
   else{}  

  for(byte i = 0; i < 5; i++) { 
   BP_prev[i] = statebit[i];    
  }

 //le port gamepad 2

   if (BP_laststate[5] != BP_state[5] ||
       BP_laststate[6] != BP_state[6] ||
       BP_laststate[7] != BP_state[7] ||
       BP_laststate[8] != BP_state[8] ||
       BP_laststate[9] != BP_state[9]
      ) {
    GP2toOSC();
    for(byte i = 5; i < 10; i++) {
    BP_laststate[i] = BP_state[i]; 
     }
      }
   else{}  

  for(byte i = 5; i < 10; i++) { 
   BP_prev[i] = statebit[i];    
  }

//le joystick...
   if (BP_laststate[10] != BP_state[10] ||
       BP_laststate[11] != BP_state[11] ||
       BP_laststate[12] != BP_state[12] 
       ) {
       JOYtoOSC(); 
     for(byte i = 10; i < 13; i++) {
     BP_laststate[i] = BP_state[i]; 
     }       
      }
   else{} 

  for(byte i = 10; i < 13; i++) { 
   BP_prev[i] = statebit[i];    
  }


 if ((BP_laststate[13] != BP_state[13]) 
   || (BP_laststate[14] != BP_state[14]))
   {
   BaseToOSC();
   BP_laststate[13] = BP_state[13];
   BP_laststate[14] = BP_state[14];
   }
 else{}   
   BP_prev[13] = statebit[13]; 
   BP_prev[14] = statebit[14];

   //les 4 BP de la pédale d'expression
   if(pedalPresent == 1){
   if ((BP_laststate[16] != BP_state[16]) 
   || (BP_laststate[17] != BP_state[17])
   || (BP_laststate[18] != BP_state[18])
   || (BP_laststate[19] != BP_state[19]))
   {
   jackBPToOSC();
   BP_laststate[16] = BP_state[16];
   BP_laststate[17] = BP_state[17];
   BP_laststate[18] = BP_state[18];
   BP_laststate[19] = BP_state[19];
   }
 else{} 

   BP_prev[16] = statebit[16]; 
   BP_prev[17] = statebit[17]; 
   BP_prev[18] = statebit[18]; 
   BP_prev[19] = statebit[19]; 
}

  }

void LED_to_MAX6956()
{
    Wire.beginTransmission (0x46);                  // transmit to outputs
    Wire.write (0x3B);                          // output P27
    Wire.write (LedOnOff[0]);                       // P27 led 0
    Wire.write (LedOnOff[1]);                       // P28 led 1
    Wire.write (LedOnOff[2]);                       // P29 led 2  
    Wire.write (LedOnOff[3]);                       // P30 led 3 
    Wire.write (LedOnOff[4]);                       // P31 led 4 
    Wire.endTransmission () ;                       // stop transmitting
}

callbacks

// callback fonctions messages OSC entrants
void funcATU(OSCMessage *_mescurrent){
  ATU = _mescurrent->getArgInt32(0);
  veille_ATU = millis();
  //send_ANO_ATU = 0;
}

void funcANO(OSCMessage *_mescurrent){
  send_ANO = 0;
}

void funcLED(OSCMessage *_mescurrent){ // les voyants au dessus des BP
 byte lednb =    (long int)_mescurrent->getArgInt32(0);
 byte ledstate = (long int)_mescurrent->getArgInt32(1);

     if(lednb < 5)
     {
       if(ledstate == 1)
        {
          LedOnOff[lednb] = 1;
        }
       else
        {
          LedOnOff[lednb] = 0;
        }
     }
     else if (lednb == 255)//toutes les LED
     {
       for(byte n = 0; n < 5; n++)
       {
         LedOnOff[n] = ledstate; 
       }
     }
     else{}
     LED_to_MAX6956(); 
}

void funcVOY(OSCMessage *_mescurrent){ // le voyant du dessus
 byte ledIntensity =    (long int)_mescurrent->getArgInt32(0);
 analogWrite(3,ledIntensity);

}


///////////////////////////////////////////////////
void funcS2MPG(OSCMessage *_mescurrent) { // 
   unsigned int newValueMPG = (long int)_mescurrent->getArgInt32(0);
   if(newValueMPG >= 60000) {
     newValueMPG = 0;
   }
   data2 = newValueMPG;
   jetonMPG = 0;
}

void funcS3MPG(OSCMessage *_mescurrent) { // 
   unsigned int newValueMPG = (long int)_mescurrent->getArgInt32(0);

   if(newValueMPG >= maxData3) {
     data3 = maxData3;

   }
   else if(newValueMPG <= minData3) {
     data3 = minData3;
   } 
  else {
   data3 = newValueMPG;
  }
  jetonMPG = 0;
}

void funcMAX3MPG(OSCMessage *_mescurrent) { // 
   unsigned int newValueMPGmini = (long int)_mescurrent->getArgInt32(0);
   unsigned int newValueMPGmaxi = (long int)_mescurrent->getArgInt32(1);
   if(newValueMPGmini >= 65534) {
     minData3 = 65534;
   }
   else if(newValueMPGmini <= 0) {
     minData3 = 0;
   }
   else {
     minData3 = newValueMPGmini;
   }
   if(newValueMPGmaxi >= 65535) {
     maxData3 = 65535;
   }
   else if(newValueMPGmaxi <= 1) {
     maxData3 = 1;
   }
   else {
     maxData3 = newValueMPGmaxi;
   }
}

///////////////////////////////////////////////////

midi to OSC (not active)

// This function will be automatically called when a NoteOn is received.
// It must be a void-returning function with the correct parameters,
// see documentation here:
// http://arduinomidilib.fortyseveneffects.com/a00022.html

#ifdef midiInput

void handleNoteOn(byte channel, byte pitch, byte velocity)
{
  send3integers(oscAdrMinNon, channel, pitch, velocity);
  bitWrite(noteStateCh[pitch], channel - 1, 1);
}

void handleNoteOff(byte channel, byte pitch, byte velocity)
{
  // Note that NoteOn messages with 0 velocity are interpreted as NoteOffs.
  send3integers(oscAdrMinNof, channel, pitch, velocity);
  bitWrite(noteStateCh[pitch], channel - 1, 0);
}

void handlePitchBend(byte channel, int pitchBend)
{
  send2integers(oscAdrMinPB, channel, pitchBend);
}

void handleControlchange(byte channel, byte CCnum, byte value)
{
 /* if (CCnum == 99) {
    isNRPN = 1;
    NRPN[0] = channel;
    NRPN[1] = value;
  }
  else if (CCnum == 98) {
    isNRPN = 1;
    NRPN[2] = value;
  }
  else if (CCnum == 6 && isNRPN == 1) {
    NRPN[3] = value;
  }
  else if (CCnum == 38&& isNRPN == 1) {
    NRPN[4] = value;
  send3integers(oscAdrMinNRPN, NRPN[0], NRPN[1] << 7 | NRPN[2], NRPN[3] << 7 | NRPN[4]);
  isNRPN = 0;
  }
  else {*/
    send3integers(oscAdrMinCC, channel, CCnum, value);
  //}
/*
  if (millis() - time > 20) {
  isNRPN = 0;
}
else {}
*/
}

void afterTouchChannel(byte channel,  byte value)
{
  send2integers(oscAdrMinATc, channel, value);
}

void programChange(byte channel,  byte value)
{
  send2integers(oscAdrMinPC, channel, value);
}

/*void afterTouchPoly(byte channel, byte pitch, byte aftertouch)
{
  send3integers(oscAdrMinATp, channel, pitch, aftertouch);
}*/


void send3integers(char* oscAdr, int int1, int int2, int int3) {
  OSCMessage message;
  message.setAddress(destIp, destPort);
  message.beginMessage(oscAdr);
  message.addArgInt32(int1);
  message.addArgInt32(int2);
  message.addArgInt32(int3);
  client.send(&message);
  message.flush();
}

void send2integers(char* oscAdr, byte byte1, byte byte2) {
  OSCMessage message;
  message.setAddress(destIp, destPort);
  message.beginMessage(oscAdr);
  message.addArgInt32(byte1);
  message.addArgInt32(byte2);
  client.send(&message);
  message.flush();
}
#endif


loop

void loop ()
{
#ifdef midiInput

  // Call MIDI.read the fastest you can for real-time performance.
  MIDI.read();

//detection noteOff partout :
  int NoteStates = 0;
  for (byte note = 0; note < 128; note++) {
   NoteStates = NoteStates | noteStateCh[note];
  }
  if (NoteStates != NoteStatesPrev) {
    timeNoNoteSafety = millis();
    NoteStatesPrev = NoteStates;
  }
  if (millis() - timeNoNoteSafety > 100) {
    OSCMessage message;
    message.setAddress(destIp, destPort);
    message.beginMessage(oscAdrNoNoteSafety);
    message.addArgInt32(NoteStates);
    client.send(&message);
    message.flush();
    timeNoNoteSafety = millis();
  }

#endif

  padState = nintendo.buttons();
  if (padState != padState_prev) {
    NEStoOSC();
    padState_prev = padState;
  }

  if (server.availableCheck() > 0) // indispensable pour que l'OSC reçu soit décodé
  {
    //nada
  }

  if (millis() - veille_ATU > 1500) // chien de garde
  {
    if (millis() - veille_ATU > 10000) {
      asm volatile ("  jmp 0");
    }
  }
  else {}

  ActiveSens();
  Get_inputs(0x46);
  if (millis() - time_send_NUN > 20) {
    readNunchuck();
    time_send_NUN = millis();
  }

  JoyX = analogRead(0) >> 2;
  JoyY = analogRead(1) >> 2;
  if ((JoyX != JoyX_prev || JoyY != JoyY_prev) && millis() - timeX > 20) {
    timeX = millis();
    JoyX_prev = JoyX;
    JoyY_prev = JoyY;
    JOYtoOSC();
  }
  if (millis() - timeRFID > 100) {
    timeRFID = millis();
    Get_RFID();
  }

#ifdef pedal
  if (pedalPresent == 1 && millis() - timeCheck > 15) {
    timeCheck = millis();
    Wire.requestFrom(0xC, 3); // request 3 bytes but only 2 will be send ???
    while (Wire.available() )
    {
      pedalVal = Wire.read();
      BPSideVal = Wire.read(); //4BP's
      byte dummy = Wire.read();
      //Serial.println(pedalVal);
    }
    BP_state[16] = bitRead(BPSideVal, 0);
    BP_state[17] = bitRead(BPSideVal, 1);
    BP_state[18] = bitRead(BPSideVal, 2);
    BP_state[19] = bitRead(BPSideVal, 3);
  }
  if (millis() - timeSendPedal > 15 && pedalVal != prevPedalVal)
  {
    sendPedal();
    timeSendPedal = millis();
    prevPedalVal = pedalVal;
  }

#endif //pedal

  sendManualPulseGenerator(); //le plus souvent possible !

}

to OSC

/*
void sendDinsolo(byte inputnumber, long int tmpDin)
{
 //réalisation de la fin de l'adresse OSC : 
  if(inputnumber < 10)
 {
   oscAdrDin[8] = '0'; //0
   oscAdrDin[9]  = inputnumber+0x30; // 0x30 correspond au charactere 0
 }
 else if(inputnumber >= 10)
 {
  oscAdrDin[8] = '1'; 
  oscAdrDin[9] = inputnumber+0x26; // 0x26 + 0xA = 0x30
 }
 else{}
 //envoi du message
 OSCMessage mes;  
 mes.setAddress(destIp,destPort);
 mes.beginMessage(oscAdrDin);
 mes.addArgInt32(tmpDin); 
 client.send(&mes);
 mes.flush(); 
}
*/

void print ()
{
  joyX.add (outbuf1[0]);
  joyY.add (outbuf1[1]);
  AxisX.add(outbuf1[2]);
  AxisY.add(outbuf1[3]);
  AxisZ.add(outbuf1[4]);

  z_button1 = 1;
  c_button1 = 1;

  // byte outbuf[5] contains bits for z and c buttons
  // it also contains the least significant bits for the accelerometer data
  // so we have to check each bit of byte outbuf[5]
  if ((outbuf1[5] >> 0) & 1)
  {
    z_button1 = 0;
  }
  if ((outbuf1[5] >> 1) & 1)
  {
    c_button1 = 0;
  }

  if (joyX.count() > 60 ){
    joy_x_axis1 = 127;
    joy_y_axis1 = 127;
    if(outbuf1[0] < Xcenter) {
       joy_x_axis1 = map(outbuf1[0],(float)joyX.minimum(),Xcenter,0,127);
       joy_x_axis1 = constrain(joy_x_axis1,0,127);
    }
    else if(outbuf1[0] > Xcenter) {
       joy_x_axis1 = map(outbuf1[0],Xcenter,(float)joyX.maximum(),127,255);
       joy_x_axis1 = constrain(joy_x_axis1,127,255);
    }    
    else{}

    if(outbuf1[1] < Ycenter) {
       joy_y_axis1 = map(outbuf1[1],(float)joyY.minimum(),Ycenter,0,127);
       joy_y_axis1 = constrain(joy_y_axis1,0,127);
    }
    else if(outbuf1[1] > Ycenter) {
       joy_y_axis1 = map(outbuf1[1],Ycenter,(float)joyY.maximum(),127,255);
       joy_y_axis1 = constrain(joy_y_axis1,127,255);
    }    
    else{}    

    accel_x_axis1 = AxisX.average();
    accel_y_axis1 = AxisY.average();
    accel_z_axis1 = AxisZ.average();    
    if(accel_x_axis1 != accel_x_axis1_prev || 
       accel_y_axis1 != accel_y_axis1_prev ||
       accel_z_axis1 != accel_z_axis1_prev ||
       z_button1 != z_button1_prev || 
       c_button1 != c_button1_prev ||
       joy_x_axis1 != joy_x_axis1_prev ||
       joy_y_axis1 != joy_y_axis1_prev       
       ) {

      NunchuckToOsc();

      c_button1_prev = c_button1;    
      z_button1_prev = z_button1;
      joy_x_axis1_prev = joy_x_axis1;
      joy_y_axis1_prev = joy_y_axis1;
      accel_x_axis1_prev = accel_x_axis1;   
      accel_y_axis1_prev = accel_y_axis1;  
      accel_z_axis1_prev = accel_z_axis1;        
      AxisX.clear();
      AxisY.clear();
      AxisZ.clear();
    }
  }

}

// Encode data to format that most wiimote drivers except
// only needed if you use one of the regular wiimote drivers
char nunchuk_decode_byte (char x)
{
  x = (x ^ 0x17) + 0x17;
  return x;
}

void ActiveSens() {
  // active sens
  if (millis() - time_send_AS > 1000)
  {
    send_RFID();
    OSCMessage mesAS;  
    mesAS.setAddress(destIp,destPort);
    mesAS.beginMessage(oscAdrAsens);
    //mesAS.addArgInt32(Xcenter); 
    //mesAS.addArgInt32(Ycenter);    
    mesAS.addArgInt32(AsensNb); 
    client.send(&mesAS);
    mesAS.flush();
    time_send_AS = millis(); 
    BaseToOSC();
         if(padState == 0) {
           NEStoOSC();
          }
         if( z_button1   == 0   && 
             c_button1   == 0   &&
             joy_x_axis1 == 127 &&
             joy_y_axis1 == 127       
             ) {
              NunchuckToOsc();
             }
         AsensNb++;

          if (BP_state[0]  ==0 &&
              BP_state[1]  ==0  &&
              BP_state[2]  ==0  &&
              BP_state[3]  ==0  &&
              BP_state[4]  ==0
           ) {
              GP1toOSC();
             }
          if (BP_state[5]  ==0 &&
              BP_state[6]  ==0  &&
              BP_state[7]  ==0  &&
              BP_state[8]  ==0  &&
              BP_state[9]  ==0
           ) {
              GP2toOSC();
             }

          if (BP_state[10]  ==0 &&
              BP_state[11]  ==0  &&
              BP_state[12]  ==0
              ) {
              JOYtoOSC();  
             }       
  }

  else{
  } 
}


void NEStoOSC() {
    OSCMessage mesAS;  
    mesAS.setAddress(destIp,destPort);
    mesAS.beginMessage(oscAdrNesPad);
    mesAS.addArgInt32((byte)bitRead(padState,4)); //up
    mesAS.addArgInt32((byte)bitRead(padState,5)); //dwn
    mesAS.addArgInt32((byte)bitRead(padState,6)); //left
    mesAS.addArgInt32((byte)bitRead(padState,7)); //right

    mesAS.addArgInt32((byte)bitRead(padState,2)); // select
    mesAS.addArgInt32((byte)bitRead(padState,3)); //start

    mesAS.addArgInt32((byte)bitRead(padState,1)); //B
    mesAS.addArgInt32((byte)bitRead(padState,0)); //A

    client.send(&mesAS);
    mesAS.flush();
}

void NunchuckToOsc() {
      OSCMessage mesAS;  
      mesAS.setAddress(destIp,destPort);
      mesAS.beginMessage(oscAdrNunchuck);
      mesAS.addArgInt32(c_button1); 
      mesAS.addArgInt32(z_button1);
      mesAS.addArgInt32(joy_x_axis1);       
      //mesAS.addArgInt32(outbuf1[0]); 
      mesAS.addArgInt32(joy_y_axis1);        
      //mesAS.addArgInt32(outbuf1[1]);   
      mesAS.addArgInt32(accel_x_axis1); 
      mesAS.addArgInt32(accel_y_axis1);  
      mesAS.addArgInt32(accel_z_axis1);    
      client.send(&mesAS);
      mesAS.flush();
}

void GP1toOSC() {
    OSCMessage mesAS;  
    mesAS.setAddress(destIp,destPort);
    mesAS.beginMessage(oscAdrGamePad1);
    mesAS.addArgInt32((byte)BP_state[0]); //up
    mesAS.addArgInt32((byte)BP_state[1]); //dwn
    mesAS.addArgInt32((byte)BP_state[2]); //left
    mesAS.addArgInt32((byte)BP_state[3]); //right
    mesAS.addArgInt32((byte)BP_state[4]); // BP 
    client.send(&mesAS);
    mesAS.flush();
}

void GP2toOSC() {
    OSCMessage mesAS;  
    mesAS.setAddress(destIp,destPort);
    mesAS.beginMessage(oscAdrGamePad2);
    mesAS.addArgInt32((byte)BP_state[5]); //up
    mesAS.addArgInt32((byte)BP_state[6]); //dwn
    mesAS.addArgInt32((byte)BP_state[7]); //left
    mesAS.addArgInt32((byte)BP_state[8]); //right
    mesAS.addArgInt32((byte)BP_state[9]); // BP 
    client.send(&mesAS);
    mesAS.flush();
}

void JOYtoOSC() {
    OSCMessage mesAS;  
    mesAS.setAddress(destIp,destPort);
    mesAS.beginMessage(oscAdrJoystick);
    mesAS.addArgInt32((int)JoyX);          //up
    mesAS.addArgInt32((int)JoyY);          //dwn
    mesAS.addArgInt32((byte)BP_state[10]); //BP
    mesAS.addArgInt32((byte)BP_state[11]); //BP
    mesAS.addArgInt32((byte)BP_state[12]); //BP 
    client.send(&mesAS);
    mesAS.flush();  
}

void BaseToOSC() {
    OSCMessage mesAS;  
    mesAS.setAddress(destIp,destPort);
    mesAS.beginMessage(oscAdrBase);
    mesAS.addArgInt32((byte)BP_state[13]); //
    mesAS.addArgInt32((byte)BP_state[14]); //
    client.send(&mesAS);
    mesAS.flush();
}

void Get_RFID() {
Wire.requestFrom(0x5, 7);    // request 7 byte from slave device #4
  while(Wire.available())    // slave may send less than requested
    { 
      buf[0] = Wire.read ();// receive byte
      buf[1] = Wire.read ();// receive byte
      buf[2] = Wire.read ();// receive byte
      buf[3] = Wire.read ();// receive byte
      buf[4] = Wire.read ();// receive byte
      buf[5] = Wire.read ();// receive byte
      buf[6] = Wire.read ();// receive byte       
    }

    if(buf[0] != buf_prev[0] 
    || buf[1] != buf_prev[1] 
    || buf[2] != buf_prev[2] 
    || buf[3] != buf_prev[3]
    || buf[4] != buf_prev[4]
    || buf[5] != buf_prev[5]
    || buf[6] != buf_prev[6]    
    ) {
      buf_prev[0] = buf[0];
      buf_prev[1] = buf[1];
      buf_prev[2] = buf[2];
      buf_prev[3] = buf[3];
      buf_prev[4] = buf[4];
      buf_prev[5] = buf[5];
      buf_prev[6] = buf[6];      
      send_RFID();
    }

}

void send_RFID() {
 OSCMessage mes;  
 mes.setAddress(destIp,destPort);
 mes.beginMessage(oscAdrRFID);
 mes.addArgInt32(buf[0]); //MSB
 mes.addArgInt32(buf[1]);
 mes.addArgInt32(buf[2]);
 mes.addArgInt32(buf[3]);
 mes.addArgInt32(buf[4]);
 mes.addArgInt32(buf[5]); 
 mes.addArgInt32(buf[6]); //LSB
 client.send(&mes);
 mes.flush(); 
}

void sendManualPulseGenerator() {
  Wire.requestFrom(0x4, 1);    // request 1 byte from slave device #4
  char LSB;
  while(Wire.available())    // slave may send less than requested
    { 
    LSB = Wire.read ();// receive byte
    //BP_MPG = ~Wire.read ();// receive byte
    } 
    data1 += (char)LSB; // increments
    data2 += (char)LSB; // absolue 600 tours
    //data2 doit repasser à 0 sur un multiple de tours complets...
     if(data2 >= 62517) { //on est entrain de passer par le 0
      //data2 = 59999 - (65535 - data2);
      data2 = data2 - 5536;
    }
    else if(data2 >= 60000) { //on a fait plus de 100 tours !
      data2 = data2 - 60000;
    }
    else{}

    data3 += (char)LSB; // pot xxx points avec butée basse et haute
    if(data3 <= minData3) {
     data3 = minData3;
    }
    if(data3 >= maxData3) {
     data3 = maxData3;
    }


  long int currenttime = millis();
  if(currenttime - time_roue > 70 && (data1 != 0 || data2 != data2_prev || data3 != data3_prev || data4 != 0)) {
  time_roue = currenttime; 
  data4 = data1 - data1_prev; // cacul de l'acceleration angulaire
  OSCMessage messageMPG;   
  messageMPG.setAddress(destIp,destPort);
  messageMPG.beginMessage(oscAdrMPG);
  messageMPG.addArgInt32(data1); 
  messageMPG.addArgInt32(data2);   
  messageMPG.addArgInt32(data3);  
  messageMPG.addArgInt32(data4);  
  client.send(&messageMPG);
  data1_prev = data1;
  data1 = 0;
  data2_prev = data2;
  data3_prev = data3;  
  jetonMPG = 0;
 }
  else if(currenttime - time_roue > 70 && data1 == 0 && jetonMPG == 0)
  {
  time_roue = currenttime; 
  data4 = data1 - data1_prev; // calcul de l'acceleration angulaire
  OSCMessage messageMPG;   
  messageMPG.setAddress(destIp,destPort);
  messageMPG.beginMessage(oscAdrMPG);
  messageMPG.addArgInt32(data1);
  messageMPG.addArgInt32(data2);   
  messageMPG.addArgInt32(data3);  
  messageMPG.addArgInt32(data4);  
  client.send(&messageMPG);
  messageMPG.flush();
  jetonMPG = 1;
 }  

  else{}
}


void sendPedal() {
  OSCMessage messagePedal;
  messagePedal.setAddress(destIp, destPort);
  messagePedal.beginMessage(oscAdrPedal);
  messagePedal.addArgInt32((uint8_t)pedalVal);
  client.send(&messagePedal);
  messagePedal.flush();
}

void jackBPToOSC() {
    OSCMessage mesAS;  
    mesAS.setAddress(destIp,destPort);
    mesAS.beginMessage(oscAdrDin);
    mesAS.addArgInt32((byte)BP_state[16]); //
    mesAS.addArgInt32((byte)BP_state[17]); //
    mesAS.addArgInt32((byte)BP_state[18]); //
    mesAS.addArgInt32((byte)BP_state[19]); //
    client.send(&mesAS);
    mesAS.flush();
}
//*******************************************************