Go Down

Topic: Ayuda con CANBus Modo Listen (Read 979 times) previous topic - next topic

nuevoaqui

Apr 09, 2013, 10:19 pm Last Edit: Apr 09, 2013, 10:33 pm by nuevoaqui Reason: 1
Saludos a todos.
Primero daros las gracias por todos vuestros aportes, que ma han ayudado mucho.
Pero, tengo un problema con el CANBus, no recoge datos en modo LISTEN.
Los datos en modo NORMAL los recoge sin problemas, pero en este modo, se me paran las comunicaciones de un sistema de seguridad.
Lo que estoy intentando, es captura datos del bus y guardarlos en una SD, con un sheld SPANKFUN. (como prueba para un proyecto).
Uso la libreria MCP2515 de David Harding, que funciona muy bien y es totalmente configurable, me he puesto en contacto con él, pero no ma ha contestado.
Os pongo una parte del código:

[font=Verdana]Can.ino[/font]

Code: [Select]

#include <SPI.h> // Libreria SPI de Arduino
#include <MCP2515.h> //Libreria para el controlador de CANBus MCP2515

#include <Time.h>  //Libreria captura hora RTC
#include <Wire.h>  //Libreria I2C
#include <DS1307RTC.h>  // Libreria básica DS1307 que retorna el tiempo como: time_t


// Pin específicos de cómo el MCP2515, está cableado:  CS_PIN activación línea SPI al controlador MCP2515
//                                                     INT_PIN lectura del pin de interrupción del MCP2515
#define CS_PIN    10 //Pin 10 Arduino
#define INT_PIN   2  //Pin 2 Arduino

// Se crea el objeto CAN, con los pines definidos en esas variables.
MCP2515 CAN(CS_PIN, INT_PIN);

//Declaramos los led de estado
//Led D7, pin Arduino 7, como mensaje recibido y estado interrupciones
int D7 = 7;
//Led D8, pin Arduino 8, como led auxiliar para fallo y estado interrupciones
int D8 = 8;
//Declaramos variable de iteración de secuencia inicio
// Ponemos a cero la variable de iteración "i"
byte i = 0;

void setup() {
 // Poner código de configuración aquí, se ejecutar una vez:

 //D7 y D8 como salida
 pinMode(D7, OUTPUT);
 pinMode(D8, OUTPUT);
 //Velocidad de comunicación serie
 Serial.begin(115200);

 setSyncProvider(RTC.get);   // Función que toma el tiempo del RTC


 Serial.println("Empezamos ...");
 Serial.println();
 Serial.println();
 digitalClockDisplay();
 Serial.println();
 Serial.println();
 Serial.println();
 // Configuración de las comunicaciones SPI
 // setDataMode solo puede ser, SPI_MODE0 o SPI_MODE3 para el MCP2515
 SPI.setClockDivider(SPI_CLOCK_DIV2);
 SPI.setDataMode(SPI_MODE0);
 SPI.setBitOrder(MSBFIRST);
 SPI.begin();

 // Inicializar controlador CAN MCP2515 a la velocidad especificada y frecuencia de reloj de la Tj. CAN
 // En el S9000, 250 kbps y a 16 MHz el oscilador de la Tj. CANBus. Podemos utilizar SJW como divisor sincronismo mensajes (250, 16, "1 al 4");

 int baudRate=CAN.Init(250,16,1);
  /*
 Podemos elegir entre estos modos (estan definidos en MCP2515_defs.h):
 MODE_CONFIG
 MODE_LISTEN
 MODE_LOOPBACK
 MODE_SLEEP
 MODE_NORMAL
 */
 CAN.Mode(MODE_LISTEN);
 

 if(baudRate>0) {
   Serial.println("MCP2515 Inicializacion OK ...    :-)  ");
   Serial.println("");
   Serial.print("Velocidad de transmision (kbps): ");
   Serial.println(baudRate,DEC);


   // Secuencia led D7, D8 de inicio
   for(i=0;i<4;i++) {
     digitalWrite(D7, HIGH);
     delay(50);
     digitalWrite(D8, HIGH);
     delay(50);
     digitalWrite(D7, LOW);
     delay(50);
     digitalWrite(D8, LOW);
     delay(50);
   }
 }
 else {
   Serial.println("MCP2515 Inicializacion KO... OH, OH...     :-((  ");

 }
 Serial.println("");
 Serial.println("PREPARADO ...");
 Serial.println("");
}

// Telegrama CAN (en realidad, sólo las partes de expuestas por los MCP2515 RX / TX buffers)
// Nos llega el mensaje de la biblioteca, MCP2515.CPP
Frame message;



void loop() {
 // poner código principal aquí, para ejecutar repetidamente:

 message.id=0x00; //Ponemos a "0", la ID, para leer solo con ID mayores de "0".

 // Esta aplicación utiliza el pin de interrupción "INT", 12, del MCP2515 12, para marcar los mensajes recibidos, en este caso los buffers RXB0 y RXB1.
 if(CAN.Interrupt()) {

   // Determina lo ocurrido al activarse la interrupción
   byte interruptFlags = CAN.Read(CANINTF);

   if(interruptFlags & RX0IF) {

     // lee el buffer RXB0
     message = CAN.ReadBuffer(RXB0);
     digitalWrite(D7, HIGH);
     delay(50);
   }
   if(interruptFlags & RX1IF) {

     // lee el buffer RXB1
     message = CAN.ReadBuffer(RXB1);
     digitalWrite(D7, HIGH);
     delay(50);
     // (Este código, al recibir un mensaje por el segundo buffer, sobreescribe el primero)
   }}
 // Apagamos D7 recepción mensaje
 digitalWrite(D7, LOW);
 delay(50);

 if(message.id>0x00) { //Leemos solo los ID, mayores de "0".
    //if(message.id == 0x10 | message.id == 0x56){ // Seleccionamos los telegramas que queremos
   // IMPRIME MENSAJE
   //Serial.print("Time: ");
   // digitalClockDisplay(); // Llamamos a la función y ponemos la hora de la muestra tomada.
   
   Serial.print("ID: ");
   Serial.print(message.id,HEX);
   Serial.print(" EXT: ");
   if(message.ide) {
     Serial.print(" 1");
   }
   else {
     Serial.print(" 0");
   }
   Serial.print(" DLC: ");
   Serial.print(message.dlc,DEC);
   Serial.print(" ");
   // Imprime el número de datos que nos dice el DLC de telegrama CAN
   Serial.print(" Datos: ");
   for(i=0;i<message.dlc;i++) {
     Serial.print(message.data[i],HEX);
     Serial.print(" ");
   }
   Serial.println();
   }
   // Envía un mensaje de respuesta por cada uno de los datos recibidos
   // Simplemente incrementar la identificación del mensaje y los bytes de datos, para mostrar la correcta transmisión
   // Lo dejamos desconectado para no interferir en la comunicaciones del CANBus del S9000
   //message.id++;
   //for(i=0;i<message.dlc;i++) {
   // message.data[i]++;
   //}

   //CAN.LoadBuffer(TXB0, message);
   //CAN.SendBuffer(TXB0);

 //} // Condición del IF de selección de telegramas
}
void digitalClockDisplay(){
 // Imprimimos el tiempo con forma: hh:mm:ss dia-mes-año
 Serial.print(hour());
 printDigits(minute());
 printDigits(second());
 Serial.print(" ");
 Serial.print(day());
 Serial.print("/");
 Serial.print(month());
 Serial.print("/");
 Serial.print(year());
 Serial.print(" ");
}

void printDigits(int digits){
 // función de utilidad para la visualización del reloj digital: imprime : entre hora:minuto:segundo y pone un 0 si valor menor de 10
 Serial.print(":");
 if(digits < 10)
   Serial.print('0');
 Serial.print(digits);
}

Dejo las librerías aquí;

http://arduino.cc/forum/index.php/topic,8730.msg71416.html#msg71416

Necesito de vuestra ayuda, no entiendo qué es lo que falla. No mando ningún dato y creo que las interrupciones se pueden utilizar en el modo LISTEN.

Gracias de antemano.
Probado con USB - CANBus de PEAK. Mando datos y OK en modo Normal con 29bits y 11bits.
En listen aparece BUSHEAVY.

Igor R

Hola,

No me he mirado el código que has puesto, pero antes de todo... ¿cuantos dispositivos tienes en el bus?
Si la respuesta es sólo dos dispositivos, es decir, el Arduino y el conversor de Peak, ahí viene el problema.

Saludos,


Igor R.

nuevoaqui

Gracias, por ayudar.
el sistema tiene 12 slaves, 1master y 1 master redundado.
Velocidad 250 k.
El PEAK tampoco funciona en el bus.

No tengo información de funcionamiento de las comunicaciones del sistema.
Solo tengo capturas de tramas con un osciloscopio.
Ayer cambié, cosas de la biblioteca MCP2515_defs.h, y he conseguido capturar cosa pero sin mucho sentido.

Seguiré intentando.
Si tienes alguna idea, me lo comentas estoy muy agradecido.

Igor R

#3
Apr 11, 2013, 06:06 pm Last Edit: Apr 11, 2013, 07:31 pm by Igor R Reason: 1
Cuando dices que el peak no funciona? Como lo conectas en el bus? Me refiero electricamente,etc
Ten en cuenta que es un bus, que estara terminado (120 ohm) en los extremos,etc

Quote
En listen aparece BUSHEAVY.

Yo te decia que si habias conectado el Arduino+shield (en modo listen) y al conversor de Peak, sin ningun otro dispositivo mas en el bus, es normal que no te funcione, ya que no hay nadie en el bus que cambie el ACK de los mensajes transmitidos por ese nodo. Si quieres saber mas de esto, puedes leer la parte que explica el modo Listen Only en el datasheet del mcp2515.


Saludos,


Igor

nuevoaqui

hola
El sistema funciona en bus y con sus terminadores de 120 homs.
Pertenece a un sistema de freno de una composición de trenes.
El PEAK me lo han prestado pero el SW que lleva gratuito, solo puedo configurar velocidad y tipo de ID 
osea 2.0A y 2.0B.
Mi intención es ver las tramas y sacar partes que me interesan.
Primero intenté conectar en el bus el PEAK, pero al conectarlo como conecto los otros dispositivos al bus' las comunicaciones se paran, no está mal conectado, es como si al conectar identificara algún mensaje del PEAK de error, o de trama no leida y el PEAK mande algo por el bus y sea identificado como error dispositivo, como te comentoé es de seguridad.
Con el ARDUINO, lo mismo, si lo conecto en modo NORMAL fallo sistema, si lo conecto en LISTEN solo recoge dos mensajes de dos ID que no cambian nunca.
El lunes haré una captura de lo que veo en el PC y lo dejo para que veas que pasa.

UNA IMAGEN VALE MÁS QUE MIL PALABRAS.

Gracias y si se te ocurre algo no dudes en decirlo, yo segiré aprendiendo de mis errores.

Go Up