Je suis débutant avec Arduino, pour un projet de domotique j'aimerais piloter les port logique d'une carte mega 2560 (pour piloter un moteur) depuis un PC ainsi que récupérer les valeurs de capteurs analogiques branchés sur les ports analogique de la carte depuis un PC linux (Lina 13.04) via USB en code C mais je ne sais pas trop comment aborder la communication USB (Arduino est nouveau pour moi)
La carte Arduino depuis le PC est vue comme un port série identifié sous Linux comme /dev/ttyUSB0 ou approchant. C'est le nom qui apparaît dans l'IDE arduino. Sinon tu ouvres une console juste après avoir branché la carte arduino et tu fais un dmesg |tail et tu devrais voir quelque chose comme ça:
[12088.676111] usb 4-2: new full-speed USB device number 10 using ohci_hcd
[12088.860510] ftdi_sio 4-2:1.0: FTDI USB Serial Device converter detected
[12088.860588] usb 4-2: Detected FT232RL
[12088.860594] usb 4-2: Number of endpoints 2
[12088.860600] usb 4-2: Endpoint 1 MaxPacketSize 64
[12088.860606] usb 4-2: Endpoint 2 MaxPacketSize 64
[12088.860611] usb 4-2: Setting MaxPacketSize 64
[12088.864628] usb 4-2: FTDI USB Serial Device converter now attached to ttyUSB0
Pour communiquer avec la carte, depuis n'importe quel langage de programmation, il suffit d'ouvrir le port en question est de dialoguer avec la carte suivant le protocole que tu auras défini.
J'ai réussi à écrire un code de communication, finalement en Python mais dans le code Arduino il y a des conditions qui tourne en permanence indépendamment du port série ces conditions mette en route ou non des relais suivant la valeur d'un capteur analogique mais avec mon code python je dois absolument pouvoir éteinte et allumer les relais, les conditions qui tourne en permanence prennent la main sur les instructions série.
code Python :
Ton code arduino fait ce que tu l'as programmé à faire.
Dans loop tu as mis à la suite la réception des messages par la liaison série et les commandes automatiques donc il les exécute en séquence.
Si tu veux un comportement différent, il faut modifier ton programme.
En premier lieu, si tu veux avoir 2 comportement différents, automatique et manuel, il faut définir les conditions de passage d'un mode à l'autre.
Il faut bien détailler par écrit ce que doit faire ton programme:
Dans quel cas il est autonome, dans quel cas il est piloté par la liaison série.
Comment il passe d'autonome à piloté:
par une commande, laquelle?
automatiquement, dans quelle(s) condition(s) conditions extérieure, action sur un bouton, temporisation,....
Ensuite tu pourras réécrire ton programme pour qu'il fasse ce que tu veux.
j'ai reussie à faire un protocole avec mode manu et auto mais pour mon projet il faut que le code python du PC puisse envoyer des valeurs comme des températures vers l'arduino et que l'arduino puisse savoir a quoi correspondent c'est température genre température chaudière ou température chauffe eau mais mon programme actuelle ne peut envoyer une lettre vers l'arduino il faudrait une chaîne de caractère avec un code genre 22CE pour 22°C chauffe eau mais je suis débutant en C et Arduino et je sais pas comment faire
#include <math.h>
//Liste des PIN
#define PIN_SENSOR_ANGLE A1
#define PIN_RELAY1 22
#define PIN_RELAY2 24
#define PIN_RELAY3 26
//allume les relais à partir angle=500 avec une hystérésis pour les parasites
#define ANGLE_CHANGE_UP 439
#define ANGLE_CHANGE_DOWN 447
//Com série
#define BAUDRATE 9600
//Mode de fonctionnement
#define MODE_AUTO 1
#define MODE_MANU 2
#define DEFAULT_MODE MODE_AUTO
float Temp=0;
void setup(){
long previousMillis=0; // will store last time LED was updated
// the follow variables is a long because the time, measured in miliseconds,
// will quickly become a bigger number than can be stored in an int.
long interval=5000; // interval at which to blink (milliseconds)
unsigned long currentMillis = millis();
pinMode(PIN_RELAY1, OUTPUT);
pinMode(PIN_RELAY2, OUTPUT);
pinMode(PIN_RELAY3, OUTPUT);
digitalWrite(PIN_RELAY1, LOW);
//état des relais pas défaut
if(currentMillis - previousMillis > interval) {
// save the last time you blinked the LED
previousMillis = currentMillis;
digitalWrite(PIN_RELAY1, HIGH);
}
digitalWrite(PIN_RELAY2, LOW);
digitalWrite(PIN_RELAY3, LOW);
//initialise le port com
Serial.begin(BAUDRATE);
}
void loop(){
//var et init var
int angle;
bool relayCmd=false; //donne l'ordre activer/désactiver les rélais
bool relayState=false; //indique l'états des rélais
unsigned char mode=DEFAULT_MODE;
//boucle principale
while(true){
//lecture des capteurs
angle=analogRead(PIN_SENSOR_ANGLE);
int RawADC;
RawADC=analogRead(PIN_SENSOR_ANGLE);
//communication et traitement
if (Serial.available()) {
char c=Serial.read();
switch(c){
case 'A': //mode auto
mode=MODE_AUTO;
break;
case 'H': //activation des relais + mode manu
relayCmd=true;
mode=MODE_MANU;
break;
case 'L': //activation des relais + mode manu
relayCmd=false;
mode=MODE_MANU;
break;
case '22': //demande de lecture de l'angle
Serial.print("Angle: ");
Serial.println(angle);
Temp = log(((10240000/RawADC) - 10000));
Temp = 1 / (0.001129148 + (0.000234125 * Temp) + (0.0000000876741 * Temp * Temp * Temp));
Temp = Temp - 273.15; // Convert Kelvin to Celcius
Serial.print("Celsius: ");
Serial.println(Temp);
break;
}
}
//calcul et traitement
if(mode==MODE_AUTO){
if (angle>ANGLE_CHANGE_UP)
relayCmd=true;
if (angle<ANGLE_CHANGE_DOWN)
relayCmd=false;
}
//exécution des ordres
if (relayCmd==true && relayState==false){ //front montant
digitalWrite(PIN_RELAY1,HIGH);
digitalWrite(PIN_RELAY2,HIGH);
digitalWrite(PIN_RELAY3,HIGH);
relayState=true;
}
if (relayCmd==false && relayState==true){ //front descendant
digitalWrite(PIN_RELAY1,LOW);
digitalWrite(PIN_RELAY2,LOW);
digitalWrite(PIN_RELAY3,LOW);
relayState=false;
}
}
}