viernes, 9 de octubre de 2020

CanOpen, Linux y STM32F103

Introducción. 

    Estuve trabajando en proyectos con CanOpen.
    Dicho protocolo era una materia pendiente para mi.
    Así que me dí a la tarea de tratar de entender y comunicarme mínimamente con dispositivos CanOpen de distintos fabricantes.

     Sin más dejaré asentado las herramientas que fuí utilizando, lejos está de estar optimizado el sistema, pero es un buen punto de partida, para quién esté interesado.

     Sepan que no soy un experto en el tema, así que quizás haya temas que no estan profundamente desarrollados y quizás, también, con algunos errores conceptuales. No obstante, los invito que si están realmente interesados en profundizar en el protocolo, busquen e investiguen. Con lo aquí descripto he podido comunicarme con cualquier equipo con 
CanOpen disponibles.

    Como siempre, lo aquí descripto, es lo que utilicé personalmente para entender y poner en marcha  este sistema.



Referencias:


    El texto en este formato y color es el devuelto por la PC.


    El texto en este formato y color es el que deben ingresar en la línea de comando.

Que es CanOpen?

Abunda información sobre lo que es CanOpen, así que si llegaron hasta esta entrada del blog, seguramente están necesitando algo mas práctico para empezar a utilizarlo.

Algunas definiciones aburridas, pero necesarias.
Resumen de definciones.

*- CanOpen posee tres modelos de comunicación:

    *- Master/Slave
    *- Client/Server
    *- Producer/Consumer 

*- Protocolos disponibles esenciales:

    NMT (Network management): Utilizado para establecer el estado del nodo. (Initialization, pre-operational, operational, stopped). 
 Utiliza el modelo Master/Slave

    SDO (Service device object): Utilizado para mensajes de configuración. (Permite leer y escribir registros determinados). También se puede utilizar para operar el dispositivo, no obstante es poco eficiente.
 Utiliza el modelo Master/Slave


Código de comados por SDO
Comando


4 byte de datos 2 byte de datos 1 byte de datos
5to a 8vo byte 5to a 6to byte 5to byte
Pedido de escritura (Enviar parámetro al drive) 23h 2Bh 2Fh
Respuesta de escritura (El drive responde a la solicitud de la escritura, reconociendola) 60h 60h 60h
Pedido de lectura (Pedido de lectura de un parámetro desde el drive) 40h 40h 40h
Respuesta de la lectura (Responde a la lectura con el valor actual) 43h 4Bh 4Fh
Respuesta con error 80h 80h 80h


Tabla 1


    PDO (Process device object): Utilizado para el intercambio de datos entre nodos en tiempo real.

     Los protocolos SYNC (Synchronization), EMCY (Emergency), TIME (TimeStamp) y HEARTBEAT (Node monitoring), están disponibles también, pero escapan a esta entrada (mas información en la WEB).

*-Estructura del paquete:


Identificador Datos
11 bits Byte 0 Byte 1 Byte 2 Byte 3 Byte 4 Byte 5 Byte 6 Byte 7

Tabla 2



Identificador
x x x x x x x x x x x
Cod. Funcion Id Nodo

Tabla 3


 Entre el Identificador y Datos existen 5 bits propios del telegrama Can, sin embargo, son generados por el módulo de Can del dispositivo, se han omitido por legibilidad.


Herramientas.


*-Slcan:

    Linux (distro Debian en mi caso), tiene disponible SocketCan, que provee algunas interfaces del tipo CAN:

    *- Interfaces virtuales como vcan0
    *- Interfaces nativas  (hardware real), como can0
    *- Interfaces SLCAN (interfaces serie), como slcan0
 
*-Stm32-slcan:

https://github.com/GBert/misc/tree/master/stm32-slcan



   Es un proyecto del tipo OpenSource, que utiliza librerías libopencm3, para convertir una placa blue-pill (STM32F103), en una económica interfaz serie para CAN.

    El código fuente lo compilé y subí a mi blue-pill, utilizando Atom junto al framework de libopencm3.

    He modifcado el archivo "usart.c", en la línea

    #define USART2_SPEED    500000

    para 

    #define USART2_SPEED    115200 

    Hice lo anterior ya que no podía comunicarme con el dispositivo (creo que mi adaptador USB-Serial TTL no soporta esa velocidad)

    En fuentes, dejo el link a los archivos  "slcan-bluepill.elf" y el "slcan-bluepill.bin", por si quieren evitar la compilación. Estos archivos, son los que subí a mi placa y funcionaron. 

    Para grabarlo en su placa pueden utilizar openocd (si poseen un dongle st-link) o con la utilidad  stm32flash para grabarlo por medio de un USB-serial TTL. ( Mas info en la web, quizás en algún momento elaboro una entrada con el uso de stm32flash).

    Además del firmware, para que nuestra placa pueda conectarse a un bus Can, es necesario colocar un adaptador de interfaz serial a Can, en mi caso utilicé el iso1050 el cual lo obtuve de unos PLC inoperantes. Este componente con encapsulado 8-Pin DUB, es muy fácil de conectar, y soldando unos pines es facilmente utilizable en un protoboard.

    El esquema de conexiones está perfectamente detallado en el repositorio de stm32-slcan. (no utilicé el MCP2562, ni los leds para el estado de comunicación que detalla en el diagrama)

Mi configuración para pruebas. En el HUB USB se observa el conversor USB-Serial TTL y mi dongle St-link. En el protoboard, fuente USB-Protoboard, ISO1050 (cable amarillo CanH, cable negro CanL) y blue-pill.
 
N.A.: Por alguna razón que aún no investigué, deben presionar reset en la blue-pill luego de flashear o al energizar el sistema, no siempre es necesario, pero en ocasiones que no pude comunicarme con los slaves, presionando reset, todo funcionaba correctamente. Así que, ni bien energizan, presionan reset.

*- CanOpen Slave:

    Para los primeros ensayos utilicé un variador de frecuencia WEG modelo CFW500 para 1Hp, al cual hay que añadirle un accesorio llamado plug-in CanOpen, para darle conectividad a la red (los manuales de los link están en español, no obstante estos equipos son de origen brasilero, por lo que recomiendo que utilicen los manuales en portugués, para quién comprenda dicho idioma, solo es una recomendación, en español son funcionales).


Pinout del plug-in para CFW500 (Recordar que CanOpen Posee alimentación independiente,  es decir no proviene del equipo). CAN H y CAN L, son conectados al montaje anteriormente descripto (cable amarillo y negro en mi montaje)

    Mas ensayos realicé con PLC unitronics, variador SEW, y un sensor de presión. Todos con resultados satisfactorios.

Poniendo en marcha el sistema.

Presentadas las herramientas, comenzaremos a configurarlas y utilizarlas.

Comenzamos en nuestra PC con Linux.

Para los ensayos utilicé Konsole (escritorio KDE), como terminal, en la cual abro 3(tres) pestañas, una con usuario root para el montaje de los módulos. Otra como usuario normal para enviar comandos y la tercera pestaña también como usuario normal para ver la actividad del CanOpen, con candump.


Cuando conecten su adaptador serial TTL a USB a la PC, asegurense de la denominación que linux le dió ($ ls /dev/tty*) en mi caso /dev/ttyUSB0
 



*- Iniciando slcan

    # modprobe can
 
    # modprobe can-raw

 
    # modprobe slcan

    # slcand -s2 -S115200 /dev/ttyUSB0 can0

    # ip link set up can0


Pestaña root para el montaje de los módulos y la inicialización de la interfaz
Ahora para utilizar las siguientes herramientas en Linux primero debemos instalar:

    # apt install can-utils

Una vez hecho lo anterior podremos hacer lo siguiente:

 
*- Analizando bus (pestaña terminal):
      En esta pestaña podremos observar toda la actividad del bus, desde lo que "enviamos" hasta todas las comunicaciones de los nodos. (esto último, muy útil para usuarios con experiencia)

    $ candump can0

Pestaña usuario normal con candump para registrar la actividad del bus


*- Enviando comandos (otra pestaña terminal):
     Desde esta pestaña "enviaremos" los comandos hacia los nodos. (mayormente los nodos son servidores y nuestra PC cliente)

Pestaña usuario normal utilizando cansend para enviar comandos hacia la red CanOpen



    Pasar a operacional al nodo ID 2
    $ cansend can0 000#0102



Ejemplo de paquete:

Queremos enviar un SDO desde master, solicitando al slave ID 2, el registro cuyo indice es  1008h y subindice 0. Para  un equipo "CanOpen-Compliant", este registro corresponde al nombre del nodo.

Comando linux:
Ejemplo de paquete:

Queremos enviar un SDO desde master, solicitando al slave ID 2, el registro cuyo indice es  1008h y subindice 0. Para  un equipo "CanOpen-Compliant", este registro corresponde al nombre del nodo.

Comando linux:

$ cansend can0 602#4008100000000000

 602 = Cob ID 600 + Id nodo 2 = 602

(Mas avanzado el tema explico como se arma el comando)

$ cansend can0 602#4008100000000000

 602 = Cob ID 600 + Id nodo 2 = 602

(Mas avanzado el tema explico como se arma el comando)

 
 ENTRADA EN DESARROLLO.

DEJA TU COMENTARIO PARA SEGUIR EL DESARROLLO DE LOS SIGUIENTES TEMAS:

 
*- Configuracion inicial del CFW500 (conexiones del plug-in, parametrización)
*- Comunicando con el CFW500.
*- Modificando parámetros con SDO. 
*- Modificando diccionario de objetos.
*- Control por PDO. 

*-Finalizando.


Fuentes:

https://www.canopensolutions.com/english/about_canopen/about_canopen.shtml


https://elinux.org/Bringing_CAN_interface_up

https://en.wikipedia.org/wiki/CANopen

https://www.csselectronics.com/screen/page/canopen-tutorial-simple-intro/language/en