Tabla de Contenidos
I32CCT
Es una libreria desarrollada por el hackerspace San Salvador y que esta almacenada en https://github.com/hackerspacesv/I32CTT para poder controlar los modulos de comunicacion inalambricas con chips at86rf233 usados en los modulos https://openlabs.co/OSHW/Raspberry-Pi-802.15.4-radio para la raspberrypi.
Los drivers originalente diseñados para los tensy se puede usar en arduino con una advertencia: Tienen tres implementaciones:
- C++ para arduino en la carpeta /tmp/I32CTT/Arduino que ocupa demasiada memoria
- C mas ligero que esta en la carpeta I32CTT/C
- python para usarlo en una raspberrypi
Capas:
- Protocolo I32CTT
- MAC 802.4
- PHY at86rf233
Descripcion del protoccolo
PHY 128 bytes max -HEADER MAC -HEADER y CRC bytes I32CTT - HEADER bytes UI I32CTT unidades entereos
- Registros 32 bits
- cantidad de Registros 65536
- Cantidad de endpoints 255
Función Maestro
Para escribir como maestro
Serial.println("Sending commands"); #En vez de null puedo enviar un puntero para guardar la cantidad maxima de registro i32ctt_reg_pair_t *p_write_cmd_buffer = i32ctt_master_get_write_cmd_buffer(NULL); p_write_cmd_buffer[0].address = 0; p_write_cmd_buffer[0].data = 0x10; p_write_cmd_buffer[1].address = 1; p_write_cmd_buffer[1].data = 0x20;
mac_802154_driver_set_tx_destination_addr(0x0201); #(ENDPOINT CANT_REGISTRO) i32ctt_master_send_write_reg_cmd(1, 2);
Para leer como marestro
Serial.println("Reading commands"); i32ctt_addr_t *p_read_cmd_buffer = i32ctt_master_get_read_cmd_buffer(NULL); p_read_cmd_buffer[0].address = 0; p_read_cmd_buffer[0].address = 1;
mac_802154_driver_set_tx_destination_addr(0x0201);
i32ctt_master_send_read_reg_cmd(1, 2); //Direccion del maestro: TODO: contestar al que hizo la solicitud mac_802154_driver_set_tx_destination_addr(0x0100);
Función Esclavo
Para leer como esclavo
#En vez de null puedo enviar un puntero para guardar la cantidad maxima de registro i32ctt_addr_t *p_read_cmd_buffer = i32ctt_master_get_read_cmd_buffer(NULL); p_read_cmd_buffer[0].address = 0; p_read_cmd_buffer[0].address = 1;
mac_802154_driver_set_tx_destination_addr(0x0201); #(ENDPOINT CANT_REGISTRO) i32ctt_master_send_read_reg_cmd(1, 2); #Luego cuando se ejecuta i32ctt_update(); llama al callback (set_read_callback) de lectura
Para el esclavo
//Crea una estrcutura ep1 endpoint 1 dos callbacks
I32CTT_SLAVE_INSTANCE(ep1, 1, ep1_read_reg_callback, ep1_write_reg_callback); // Registrando a endpoint i32ctt_slave_add_instance(&ep1); //Leer ep1_read_reg_callback() //Escribir ep1_write_reg_callback()
//mac_802154_driver_set_tx_destination_addr(0x0100);
ElPIN del IRQ _SIEMPRE_ debe ser en el #3
Código
#include "src/at86rf233-iodriver-arduino.h" #include "src/at86rf233-driver.h" #include "src/phy-802154-driver.h" #include "src/mac-802154-driver.h" #include "src/at86rf233-iodriver.h" //#include "src/phy-packet-driver.h" //#include "src/mac-packet-driver.h" #include "src/i32ctt-master.h" #include "src/i32ctt-slave.h" const int radio_cs_pin = 10; //AT86RF233 radio (SPI is shared with display) const int radio_rst_pin = 8; const int radio_slp_tr_pin = 9; const int radio_irq_pin = 3; const int display_cs = 10; //Bubble display (SPI is shared with radio) const int sensor_irq_pin = 3; //Laser sensor receiver (LDR + debouncing circuit) //mensajes="Hola"; char mensajes[20] = "000000000000000"; void master_read_callback(const i32ctt_reg_pair_t *reg_pair_array, uint16_t reg_count) { Serial.println("Master read register:"); for (uint16_t i = 0; i < reg_count; i++) { Serial.print("address: "); Serial.print(reg_pair_array[i].address); Serial.print(", data: 0x"); Serial.println(reg_pair_array[i].data, HEX); } } void master_write_callback(const i32ctt_addr_t *reg_addr_array, uint16_t reg_count) { Serial.println("Master write register:"); for (uint16_t i = 0; i < reg_count; i++) { Serial.print("address: "); Serial.println(reg_addr_array[i].address); } } void ep1_read_reg_callback(const i32ctt_addr_t *reg_addr_array, uint16_t reg_count) { int inicial=10; i32ctt_reg_pair_t *p_ans_buffer = i32ctt_slave_get_read_ans_buffer(); uint16_t master_addr = mac_802154_driver_get_rx_source_addr(); Serial.println("Slave read register:"); for (uint16_t i = 0; i < reg_count; i++) { p_ans_buffer[i].address = reg_addr_array[i].address; //p_ans_buffer[i].data = reg_addr_array[i].address + 50; p_ans_buffer[i].data = inicial; Serial.print("address: "); Serial.print(p_ans_buffer[i].address); Serial.print(", data: 0x"); Serial.println(p_ans_buffer[i].data, HEX); inicial=inicial+1; } mac_802154_driver_set_tx_destination_addr(master_addr); i32ctt_slave_send_read_reg_ans(reg_count); } void ep1_write_reg_callback(const i32ctt_reg_pair_t *reg_pair_array, uint16_t reg_count) { i32ctt_addr_t *p_ans_buffer = i32ctt_slave_get_write_ans_buffer(); uint16_t master_addr = mac_802154_driver_get_rx_source_addr(); Serial.println("Slave Write register:"); for (uint16_t i = 0; i < reg_count; i++) { Serial.print("address: "); Serial.print(reg_pair_array[i].address); Serial.print(", data: 0x"); Serial.println(reg_pair_array[i].data, HEX); p_ans_buffer[i].address = reg_pair_array[i].address; } mac_802154_driver_set_tx_destination_addr(master_addr); i32ctt_slave_send_write_reg_ans(reg_count); } //Crea una estrcutura ep1 endpoint 1 dos callbacks, para lectura y escritura de datos I32CTT_SLAVE_INSTANCE(ep1, 1, ep1_read_reg_callback, ep1_write_reg_callback); void sensor_isr() { digitalWrite(led_0_pin, digitalRead(sensor_irq_pin)); } void setup() { Serial.begin(9600); pinMode(led_0_pin, OUTPUT); //pinMode(sensor_irq_pin, INPUT); randomSeed(analogRead(A0)); at86rf233_iodriver_arduino_init(radio_cs_pin, radio_rst_pin, radio_slp_tr_pin, radio_irq_pin); //at86rf233_iodriver_arduino_set_fem_cps_pin(7); at86rf233_driver_init(false); phy_802154_driver_set_channel(26); mac_802154_driver_init(0xCAFE, 0x0201, random(256)); i32ctt_master_set_read_callback(master_read_callback); i32ctt_master_set_write_callback(master_write_callback); i32ctt_slave_add_instance(&ep1); dht.begin(); Serial.println("Listo"); for (int i = 0; i < 6; i++) { digitalWrite(led_0_pin, !digitalRead(led_0_pin)); delay(100); } } void loop() { unsigned long t = millis(); static unsigned long t_last = 0; //attachInterrupt(digitalPinToInterrupt(sensor_irq_pin), sensor_isr, CHANGE); mensajes[0]='0'; mensajes[1]='0'; mensajes[2]='0'; mensajes[3]='0'; mensajes[4]='0'; i32ctt_update(); if (t >= t_last + 1000) { static int cuenta = 0; at86rf233_iodriver.irq_enable(false); //at86rf233_iodriver.irq_enable(true); cuenta++; Serial.println("Iterando"); ////Escritura de maestro //Serial.println("Sending commands"); // //i32ctt_reg_pair_t *p_write_cmd_buffer = i32ctt_master_get_write_cmd_buffer(NULL); //p_write_cmd_buffer[0].address = 0; //p_write_cmd_buffer[0].data = 0x10; //p_write_cmd_buffer[1].address = 1; //p_write_cmd_buffer[1].data = 0x20; //mac_802154_driver_set_tx_destination_addr(0x0100); //i32ctt_master_send_write_reg_cmd(1, 2); ////Lectura maestro //Serial.println("Reading commands"); // i32ctt_addr_t *p_read_cmd_buffer = i32ctt_master_get_read_cmd_buffer(NULL); // p_read_cmd_buffer[0].address = 0; // p_read_cmd_buffer[0].address = 1; // mac_802154_driver_set_tx_destination_addr(0x0201); // i32ctt_master_send_read_reg_cmd(1, 2); //Direccion del maestro: TODO: contestar al que hizo la solicitud //mac_802154_driver_set_tx_destination_addr(0x0100); t_last += 1000; } } /* void mac_driver_test() { static unsigned long t_sig = 1000; const uint8_t paquete[] = { 0x03, 0x01, 0x01, 0x00, 0x78, 0x56, 0x34, 0x12 }; uint8_t *tx_buffer; uint16_t mtu_size; const uint8_t *rx_buffer; uint16_t rx_payload_size; if (millis() >= t_sig) { t_sig += 1000; digitalWrite(led_0_pin, !digitalRead(led_0_pin)); mac_802154_driver_set_tx_destination_addr(0x0201); tx_buffer = mac_packet_driver.get_tx_packet(&mtu_size); memcpy(tx_buffer, paquete, sizeof(paquete)); if (mac_packet_driver.packet_send(sizeof(paquete))) Serial.println("Enviado"); else Serial.println("No enviado"); } at86rf233_iodriver if (!mac_packet_driver.is_packet_available()) return; mac_packet_driver.get_rx_packet(&rx_buffer, &rx_payload_size); for (uint16_t i = 0; i < rx_payload_size; i++) { Serial.print(rx_buffer[i], HEX); Serial.print(" "); } Serial.println(); mac_packet_driver.dismiss_rx_packet(); } */ /* void phy_driver_test() { static unsigned long t_sig = 1000; const uint8_t paquete[] = { 0x03, 0x01, 0x01, 0x00, 0x78, 0x56, 0x34, 0x12 }; uint8_t *tx_buffer; uint16_t mtu_size; const uint8_t *rx_buffer; uint16_t rx_payload_size; if (millis() >= t_sig) { t_sig += 1000; digitalWrite(led_0_pin, !digitalRead(led_0_pin)); tx_buffer = phy_packet_driver.get_tx_packet(&mtu_size); memcpy(tx_buffer, paquete, sizeof(paquete)); if (phy_packet_driver.packet_send(sizeof(paquete))) Serial.println("Enviado"); else Serial.println("No enviado"); } if (!phy_packet_driver.is_packet_available()) return; phy_packet_driver.get_rx_packet(&rx_buffer, &rx_payload_size); for (uint16_t i = 0; i < rx_payload_size; i++) { Serial.print(rx_buffer[i], HEX); } Serial.println(); phy_packet_driver.dismiss_rx_packet(); } */
Pueden descargar el codigo de https://github.com/hackerspacesv/I32CTT/tree/feature/C/i32ctt_implementation O pueden descargar el archivo compreso de: i32ctt.tar.gz.
Nota:
- Los pines que SIEMPRE se deben usar para IRQ en este driver (I32CTT para C) es el 2 o el 3 para el arduino UNO IRQ Arduino
- Se a la hora de compilar el proyecto, el proyecto debe ser guardado en la carpeta
I32CTT/examples
y se debe copiar la carpeta
I32CTT/examples/Arduino_C/src
a la carpeta del proyecto la cual contiene todos los enlaces para la copilacion.
- Para las pruebas se recomienda usar primero la raspberry pi usando el codigo I32CTT/python/i32ctt_master_test.py y el codigo C++