AppIventor et Arduino liaison série

Bonjour,

J'ai un capteur MPU6050 qui relève les valeurs d'accélérations et de rotations grâce à mon programme Arduino(sur arduino Uno). Mon programme fonctionne très bien et envoi les valeur du capteur toute les 1s sur le Bus I2C.

L'arduino est relier en Série (cable) à une tablette/un téléphone ou j'ai fait une application qui récupère les données envoyer en séries et les affiches.

Mon problème maintenant est de synchroniser l'horloge de mon applis avec celle de l'arduino pour relever au bon moment les données sinon l'applis ne récupère pas tout OU de trouver un moyen de récupérer les données à la réception sur l’appareil (sans utiliser l'horloge) mais je n'ai pas trouver comment faire avec AppInventor.
Voici ce que j'ai fait sur appInventor:

Avec ce petit programme cela m'affiche mes données mais en décaler, je m'explique, le 1er affichage vas etre parfait puis le 2eme vas être décaler d'une ou plusieurs lignes et ainsi de suite; je pense donc au problème de synchronisation d'horloge.

Avez-vous une piste ou une idée pour me guidé ?

Merci d'avance !

Bonjour azzog

Mets ton programme Arduino et App Inventor en ligne.

Cordialement
jpbbricole

Je ne vois pas trop comment poster mon code AppInventor autrement qu'avec des captures d'écrans.
Sinon voici la partie de mon code concernant le MPU6050:

#include "Wire.h" // This library allows you to communicate with I2C devices.

const int MPU_ADDR = 0x68; // I2C address of the MPU-6050. If AD0 pin is set to HIGH, the I2C address will be 0x69.

int16_t accelerometer_x, accelerometer_y, accelerometer_z; // variables for accelerometer raw data
int16_t gyro_x, gyro_y, gyro_z; // variables for gyro raw data
int16_t temperature; // variables for temperature data

char tmp_str[7]; // temporary variable used in convert function

char* convert_int16_to_str(int16_t i) { // converts int16 to string. Moreover, resulting strings will have the same length in the debug monitor.
  sprintf(tmp_str, "%6d", i);
  return tmp_str;
}

void setup() {
  TCCR2B = 0x02;
  Serial.begin(115200);
  Wire.begin();
  Wire.beginTransmission(MPU_ADDR); // Begins a transmission to the I2C slave (GY-521 board)
  Wire.write(0x6B); // PWR_MGMT_1 register
  Wire.write(0); // set to zero (wakes up the MPU-6050)
  Wire.endTransmission(true);
}
void loop() {
  Wire.beginTransmission(MPU_ADDR);
  Wire.write(0x3B); // starting with register 0x3B (ACCEL_XOUT_H) [MPU-6000 and MPU-6050 Register Map and Descriptions Revision 4.2, p.40]
  Wire.endTransmission(false); // the parameter indicates that the Arduino will send a restart. As a result, the connection is kept active.
  Wire.requestFrom(MPU_ADDR, 7*2, true); // request a total of 7*2=14 registers
  
  // "Wire.read()<<8 | Wire.read();" means two registers are read and stored in the same variable
  accelerometer_x = Wire.read()<<8 | Wire.read(); // reading registers: 0x3B (ACCEL_XOUT_H) and 0x3C (ACCEL_XOUT_L)
  accelerometer_y = Wire.read()<<8 | Wire.read(); // reading registers: 0x3D (ACCEL_YOUT_H) and 0x3E (ACCEL_YOUT_L)
  accelerometer_z = Wire.read()<<8 | Wire.read(); // reading registers: 0x3F (ACCEL_ZOUT_H) and 0x40 (ACCEL_ZOUT_L)
  temperature = Wire.read()<<8 | Wire.read(); // reading registers: 0x41 (TEMP_OUT_H) and 0x42 (TEMP_OUT_L)
  gyro_x = Wire.read()<<8 | Wire.read(); // reading registers: 0x43 (GYRO_XOUT_H) and 0x44 (GYRO_XOUT_L)
  gyro_y = Wire.read()<<8 | Wire.read(); // reading registers: 0x45 (GYRO_YOUT_H) and 0x46 (GYRO_YOUT_L)
  gyro_z = Wire.read()<<8 | Wire.read(); // reading registers: 0x47 (GYRO_ZOUT_H) and 0x48 (GYRO_ZOUT_L)
  
  // print out data
  Serial.print("aX = "); Serial.print(convert_int16_to_str(accelerometer_x));
  Serial.print(" | aY = "); Serial.print(convert_int16_to_str(accelerometer_y));
  Serial.print(" | aZ = "); Serial.print(convert_int16_to_str(accelerometer_z));
  // the following equation was taken from the documentation [MPU-6000/MPU-6050 Register Map and Description, p.30]
  Serial.print(" | tmp = "); Serial.print(temperature/340.00+36.53);
  Serial.print(" | gX = "); Serial.print(convert_int16_to_str(gyro_x));
  Serial.print(" | gY = "); Serial.print(convert_int16_to_str(gyro_y));
  Serial.print(" | gZ = "); Serial.print(convert_int16_to_str(gyro_z));
  Serial.println();
  
  // delay
  delay(1000);
}

Les commentaires sont en anglais désoler mais ce projet ne vas pas rester en France.

bonjour

pour synchroniser tout ca il faudrait que le materiel (arduino) envoie les valeurs a la demande du recepteur (programme inventor)
dans le programme inventor envoyer au moment voulu un "code" de déclenchement de l'envoie de la séquence en réponse

en fait instaurer un vrai dialogue entre les deux ce qui n'est pas le cas pour l'instant.

du type :roll_eyes:

"envoie moi les données !"
"voila les données!"

on attend et on recommence ...

j'ai pas mon inventor a jour mais dans l'objet serial il ne semble pas y avoir de fonction permettant de savoir si qq chose est en train d'etre recu ....
du genre serial available du coté arduino

.

Merci de t'a réponse,

J'y avait déjà pensée et c'est faisable en wifi/bluetooth/zigbee ect... mais pas en série apparemment ou il y'a un truc que je ne comprend pas avec la liaison série dans AppInventor

Les seul choses qui me sont possible à codée en applis sont:
Envoyer une données à l'arduino
ou
Lire les données de l'arduino

La tu vas me dire que si je peut envoyer qqch à l'arduino je peut le faire envoyer quand je veux sur réception d'un caractère, oui effectivement sa marche mais mon problème reste le même si l'applis ne récupère pas exactement au bon moment il y'a des données qui ne sont pas prise et il n'y a pas de mode "attente des mesures"/"attente de réponse".

Si quelqu'un connais un autre moyen de crée ce type d'application comme Arduino Studio je suis preneur aussi je ne suis pas obligé de faire avec AppInventor surtout si ce n'est pas possible.

Parcontre mes connaissance en Java et programmation objet sont assez limitées alors que je connais assez bien AppInventor.

inventor envoie le code il attend suffisemment de temps pour avoir la reponse (genre une seconde) puis va lire le buffer serie si le buffer est de bonne taille normalement tout y est

il affiche ce qu il a recu puis recommence une demande immediatement ou apres un certain temps

PS : en dehors d'inventor les autres trucs sont des usines gaz et sauf a avoir a s'en servir souvent l'investissement en temps est inutile.

Pourtant d'apres ce que j'ai essayer il n'attend pas il envoie son caractère puis next.
Par exemple je dit a mon arduino qu'il faut attendre le mot "Start" pour envoyer la mesure, sur mon terminal PC sa fonctionne sans probleme
Sur l'applis je fait envoyer un "Start" puis en dessous je fait le Readserial, sa peut marcher le 1er coup mais a partir du deuxieme il y'a un décalage.

Au moment ou je fait le readserial, il vas piocher dans la liaison série sa poignet d'info (de la taille du buffer) mais sans certitude que ce soit au bon moment.
Sauf si il existe un bloc d'attente cacher quelque part mais je ne sais pas ou.

Bonjour azzog

Il n'est pas nécessaire de synchroniser, il faut que App Inventor scanne, toutes les 250 millisecondes environ, l'arrivée éventuelle de caractères, je n'ai jamais fait en liaison câble mais en Bluetooth.

Pour exporter un programme de MAI, c'est ce menu:
image

Tu reçois un fichier MAI que tu zippes, que tu copies et colles sur le forum.

A+
Cordialement
jpbbricole

Merci de l'astuce !

Effectivement en bluetooth c'est possible de vérifier si il arrive qqch mais pas en série apparemment.

faut faire un start attendre puis lire le buffer pas faire le serial read immédiatement apres l'envoi du start.

les aia c'est bien pour de la sauvegerde mais rentrer dedans c'est une autre histoire...

Sauf si il existe un bloc d'attente cacher quelque part mais je ne sais pas ou.

cette phrase me fait supposer que tu ne sait pas utiliser le chronometre en delai ???

Il faut être conscient du temps d'exécution du code que l'on produit.
Si ton application envoie une chaîne avec un Serial.print() à 115200 bauds il faut compter un peu moins de 90µs pour émettre un caractère. Donc pour envoyer la chaîne "Start" il faut environ 450µs. Pour mettre les choses en perspectives, le CPU de l'Arduino exécute une instruction toutes les 60nS environ. Certes, une ligne de C c'est plusieurs instructions mais on voit tout de suite qu'il y a plusieurs ordres de grandeur entre la vitesse d'exécution du code et la transmission sur la ligne série.
Lorsque print s'exécute, la chaîne est placée dans un tampon et les caractères seront envoyés, un par un, au rythme de la liaison série par une tâche qui est indépendante de ton application. Pendant ce temps ton application reprend la main et tu exécutes la suite de ton code.
Donc si tu fais "je fait envoyer un "Start" puis en dessous je fait le Readserial,"
Lorsque tu fais le readSerial ton Start n'est même pas encore arrivé à son destinataire.
Celui-ci va en plus prendre un certain temps pour interpréter la chaîne reçue puis construire sa réponse et la transmettre ce qui va encore prendre du temps.
Donc il ne faut pas hésiter à mettre en pause quelques millisecondes pour laisser le temps à la réponse d'arriver.

Si je sais le faire mais je parlait d'un bloc d'attente de données série, pas d'un bloc de delai.

J'avais conscience du temps que mon code s'effectue mais j'avoue avoir zapper le temps d'envoi du start + le temps de transmission retour
merci je vais pouvoir corriger mes temps et je vais régler ma tempo en espérant que sa règle se décalage.

Bonjour azzog

Essaies en cherchant app inventor polling serial.

En Bluetooth je fais ainsi:


Les commandes envoyées à MAI ont le format COMMANDE=PARAMETRE
Ca doit être transposable su Serial?

Cordialement
jpbbricole

Peut etre que oui, mais certain bloc comme "ReceiveText" n'existe pas pour du serial.
Je vais aussi me pencher dessus.
Merci!

il n'y a pas d'event sur le serial appinventor

sauf a chercher un serial alternatif de la communauté ...

Bonjour

Sauf erreur, il en va de même avec Bluetooth, c'est du polling
image
rythmé par in timer.

Regardes cette page, il y a des exemples à télécharger pour les 2 sens.

Cordialement
jpbbricole

Je vien de me rendre compte en débranchant le câble de mon téléphone qu'il continuer de l’écrire des données alors que le capteur n'est plus brancher, j'ai attendu un petit peu puis après 4 clock plus rien ne s'affiche.
Le problème est donc que mon buffer est plein dès le 1er envoi de données et c'est pour cela qu'a chaque affichage il n'affiche qu'une partie car tout ne rentre pas.

Mais ducoup si l'affichage est bon sur le moniteur série du PC le problème vient de mon téléphone.
Je vous dirai quand j'aurai trouver comment faire pour changer le BufferSize de mon téléphone.

En tout cas merci à tous pour votre aide jusque Ici !

C'est un peu mieux mais malgré sa et toute vos solution le problème persiste.
J'aurai quelques questions pour vérifier certaine chose:

  • Est ce qu'il y'a un nombre maximum de ligne que l'ont peut envoyer ?
    Je pense que non du moment que sa rentre dans le buffer mais j'aimerai une confirmation.
  • Le buffer de l'arduino est de 64Byte donc inutile de mettre plus dans mon applis ?
  • Dans mon code donner plus haut, mes données sont bien envoyer en même temps (à quelques microseconde près) ? donc avec une pause d'1s entre chaque envoi suffit largement au traitement de l'applis ?

Je commence un peu à me perdre et à être fatiguer de ce problème.

Bonjour azzog

Je vais essayer de mon côté, mais, comme je n'ai jamais utilisé MAI avec câble, faut-il installer un driver spécial pour ça?

Cordialement
jpbbricole