i have three nodemcu and I want to send a struct over nRF24l01+ , but my struct size is 52 byte and the nRf24l01+ module is just sending 32 byte !
how should I send my struct ?
my struct :
struct fullData{
unsigned long ttime;
String data1;
String data2;
String data3;
String data4;
}sndData,recData;
I tried this way but it dosen't work :
transmitter code:
void sendOverRadio(){
char data[sizeof(sndData)];
memcpy(data, &sndData, sizeof(sndData));
radio.stopListening();
int z = 0;
for(int i= 0 ; i<2 ; i++){
char dt[32];
dt[0] = i;
for(int j =1 ; j<32;j++){
dt[j]=data[z];
z +=1;
}
radio.write(&dt , sizeof(dt));
}
radio.startListening();
}
receiver code :
char data[sizeof(recData)];
void loop(){
if(radio.available()){
Serial.println("Radio Available...");
char dt[32];
while (radio.available()){
radio.read(&dt, sizeof(dt));
}
if(dt[0]==0){
memset(data, 0, sizeof(data));
memcpy(data, &dt[1], 32);
}else if(dt[0]==1){
memcpy(&data[32], &dt[1], 32);
memcpy(&recData, data, sizeof(recData));
}
}
}
RF24Network library handles payload splitting. Send your struct like this:
RF24NetworkHeader header(0, 'D');
if (!NETWORK.write(header, &sndData, sizeof(sndData))) {
Serial.println(F("Error."));
} else {
Serial.println(F("Success."));
}
Related
I am interfacing A7672S 4G module with ESP32-C3-DevKitC-02 over Uart0
The problem i am facing is for any AT command published,i am getting lot of junk data
I have tried publising AT to the same 4G module using arduino ,i am able to get the correct response only with this ESP module i am seeing such issues
void uart_init(void)
{
const uart_config_t uart_config = {
.baud_rate = 115200,
.data_bits = UART_DATA_8_BITS,
.parity = UART_PARITY_DISABLE,
.stop_bits = UART_STOP_BITS_1,
.flow_ctrl = UART_HW_FLOWCTRL_DISABLE,
.source_clk = UART_SCLK_DEFAULT,
};
// We won't use a buffer for sending data.
uart_driver_install(UART_NUM_0, RX_BUF_SIZE * 2, 0, 0, NULL, 0);
uart_param_config(UART_NUM_0, &uart_config);
uart_set_pin(UART_NUM_0, TXD_PIN, RXD_PIN, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE);
}
#define RX_BUF_SIZE 1024
int sendData( const char *data)
{
static const char *TX_TASK_TAG = "TX_TASK";
esp_log_level_set(TX_TASK_TAG, ESP_LOG_VERBOSE);
const int len = strlen(data);
const int txBytes = uart_write_bytes(UART_NUM_0, data, len);
ESP_LOGI(TX_TASK_TAG, "Wrote %d bytes", txBytes);
return txBytes;
}
static uint8_t receiveData(uint8_t *data,unsigned int delay_ms)
{
uint8_t rxBytes = 0;
static const char *RX_TASK_TAG = "RX_TASK";
esp_log_level_set(RX_TASK_TAG, ESP_LOG_VERBOSE);
rxBytes = uart_read_bytes(UART_NUM_0, data,RX_BUF_SIZE, delay_ms / portTICK_PERIOD_MS);
data[rxBytes]='\0';
ESP_LOGI(RX_TASK_TAG, "Received %d bytes:\nRxData:%s\n", rxBytes,data);
return rxBytes;
}
uint8_t *data = (uint8_t *)malloc(RX_BUF_SIZE + 1);
uint8_t len=0;
static const char *MAIN_TAG = "MAIN_FUNCTION";
esp_log_level_set(MAIN_TAG, ESP_LOG_VERBOSE);
memset(data, 0, RX_BUF_SIZE + 1);
uart_init();
vTaskDelay(20);
uart_flush(UART_NUM_0);
sendData("AT+CGMI\r\n");
len = receiveData(data,2000);
if(OK == check_response(data,(unsigned char*)"OK"))
{
ESP_LOGI(MAIN_TAG,"Incorporated AT Response Received");
}
else
{
ESP_LOGI(MAIN_TAG,"AT Response Not Received");
}
I'm trying to use the esp-idf standard SPI management functions instead of custom ones.
The custom functions are:
// the initialization of the gpio:
void _spi_init(pn532_t *obj, uint8_t clk, uint8_t miso, uint8_t mosi, uint8_t ss)
{
obj->_clk = clk;
obj->_miso = miso;
obj->_mosi = mosi;
obj->_ss = ss;
gpio_pad_select_gpio(obj->_clk);
gpio_pad_select_gpio(obj->_miso);
gpio_pad_select_gpio(obj->_mosi);
gpio_pad_select_gpio(obj->_ss);
gpio_set_direction(obj->_ss, GPIO_MODE_OUTPUT);
gpio_set_level(obj->_ss, 1);
gpio_set_direction(obj->_clk, GPIO_MODE_OUTPUT);
gpio_set_direction(obj->_mosi, GPIO_MODE_OUTPUT);
gpio_set_direction(obj->_miso, GPIO_MODE_INPUT);
}
// read and write to SPI
uint8_t _spi_read(pn532_t *obj)
{
int8_t i, x;
x = 0;
gpio_set_level(obj->_clk, 1);
for (i = 0; i < 8; i++)
{
if (gpio_get_level(obj->_miso))
{
x |= _BV(i);
}
gpio_set_level(obj->_clk, 0);
gpio_set_level(obj->_clk, 1);
}
return x;
}
void _spi_write(pn532_t *obj, uint8_t c)
{
int8_t i;
gpio_set_level(obj->_clk, 1);
for (i = 0; i < 8; i++)
{
gpio_set_level(obj->_clk, 0);
if (c & _BV(i))
{
gpio_set_level(obj->_mosi, 1);
}
else
{
gpio_set_level(obj->_mosi, 0);
}
gpio_set_level(obj->_clk, 1);
}
}
My refactoring currently is only for these 3 functions:
void _spi_init(pn532_t *obj, spi_host_device_t spiHostDevice, uint8_t ss) {
// the spi_bus_initialize is already initialized in the main function.
gpio_set_direction((gpio_num_t) ss, GPIO_MODE_OUTPUT);
gpio_set_level((gpio_num_t) ss, 1);
//Config Frequency and SS GPIO
spi_device_interface_config_t deviceInterfaceConfig = {
.mode = 0, //SPI mode 0
.clock_speed_hz= 1200000, // Usually 1.2 Mhz
.input_delay_ns = 0,
.spics_io_num = ss,
.flags = SPI_DEVICE_BIT_LSBFIRST, // the device use LSB
.queue_size = 1
};
spi_device_handle_t spiDeviceHandle;
//Attach the pn532 to the SPI bus
ESP_ERROR_CHECK(spi_bus_add_device(spiHostDevice, &deviceInterfaceConfig, &spiDeviceHandle));
obj->spi = spiDeviceHandle;
}
void _spi_write(pn532_t *obj, uint8_t data) {
spi_transaction_t t;
memset(&t, 0, sizeof(t)); //Zero out the transaction
t.length = 8;
t.tx_buffer = &data;
ESP_LOGI(TAG, "send data: 0b%s", toBinary(data,8));
ESP_ERROR_CHECK(spi_device_polling_transmit(obj->spi, &t));
}
uint8_t _spi_read(pn532_t *obj) {
uint8_t data = 1;
spi_transaction_t t;
memset(&t, 0, sizeof(t)); //Zero out the transaction
t.length = 8;
t.rxlength = 8;
t.tx_buffer = NULL;
t.rx_buffer = &data;
ESP_ERROR_CHECK(spi_device_polling_transmit(obj->spi, &t));
ESP_LOGI(TAG, "read data: 0b%s", toBinary(data,8));
return data;
}
Currently, this rewrite is not working. I already did a lot of tries with any combination of config that makes sense, without success.
Practically, when I ask the device to give me the status, I'm expecting one byte in response, in form of 0x00 or 0x01. But I'm receiving 0x08. So still one bit up, but in the wrong position.
So I think I'm still missing some configuration on my rewrite.
Apprising any hit or test that I can do in order to found what is missing!
Thanks!
I've created an array of structs but I'm getting the error written on the title of this question. I'm still new to this so I was wondering if I could get some help.
Code:
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
lcd.begin(16, 2);
i = 0;
}
#define LIMIT 27
struct protocol {
char create[16];
char character;
int values;
int minimum;
int maximum;
};
struct protocol channels[LIMIT];
int i;
void create_channels() {
if (Serial.available() > 0) {
Serial.print("Enter the channel description");
channels[i].create = Serial.read();
Serial.print("Enter the starting character: ");
channels[i].character = Serial.read();
if (i == LIMIT) {
for (i = 0; i < LIMIT; i++)
{
Serial.println(channels[i].create);
Serial.println(channels[i].character);
}
i = 0;
}
}
}
Error:
cw.ino:24:38: error: incompatible types in assignment of 'int' to 'char [16]'
channels[i].create = Serial.read();
In linux kernel if we have a pointer to "struct gendisk" of a disk, then how can we read a known sector number from the disk.
These functions helped me. I used submit_bio and submitted a bio to the disk. The major and minor shall be assumed as input to read_sector_thread_func
static struct bio * my_mpage_alloc(struct block_device *bdev,
sector_t first_sector, int nr_vecs,
gfp_t gfp_flags)
{
struct bio *bio;
bio = my_bio_alloc(gfp_flags, nr_vecs);
if (bio == NULL && (current->flags & PF_MEMALLOC)) {
while (!bio && (nr_vecs /= 2))
bio = my_bio_alloc(gfp_flags, nr_vecs);
}
if (bio) {
//bio->bi_bdev = bdev;
bio->bi_iter.bi_sector = first_sector;
}
return bio;
}
static void src_endio(struct bio *bio)
{
if (bio->bi_private) {
complete(bio->bi_private);
}
return;
}
static int read_sector_thread_func(void *data)
{
struct block_device *r_bdev = NULL;
struct bio *r_bio = NULL;
struct page *page = NULL;
int part = NULL;
int len = 0;
struct gendisk * disk = NULL;
unsigned char * addr;
u64 first_sector_num = 0;
disk = get_gendisk(MKDEV(global_dev_major, global_dev_minor), &part);
DECLARE_COMPLETION_ONSTACK(r_wait);
page = alloc_pages(GFP_ATOMIC, 0);
printk("%d : %s ", __LINE__, __func__);
r_bio = my_mpage_alloc(r_bdev, first_sector_num, 1, GFP_ATOMIC);
if(r_bio==NULL)
{
printk("bio is NULL");
return;
}
bio_add_page(r_bio, page, 512, 0);
r_bio->bi_private = &r_wait;
r_bio->bi_end_io = src_endio;
r_bio->bi_disk = disk;
bio_associate_blkg(r_bio);
bio_get(r_bio);
bio_set_op_attrs(r_bio, REQ_OP_READ, 0);
submit_bio(r_bio);
wait_for_completion_io(&r_wait);
bio_put(r_bio);
return 0;
}
I have a problem with an ATmega8 and Mifare RC-522 based NFC/RFID controller.
I'm using this library and I've managed to read the UID of a card.
However, I'd like to also read and write other parts of the card but whenever I try to use the MFRC522_Auth function I don't get the idle interrupt which I should, instead it gives me LoAlertIrq saying that FIFObuffer is almost empty.
Here are the docs for the reader and the card, and below are relevant parts of my code.
main.c :
byte = mfrc522_request(PICC_REQALL,str);
if(byte == CARD_FOUND)
{
byte = mfrc522_get_card_serial(str);
if(byte == CARD_FOUND)
{
byte = mfrc522_auth(PICC_AUTHENT1A, 7, sectorKeyA, str);
if( (byte == CARD_FOUND) )
{
byte = MFRC522_Read1(4, str);
if(byte == CARD_FOUND)
{
//write content of that block
}
}
}
Relevant functions from the library :
void mfrc522_write(uint8_t reg, uint8_t data)
{
ENABLE_CHIP();
spi_transmit((reg<<1)&0x7E);
spi_transmit(data);
DISABLE_CHIP();
}
uint8_t mfrc522_read(uint8_t reg)
{
uint8_t data;
ENABLE_CHIP();
spi_transmit(((reg<<1)&0x7E)|0x80);
data = spi_transmit(0x00);
DISABLE_CHIP();
return data;
}
uint8_t mfrc522_to_card(uint8_t cmd, uint8_t *send_data, uint8_t send_data_len, uint8_t *back_data, uint32_t *back_data_len)
{
uint8_t status = 0;
uint8_t irqEn = 0x00;
uint8_t waitIRq = 0x00;
uint8_t lastBits;
uint8_t n;
uint8_t tmp;
uint32_t i;
switch (cmd)
{
case MFAuthent_CMD: //Certification cards close
{
irqEn = 0x12;
waitIRq = 0x10;
break;
}
case Transceive_CMD: //Transmit FIFO data
{
irqEn = 0x77;
waitIRq = 0x30;
break;
}
default:
break;
}
mfrc522_write(ComIEnReg, irqEn|0x80); //Interrupt request
n=mfrc522_read(ComIrqReg);
mfrc522_write(ComIrqReg,n&(~0x80));//clear all interrupt bits
n=mfrc522_read(FIFOLevelReg);
mfrc522_write(FIFOLevelReg,n|0x80);//flush FIFO data
// mfrc522_write(CommandReg, Idle_CMD); //NO action; Cancel the current cmd???
n=mfrc522_read(CommandReg);
mfrc522_write(CommandReg,n|0x00);
//Writing data to the FIFO
for (i=0; i<send_data_len; i++)
{
mfrc522_write(FIFODataReg, send_data[i]);
}
//Execute the cmd
mfrc522_write(CommandReg, cmd);
if (cmd == Transceive_CMD)
{
n=mfrc522_read(BitFramingReg);
mfrc522_write(BitFramingReg,n|0x80);
}
//Waiting to receive data to complete
i = 2000; //i according to the clock frequency adjustment, the operator M1 card maximum waiting time 25ms???
while (1) {
n = mfrc522_read(ComIrqReg); // ComIrqReg[7..0] bits are: Set1 TxIRq RxIRq IdleIRq HiAlertIRq LoAlertIRq ErrIRq TimerIRq
if (n & waitIRq) { // One of the interrupts that signal success has been set.
break;
}
if (n & 0x01) { // Timer interrupt - nothing received in 25ms
// return 6; //debug purpose
if (cmd == MFAuthent_CMD) {
LCD_Clear();
LCD_WriteTextXY(1, 3, LCD_itoa( mfrc522_read(ComIrqReg) ) );
_delay_ms(2500);
}
break;
}
if (--i == 0) { // The emergency break. If all other condions fail we will eventually terminate on this one after 35.7ms. Communication with the MFRC522 might be down.
if (cmd == MFAuthent_CMD) {
LCD_Clear();
LCD_WriteTextXY(1, 3, LCD_itoa( mfrc522_read(ComIrqReg) ) );
_delay_ms(2500);
}
break;
}
}
tmp=mfrc522_read(BitFramingReg);
mfrc522_write(BitFramingReg,tmp&(~0x80));
if (i != 0)
{
if(!(mfrc522_read(ErrorReg) & 0x1B)) //BufferOvfl Collerr CRCErr ProtecolErr
{
status = CARD_FOUND;
if (n & irqEn & 0x01)
{
status = CARD_NOT_FOUND; //??
}
if (cmd == Transceive_CMD)
{
n = mfrc522_read(FIFOLevelReg);
lastBits = mfrc522_read(ControlReg) & 0x07;
if (lastBits)
{
*back_data_len = (n-1)*8 + lastBits;
}
else
{
*back_data_len = n*8;
}
if (n == 0)
{
n = 1;
}
if (n > MAX_LEN)
{
n = MAX_LEN;
}
//Reading the received data in FIFO
for (i=0; i<n; i++)
{
back_data[i] = mfrc522_read(FIFODataReg);
}
}
}
if (cmd == MFAuthent_CMD) {
LCD_WriteTextXY(1, 10, LCD_itoa16( mfrc522_read(Status2Reg) ) );
_delay_ms(2500);
}
} else status = 9;
return status;
}
uint8_t mfrc522_get_card_serial(uint8_t * serial_out)
{
uint8_t status;
uint8_t i;
uint8_t serNumCheck=0;
uint32_t unLen;
mfrc522_write(BitFramingReg, 0x00); //TxLastBists = BitFramingReg[2..0]
serial_out[0] = PICC_ANTICOLL;
serial_out[1] = 0x20;
status = mfrc522_to_card(Transceive_CMD, serial_out, 2, serial_out, &unLen);
if (status == CARD_FOUND)
{
//Check card serial number
for (i=0; i<4; i++)
{
serNumCheck ^= serial_out[i];
}
if (serNumCheck != serial_out[i])
{
status = ERROR;
}
}
return status;
}
uint8_t mfrc522_auth(uint8_t authMode, uint8_t BlockAddr, uint8_t *Sectorkey, uint8_t *serNum)
{
uint8_t status;
uint32_t recvBits;
uint8_t i;
uint8_t buff[12];
// Validate instruction block address + sector + password + card serial number
buff[0] = authMode;
buff[1] = BlockAddr;
for (i=0; i<6; i++)
{
buff[i+2] = 0xFF /**(Sectorkey+i)*/;
}
for (i=0; i<4; i++)
{
buff[i+8] = *(serNum+i);
}
status = mfrc522_to_card(MFAuthent_CMD, buff, 12, buff, &recvBits);
return status;
}
uint8_t MFRC522_Read1(uint8_t blockAddr, uint8_t *recvData)
{
uint8_t status = 0;
uint8_t unLen, efa;
recvData[0] = PICC_READ;
recvData[1] = blockAddr;
CalculateCRC(recvData, 2, &recvData);
status = mfrc522_to_card(Transceive_CMD, recvData, 4, recvData, &unLen);
if ((status != CARD_FOUND)|| (unLen != 0x90))
{
status = ERROR;
}
return status;
}
uint8_t CalculateCRC(uint8_t *pIndata, uint8_t len, uint8_t *pOutData)
{
uint8_t i, n;
uint8_t status = 0;
n = mfrc522_read(DivIrqReg);
mfrc522_write(DivIrqReg,n&(~0x04)); //CRCIrq = 0
n = mfrc522_read(FIFOLevelReg); //FIFO
mfrc522_write(FIFOLevelReg, n|0x80);
//Write_MFRC522(CommandReg, PCD_IDLE);
// Write data to the FIFO
for (i=0; i<len; i++)
{
mfrc522_write(FIFODataReg, *(pIndata+i));
}
mfrc522_write(CommandReg, CalcCRC_CMD);
// Read the CRC calculation result
i = 0xFF;
while(1){
n = mfrc522_read(DivIrqReg);
if (n & 0x04) {
break;
}
if (--i != 0) {
return 7;
}
}
// Read the CRC calculation result
pOutData[3] = mfrc522_read(CRCResultReg_2);
pOutData[4] = mfrc522_read(CRCResultReg_1);
return status = 0;
}