Pages: [1]   Go Down
Author Topic: Librairie Time et serial call/response  (Read 941 times)
0 Members and 1 Guest are viewing this topic.
0
Offline Offline
God Member
*****
Karma: 2
Posts: 802
Arduino rocks
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Yep!

Bon ! Depuis un an d'absence je mets mes librairies à jour et pourtant...

Quelqu'un a-t'il déjà essayer d'implémenter dans son code la librairie Time et une transmission de données via un classique serial call/response ???

Code:
if(Serial.available())
    {
     int inByte = Serial.read();
     switch (inByte) {
     case 'a':
        processSyncMessage();
        Serial.println("READ : a");
     case 'b':
        Serial.println("READ : b");
........................
Un de mes nombreux essais malheureux...les données transitent, mais l'horloge ne se met pas à jour...

En fait, je tente de communiquer un max de données par l'intermédiaire du pc, et en outre l'horloge ainsi qu'un update de certaines variables via un interface web/python. J'utilise donc des bytes pour initier les differentes transmissions. Eh ben que nenni ! La bibliothèque Time me fout tout en l'air, rien de passe, çà bloque ou défile indefinément.
Je vous laisse volontier faire les tests et me démontrer le contraire. J'ai essayé les if, les switch/case,etc.
Indépendement, les deux fonctionnent. Ensembles, c'est le foutoirs  smiley-eek

Je pense revenir à la bibliothèque DateTime qui me semble plus propre et plus adequat avec ce que je cherche à faire, voire à construire ma propre bibliothèque...J'ai encore de nombeux essais à faire, mais là je ne vois pas de solutions dans l'instant...

Alors comment avoir une communication efficace entre l'arduino et le port série/pc avec comme prérogative une horloge temps réel (serial elle aussi) ???

Me parler pas d'un DS13** ou autre. Tout autre solution alternative m'interesse smiley-wink

Hum! Je pourrais tout passer du côté pc avec python...

@+

Zoroastre.

PS : Là j'en ai marre de chercher. Je bloque sérieusement. Je suis une pu$**n de buse de me$d*.
« Last Edit: June 21, 2011, 06:01:26 pm by zoroastre » Logged

Veuillez indiquer [RESOLU] dans l'entête du titre en éditant votre premier message smiley-wink

Ales
Offline Offline
Faraday Member
**
Karma: 39
Posts: 3582
Do or DIY
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Salut,

La librairie time te sert à faire quoi exactement ? Parce que les éventuelles solutions de remplacement vont dépendre de ce que tu as besoin. A la volée il y a effectivement le DS1307, tu peux aussi envoyer l'heure à partir du PC, utiliser la fonction millis() ...
Logged


0
Offline Offline
God Member
*****
Karma: 2
Posts: 802
Arduino rocks
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Yep!

Merci pour ton interêt B@tto smiley-wink

J'essaye effectivement de transmettre l'heure à l'arduino, mais je voudrais en plus pouvoir envoyer des données par l'intermédiaire d'une interface python. Pour moi, l'idéal serait de tout gérer côté pc.

Je commence donc à avoir des resultats. La commande write (python) semble réclamer un release aprés son execution. Pourtant, j'ai des résultats totalement aléatoires et incoherants...J'ai testé les carriage return, les sauts de ligne, différents delais...

Les scripts d'essai :
Code:
#include <Time.h>

#define TIME_MSG_LEN  11
#define TIME_HEADER  'T'
#define TIME_REQUEST  7

int inByte;

void setup()
{
// connexion usb
Serial.begin(9600);
Serial.println("MSG : Waiting for sync message");
setSyncProvider(requestSync);
delay(100);
Serial.println("MSG : setup complete");
}

void loop()
{
  if (Serial.available()>0) {
  int inByte = Serial.read();
  switch (inByte) {
    case '5' :
      Serial.println("READ : 5");
    case '4' :
      Serial.println("READ : 4");
      delay(10);
      Serial.print(TIME_REQUEST, BYTE);
      processSyncMessage();
  }
}
    delay(2500);
    Serial.println("DBG : START TRANSMISSION");
    delay(2500);
    Serial.println("a");
    delay(2500);
    Serial.println("1");
    delay(2500);
    Serial.println("SYN");
    delay(2500);
    Serial.print(hour());
    Serial.print(":");
    Serial.println(minute());
    Serial.println("END OF TRANSMISSION");
    delay(2500);
}

void processSyncMessage() {
  // if time sync available from serial port, update time and return true
  while(Serial.available() >=  TIME_MSG_LEN ){  // time message consists of a header and ten ascii digits
    char c = Serial.read() ;
    Serial.print(c);  
    if( c == TIME_HEADER ) {      
      time_t pctime = 0;
      for(int i=0; i < TIME_MSG_LEN -1; i++){  
        c = Serial.read();          
        if( c >= '0' && c <= '9'){  
          pctime = (10 * pctime) + (c - '0') ; // convert digits to a number    
        }
      }  
      setTime(pctime);   // Sync Arduino clock to the time received on the serial port
    }  
  }
}

time_t requestSync()
{
  Serial.print(TIME_REQUEST,BYTE);  
  return 0; // the time will be sent later in response to serial mesg
}

Code:
import serial, time

ser = serial.Serial('/dev/ttyUSB0',9600)

def update_time():
    time.sleep(0.1)
    tic = time.time() - time.timezone + time.daylight*3600
    tics = 'T' + str(tic)[0:10]
    ser.write(tics)

while 1:
    data = ser.readline()
    if data[0:1] == '1' :
        print "RECEIVED - 1"
    if data[0:1] == 'a' :
        print "RECEIVED - a"
    if data[0:1] == '\7' :
        update_time()
        time.sleep(0.2)
        print "TIME UPDATED"
    if data[0:3] == 'END' :
        time.sleep(0.1)
        ser.write('5')
        time.sleep(0.1)
    if data[0:3] == 'SYN' :
        print "RECEIVED SYN"
        ser.write('4')
        time.sleep(0.1)
    print data

J'aimerais éviter les pertes de donner et stabiliser tout cà. L'interface python que je développe est multithread avec une partie pour enregistrer les logs transmises par l'arduino et une autre permettant d'envoyer des données vers l'arduino. J'envisage d'autres solutions, mais à vrai dire, je reprends les choses depuis le début.

Je n'ai pas de problème pour enregistrer les data, mais je manque de précision du pc vers l'arduino.

Code:
READ : 5

READ : 4

TIME UPDATED
DBG : START TRANSMISSION

RECEIVED - a
a

RECEIVED - 1
1

RECEIVED SYN
SYN

RECEIVED - 1
16:4

END OF TRANSMISSION

DBG : START TRANSMISSION

MSG : Waiting for sync message

TIME UPDATED
MSG : setup complete

DBG : START TRANSMISSION

RECEIVED - a
a

RECEIVED - 1
1

RECEIVED SYN
SYN

TIME UPDATED
0:0

END OF TRANSMISSION

Aprés un reboot de l'arduino par exemple, la mise à jour de l'horloge ne se fait plus...de plus certaines info ne semblent plus être correctement gérées.
J'aimerais avoir des précisions sur comment appréhender correctement la com du pc vers l'arduino et sur le buffer ???

@+

Zoroastre.
« Last Edit: June 22, 2011, 09:47:14 am by zoroastre » Logged

Veuillez indiquer [RESOLU] dans l'entête du titre en éditant votre premier message smiley-wink

0
Offline Offline
God Member
*****
Karma: 2
Posts: 802
Arduino rocks
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Yep!

Bon, j'ai résolu mon problème initial. J'arrive enfin à synchro l'heure entre le pc et l'arduino tout en gérant une structure de communication sériel. J'ai tout simplement incorporé la mise à jour de l'heure à mon message de communication.
Pour préciser mes desideratas, je voudrais incorporer à mon projet, la possibilité de modifier les variables ou les modes de fonctionnement soit par l'intermédiaire de script pc (python) soit par un afficheur glcd tactile (S1D13700).
Les données, ainsi qu'un système de log, seront écrites dans des fichiers afin de garantir un aspect statique et dynamique à la fois, un peu à la manière unix.

Actuellement, j'envoie les données du pc vers l'arduino dans un tableau 2D. La première dimension sert de donnée d'entrée, la seconde dimension distribuera les variables à l'arduino.

Le script :
Code:
/*
Simple Message system arduino/serial pc
1 - Clock update
2 - Send Log
3 - Retrieve data
The goal is to have a synchronized table with index

1 - {START BIT}
2 - {IsUpdate 0/1}
# BEGIN OF DATA
3 - {MODE AUTO/AWAY/VACANCY/OFF}
4 - {A FLOAT}
5 - {AN INT }
6 - {A CHAR}
# END OF DATA
7 - {STOP BIT}

EXAMPLE MSG :
T1309023435|15.25Z
FORMAT
T1234567890 | 1 | 2345 | 68

*/

#include <string.h>
#include <stdlib.h>

#include <OneWire.h>
#include <DallasTemperature.h>

#include <Time.h>

#define ONE_WIRE_BUS 3
#define TEMPERATURE_PRECISION 10

#define TIME_MSG_LEN  11
#define DATA_HEADER  'T'
#define DATA_REQUEST  7

#include <OneWire.h>
#include <DallasTemperature.h>

OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);

uint8_t indoor[8] = {0x28, 0xFC, 0x97, 0x56, 0x2, 0x0, 0x0, 0x69};

float tempC0;
int _minute, last_minute;

// index for server message array
int  serveIn;
char serveInString[1][25];
int  serveInIndx  = 0;
int  serveOutIndx = 0;

void setup() {
Serial.begin(9600);
sensors.begin();
sensors.requestTemperatures();
}

void loop() {
  
processSyncMsg();
  
delay(2000);

//request time if needed
if(timeStatus() == timeNotSet)
  {
      checkTime();
  }

// set time vars
int _hour = (hour());
int _minute = (minute());
int current_time = (_hour*60) + _minute;

delay(2000);

// print log every minute
if (_minute != last_minute)
{
  sensors.requestTemperatures();
  tempC0 = sensors.getTempC(indoor);
  last_minute = _minute;
  Serial.print(_hour);
  Serial.print(":");
  Serial.print(_minute);
  Serial.print("|");
  Serial.print(current_time);
  Serial.print("|");
  Serial.print(tempC0);
  Serial.println("°C");
}

delay(1000);

}

void readMessageFromServer() {
    int sb;  
    if(Serial.available()) {
       Serial.print("reading Server String: ");     //optional confirmation
       while (Serial.available()){
          sb = Serial.read();
          serveInString[0][serveInIndx] = sb;
          serveInIndx++;
          Serial.write(sb);                        //optional confirmation
       }
       Serial.println();
    }  
}

void printMessageFromServer() {
  if( serveInString > 0) {
    Serial.print("Arduino memorized MESSAGE: ");
    if ((serveInString[0][0] == DATA_HEADER)) {
       for(serveInIndx=0; serveOutIndx < 15; serveOutIndx++) {
          Serial.print(serveInString[0][serveOutIndx]); }
    }
  }
      // reset array
      serveOutIndx = 0;
      serveInIndx  = 0;
      //Serial.println();
}

void processSyncMsg() {
  readMessageFromServer();
  Serial.print(DATA_REQUEST, BYTE);
  printMessageFromServer();
}

boolean checkMsg() {
  if (serveInString[0][0] == serveInString[1][0]) {
    return true; }
  else {
    return false; }
}


void checkTime() {
  if( serveInString > 0) {
    Serial.print("Arduino memorized TIME: ");
    if ((serveInString[0][0] == DATA_HEADER)) {
       time_t pctime = 0;    
      //loop through all bytes in the array and print them out
      for(serveOutIndx=0; serveOutIndx < TIME_MSG_LEN; serveOutIndx++) {
        Serial.print(serveInString[0][serveOutIndx]);    //print out the byte at the specified index          
        if( int(serveInString[0][serveOutIndx]) >= '0' && int(serveInString[0][serveOutIndx]) <= '9'){  
          pctime = (10 * pctime) + (int(serveInString[0][serveOutIndx]) - '0') ; // convert digits to a number    
        }
      }
      setTime(pctime);   // Sync Arduino clock to the time received on the serial port

          }
    }
    // reset array
      serveOutIndx = 0;
      serveInIndx  = 0;
}


C'est trés artisanal comme vous pouvez le constater.
Il me reste à faire :
  - Inclure un séparateur entre les données de la trame <-- Cà c'est ok
  - détecter automatiquement la taille des données        <-- J'y reflechis.
  - Pouvoir ne modifier qu'un index de la table                 <-- peut-être une table 3D + separateur [index:val]
  - ...

Je découvre complètement cet aspect de la programmation et cherche dans plusieurs directions en même temps. Je sais qu'il existe des librairies ayant les mêmes optiques(firmata, pyduino, simple messenger), mais aucunes ne me convenaient, trop rigides, pas adaptés à mes besoins.(C'est tellement mieux quand c'est DIY smiley-wink )

Le script python (simplicisme) :
Code:
import serial, time

ser = serial.Serial('/dev/ttyUSB0',9600, timeout=0.2)
logs = []

def send_msg():
    tic = time.time() - time.timezone + time.daylight*3600
    tics = 'T' + str(tic)[0:10]
    ser.write(tics + '|' + '15.25Z'+'\r')

def retrieve_log() :
    pass
    
while 1:
    data = ser.readline()
    if data:
        if data[0:1] == '\7' :
            send_msg()
        print data

J'arrive pour finir à convertir les caratères en int ou en float sous l'arduino, donc pas de souci de se côté là.


J'attends vos commentaires/recommandations/critiques avec impatience smiley-wink

@+

Zoroastre.
« Last Edit: June 25, 2011, 03:56:34 pm by zoroastre » Logged

Veuillez indiquer [RESOLU] dans l'entête du titre en éditant votre premier message smiley-wink

Pages: [1]   Go Up
Jump to: