Go Down

Topic: Interruption sur Serial ? (Read 1 time) previous topic - next topic

yellowsky

Bonjour à tous,

Je vous explique brièvement ma situation. Je dispose d'un Arduino relié par USB à un PC en charge d'un script python mais aussi via CAN à un autre Arduino. Le script envoi un message un certain nombre de fois à l'Arduino qui se charge de le transmettre par CAN à l'autre carte. Un message CAN retour a alors lieu et je désire le transmettre à mon script.
Le fonctionnement du sktech peut être résumé comme ça :

Code: [Select]

void loop(){
  if(CANmsg)
    Serial.write(rep);
   
  if(Serial.available()){
    char chr = Serial.read();
    can_send_msg(chr);
  }
}


Mon problème est que mon write ne semble pas fonctionner à cause d'une activité RX trop importante. Y a t'il moyen de suspendre temporairement la réception pour se concentrer sur l'émission ?
Merci d'avance

B@tto

A moins d'une activité extrêmement soutenue, aucune chance que les deux se perturbe pour la simple est bonne raison que les envois séries ne sont pas bloquant, et que la carte dispose de mémoire tampon pour stocker les données quand elles arrivent et les traiter quand on le demande.

Donc soit tes transmissions sont très généreuses (c'est pas impossible je l'ai déjà vu) soit y'a un truc dans ton code.
Blog électronique : battomicro.wordpress.com
Photographie : www.interactive-celebration.fr
Fablab de Montpellier : www.labsud.org

fdufnews

Taille des messages échangés?
Débit?

yellowsky

En l'occurrence ici j'envoi 4 octets "FF 1 0 80" avec un baud rate de 115200.
Ce n'est pas impossible qu'il y ai un problème dans mon code Arduino, le script un peu moins car il a été repris du site kreative-chaos.
Je vais tenter de décrypter a l'oscillo le message TX

skywodd

Bonjour,

Question conne : tu reset le flag "CANmsg" après envois ?
Si tu ne le fait pas c'est logique que tu traites toujours le même signal en Rx ...

Le code complet serait utile ;)
Des news, des tutos et plein de bonnes choses sur http://skyduino.wordpress.com !

yellowsky


Bonjour,

Question conne : tu reset le flag "CANmsg" après envois ?
Si tu ne le fait pas c'est logique que tu traites toujours le même signal en Rx ...

Le code complet serait utile ;)


Oui bien sur, le code donné n'est qu'un prototype du fonctionnement général, derrière il y'a une fonction qui s'occupe bien de ça.
Voici le code de mon sketch

Code: [Select]
#include <CanBib.h>

CAN can;

prog_uint8_t can_filter[] =
{
// Group 0
MCP2515_FILTER(0), // Filter 0
MCP2515_FILTER(0), // Filter 1

// Group 1
MCP2515_FILTER_EXTENDED(0), // Filter 2
MCP2515_FILTER_EXTENDED(0), // Filter 3
MCP2515_FILTER_EXTENDED(0), // Filter 4
MCP2515_FILTER_EXTENDED(0), // Filter 5

MCP2515_FILTER(0), // Mask 0 (for group 0)
MCP2515_FILTER_EXTENDED(0), // Mask 1 (for group 1)
};

void term_put_hex(const uint8_t val)
{
  uint8_t tmp = val >> 4;
 
  if (tmp > 9)
    tmp += 'A' - 10;
  else
    tmp += '0';
  Serial.write(tmp);
 
  tmp = val & 0x0f;
 
  if (tmp > 9)
    tmp += 'A' - 10;
  else
    tmp += '0';
  Serial.write(tmp);
}

void setup(){
      Serial.begin(115200);
      // Initialize MCP2515
      can.mcp2515_init(BITRATE_250_KBPS);
      can.clearFlags();
      can.activateInterrupt();
      // Load filters and masks
      //can.mcp2515_static_filter(can_filter);
      can.resetFiltersAndMasks();
}

void loop()
{   
   
    static char buffer[40];
    static uint8_t pos;
    can_t msg;
   
    if (can.mcp2515_get_message(&msg))
    {
      Serial.write(msg.length + '0');
      for(int i=0;i<msg.length;i++)
      {
        term_put_hex(msg.data[i]);
      }
      Serial.write('\r');
      }
     
    if(Serial.available()) /// receive USB Data
    { 
     
      char chr = Serial.read(); // read the incoming data
      if (chr != '\r'){ // wait the end of the message
       
        buffer[pos] = chr;
        pos++;
     
        if (pos >= sizeof(buffer)) {
        // format-error: command to long!
        pos = 0;
        }
      }
      else {
        buffer[pos] = '\0';
        can.usbcan_decode_command(buffer, pos); // try to send by CAN
        pos = 0;
       }
    }
   
}


Je ne pense pas que cela soit utile de joindre ma librairie car mes fonctions CAN fonctionnent parfaitement, mon seul problème survient au Serial.write (et je suis certain que cette portion du code est executée j'y fais clignoté mes LEDs et mon CAN listener me confirme les réceptions des messages) qui visiblement n'est pas correctement réceptionné au niveau du script [bootloader-python sur http://www.kreatives-chaos.com/artikel/can-bootloader] (voir même pas du tout) car ma Queue de message entrant reste toujours vide.
Comme je travaille avec l'IDE Arduino j'ai du adapté le code du CAN debugger de kreative chaos pour ce qui concerne la partie USB2CAN, j'ai simplement traduit ses fonctions de read et write avec celles de l'Arduino

Code: [Select]

// ------------------------------------------------------------------------
uint8_t term_data_available(void) {
return (!IS_SET(USB_RXF));
}

// ------------------------------------------------------------------------
uint8_t term_getc()
{
uint8_t t;

// read databyte
RESET(RD);
asm ("nop");

t = PIN(USB_DATA);
SET(RD);

return t;
}

// ------------------------------------------------------------------------
void term_putc(const char c)
{
// wait until ft245 ready to receive byte
while (IS_SET(USB_TXE))
;

DDR(USB_DATA) = 0xff;
PORT(USB_DATA) = c;

// write data
SET(WR);
asm ("nop");
RESET(WR);

// use port as input, pull-ups on
DDR(USB_DATA) = 0;
PORT(USB_DATA) = 0xff;
}


Voila ça me laisse perplexe...

yellowsky

Problème résolu, en bidouillant le code python je me suis rendu compte que le message attendu n'était pas celui que je lui envoyé à cause d'une entête manquante et était donc rejeté. Maintenant tout fonctionne 8)

Go Up