Преобразование массива

ulis
ulis аватар
Offline
Зарегистрирован: 09.03.2011

Прикрутил библиотеку nRF24L01 к своей метеостанции и возник вот такой вопрос

Библиотека для приема и передачи использует массив (TX_PLOAD_WIDTH = 32):

unsigned char rx_buf[TX_PLOAD_WIDTH],

а я значение с датчиков заношу в структуру (ведь программа должна быть понятна даже жене):

struct receiveData
{
  float temp;
  int lux;
  int pressure;
  int wind;
};

Так вот, как на вход некой рутине подать мою структуру, а она вернет то, что нужно библиотеке и наоборот?

Пссс - я начинающий!!!!!!

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

А какое отношение этот массив имеет к этой структуре? Массив - 32 байта, а структура сколько? Как Вы их совмещать собираетесь? Если скажете как, то тогда и разговор будет.

ulis пишет:

Пссс - я начинающий!!!!!!

Ребята, ну прекратие Вы писать эту дебильную фразу! Начинающий Вы или заканчивающий неинтересно никому, кроме Вашего психиатра.

ulis
ulis аватар
Offline
Зарегистрирован: 09.03.2011

ЕвгенийП пишет:

А какое отношение этот массив имеет к этой структуре? Массив - 32 байта, а структура сколько? Как Вы их совмещать собираетесь? Если скажете как, то тогда и разговор будет.

ulis пишет:

Понятно дело, что структура (10 байт) никакого отношенияк массиву не имеет, ибо есть плод моей фантазии, но мне ее (структуру) либо нужно передать, либо значения датчиков как-то засунуть, минуя эту структуру в массив.

Ребята, ну прекратие Вы писать эту дебильную фразу! Начинающий Вы или заканчивающий неинтересно никому, кроме Вашего психиатра.

Так это я просто приколоться хотел, воскресенье же

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Я тоже

ulis
ulis аватар
Offline
Зарегистрирован: 09.03.2011

ЕвгенийП пишет:

Я тоже

Приколоться - это про Псссс, а вопрос по массиву - это серьезно, никаких приколов

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Так ч тоже серьёзно ответил. У Вас массив 32 байта, а структура - 10. Как Вы ихсовмещать собираетесь? Что Вам нужно-то? Объясните толком. Вы хотите данные из начала (или из какого места) массива использовать как структуру? Или Вы хотите скопировать структуру в масси (в какое место)? Или чего Вам надо?

ulis
ulis аватар
Offline
Зарегистрирован: 09.03.2011

ЕвгенийП пишет:

Так ч тоже серьёзно ответил. У Вас массив 32 байта, а структура - 10. Как Вы ихсовмещать собираетесь? Что Вам нужно-то? Объясните толком. Вы хотите данные из начала (или из какого места) массива использовать как структуру? Или Вы хотите скопировать структуру в масси (в какое место)? Или чего Вам надо?

1. Начало моей структуры нужно перенести в начало массива (я думал, что это очевидно)

2. Можно подойти к вопросу и так - имеем структуру в 32 байта, ее нужно преобразовать в массив с таким же размером и наоборот.

Либо еще проще, как передать данные с датчиков, которые возвращают тип float, int, int, int используя  unsigned char _buf[32] ?

wdrakula
wdrakula аватар
Offline
Зарегистрирован: 15.03.2016

гуглим "union"

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016
struct receiveData {
  float temp;
  int lux;
  int pressure;
  int wind;
  receiveData(float a, int b, int c, int d): temp(a), lux(b), pressure(c), wind(d) {};
};
struct receiveData AA[2] = {
  {1.2, 2, 3, 4},
  {1.3, 2, 3, 4}
};
void setup() {


}

void loop() {


}

 

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Ну. есть 100500 способо это сделать. Каждый чем-то удобен, а чем-то нет. Вы же секретничаете, кодов не показываете, хрен Вас разберёт что Вам советовать.

Ну, для начала это Ваш массив или он живёт в библиотеке и она им пользуется? Вы имеете к нему доступ? Можете его переописать? Или это вообще Ващ массив и Вы его сами заводите?

А так-то можно

1. положить их (массив и структуру) друг на друга, используя union. 
2. описать указатель на стурктуру и присвоить ему адрес начала массива

И ещё 100498 способов.

В обоих приведённых вариантах не будет лишнего расхода памяти, массив и структура будут лежать друг на друге и занимать одну и ту же память. И преобразовывать ничего не надо вообще.

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

qwone пишет:

struct receiveData {
  float temp;
  int lux;
  int pressure;
  int wind;
  receiveData(float a, int b, int c, int d): temp(a), lux(b), pressure(c), wind(d) {};
};
struct receiveData AA[2] = {
  {1.2, 2, 3, 4},
  {1.3, 2, 3, 4}
};
void setup() {


}

void loop() {


}

 

Это что было? При чём тут вопрос ТС?

ulis
ulis аватар
Offline
Зарегистрирован: 09.03.2011

qwone пишет:

struct receiveData {
  float temp;
  int lux;
  int pressure;
  int wind;
  receiveData(float a, int b, int c, int d): temp(a), lux(b), pressure(c), wind(d) {};
};
struct receiveData AA[2] = {
  {1.2, 2, 3, 4},
  {1.3, 2, 3, 4}
};
void setup() {


}

void loop() {


}

 

А что значит 6-я строчка, какая-то рекурсия? А зачем мы создаем массив структур? А куда исчез массив unsigned char?

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

ЕвгенийП пишет:

Это что было? При чём тут вопрос ТС?

А вы думаете, что ТС написал внятный вопрос.

ulis
ulis аватар
Offline
Зарегистрирован: 09.03.2011

ЕвгенийП пишет:

Ну. есть 100500 способо это сделать. Каждый чем-то удобен, а чем-то нет. Вы же секретничаете, кодов не показываете, хрен Вас разберёт что Вам советовать.

Ну, для начала это Ваш массив или он живёт в библиотеке и она им пользуется? Вы имеете к нему доступ? Можете его переописать? Или это вообще Ващ массив и Вы его сами заводите?

Да уж какие секреты ... нате

#include "NRF24L01.h"

//***************************************************
#define TX_ADR_WIDTH    5   // 5 unsigned chars TX(RX) address width
#define TX_PLOAD_WIDTH  32  // 32 unsigned chars TX payload

unsigned char TX_ADDRESS[TX_ADR_WIDTH]  = 
{
  0x34,0x43,0x10,0x10,0x01
}; // Define a static TX address

unsigned char rx_buf[TX_PLOAD_WIDTH];
unsigned char tx_buf[TX_PLOAD_WIDTH];


void fnIniNRF()
{
  SPI_DIR = ( CE + SCK + CSN + MOSI);
  SPI_DIR &=~ ( IRQ + MISO);
  SPI_PORT&=~CE;      // chip enable
  SPI_PORT|=CSN;      // Spi disable  
  SPI_PORT&=~SCK;     // Spi clock line init high
}


//***************************************************
void setup() 
{
  fnIniNRF();
  
  //  attachInterrupt(1, _ISR, LOW); // interrupt enable
  Serial.begin(9600);

    /*
  unsigned char status=SPI_Read(STATUS);
  Serial.print("status = ");
  Serial.println(status,HEX);      // There is read the mode’s status register, the default value should be ‘E’  
  Serial.println("*****************RX_Mode start******************************R");
  */
  RX_Mode();                        // set RX mode
}
void loop() 
{
  for(;;)
  {
    unsigned char status = SPI_Read(STATUS);                         // read register STATUS's value
    if(status&RX_DR)                                                 // if receive data ready (TX_DS) interrupt
    {
      SPI_Read_Buf(RD_RX_PLOAD, rx_buf, TX_PLOAD_WIDTH);             // read playload to rx_buf
      SPI_RW_Reg(FLUSH_RX,0);                                        // clear RX_FIFO
      for(int i=0; i<32; i++)
      {
          Serial.print(" ");
          Serial.print(rx_buf[i],HEX);                              // print rx_buf
      }
      Serial.println(" ");
    }
    SPI_RW_Reg(WRITE_REG+STATUS,status);                             // clear RX_DR or TX_DS or MAX_RT interrupt flag
    delay(1000);
  }
}



/**************************************************
 * Function: SPI_RW();
 * 
 * Description:
 * Writes one unsigned char to nRF24L01, and return the unsigned char read
 * from nRF24L01 during write, according to SPI protocol
 **************************************************/
unsigned char SPI_RW(unsigned char Byte)
{
  unsigned char i;
  for(i=0;i<8;i++)                      // output 8-bit
  {
    if(Byte&0x80)
    {
      SPI_PORT |=MOSI;    // output 'unsigned char', MSB to MOSI
    }
    else
    {
      SPI_PORT &=~MOSI;
    }
    SPI_PORT|=SCK;                      // Set SCK high..
    Byte <<= 1;                         // shift next bit into MSB..
    if(SPI_IN & MISO)
    {
      Byte |= 1;                // capture current MISO bit
    }
    SPI_PORT&=~SCK;                     // ..then set SCK low again
  }
  return(Byte);                    // return read unsigned char
}
/**************************************************/

/**************************************************
 * Function: SPI_RW_Reg();
 * 
 * Description:
 * Writes value 'value' to register 'reg'
/**************************************************/
unsigned char SPI_RW_Reg(unsigned char reg, unsigned char value)
{
  unsigned char status;

  SPI_PORT&=~CSN;                   // CSN low, init SPI transaction
  status = SPI_RW(reg);             // select register
  SPI_RW(value);                    // ..and write value to it..
  SPI_PORT|=CSN;                    // CSN high again

  return(status);                   // return nRF24L01 status unsigned char
}
/**************************************************/

/**************************************************
 * Function: SPI_Read();
 * 
 * Description:
 * Read one unsigned char from nRF24L01 register, 'reg'
/**************************************************/
unsigned char SPI_Read(unsigned char reg)
{
  unsigned char reg_val;

  SPI_PORT&=~CSN;                // CSN low, initialize SPI communication...
  SPI_RW(reg);                   // Select register to read from..
  reg_val = SPI_RW(0);           // ..then read register value
  SPI_PORT|=CSN;                 // CSN high, terminate SPI communication

  return(reg_val);               // return register value
}
/**************************************************/

/**************************************************
 * Function: SPI_Read_Buf();
 * 
 * Description:
 * Reads 'unsigned chars' #of unsigned chars from register 'reg'
 * Typically used to read RX payload, Rx/Tx address
/**************************************************/
unsigned char SPI_Read_Buf(unsigned char reg, unsigned char *pBuf, unsigned char bytes)
{
  unsigned char status,i;

  SPI_PORT&=~CSN;                   // Set CSN low, init SPI tranaction
  status = SPI_RW(reg);            // Select register to write to and read status unsigned char

  for(i=0;i<bytes;i++)
  {
    pBuf[i] = SPI_RW(0);    // Perform SPI_RW to read unsigned char from nRF24L01
  }

  SPI_PORT|=CSN;                   // Set CSN high again

  return(status);                  // return nRF24L01 status unsigned char
}
/**************************************************/

/**************************************************
 * Function: SPI_Write_Buf();
 * 
 * Description:
 * Writes contents of buffer '*pBuf' to nRF24L01
 * Typically used to write TX payload, Rx/Tx address
/**************************************************/
unsigned char SPI_Write_Buf(unsigned char reg, unsigned char *pBuf, unsigned char bytes)
{
  unsigned char status,i;

  SPI_PORT&=~CSN;                   // Set CSN low, init SPI tranaction
  status = SPI_RW(reg);             // Select register to write to and read status unsigned char
  for(i=0;i<bytes; i++)             // then write all unsigned char in buffer(*pBuf)
  {
    SPI_RW(*pBuf++);
  }
  SPI_PORT|=CSN;                   // Set CSN high again
  return(status);                  // return nRF24L01 status unsigned char
}
/**************************************************/

/**************************************************
 * Function: RX_Mode();
 * 
 * Description:
 * This function initializes one nRF24L01 device to
 * RX Mode, set RX address, writes RX payload width,
 * select RF channel, datarate & LNA HCURR.
 * After init, CE is toggled high, which means that
 * this device is now ready to receive a datapacket.
/**************************************************/
void RX_Mode(void)
{
  SPI_PORT&=~CE;
  SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, TX_ADDRESS, TX_ADR_WIDTH); // Use the same address on the RX device as the TX device
  SPI_RW_Reg(WRITE_REG + EN_AA, 0x01);      // Enable Auto.Ack:Pipe0
  SPI_RW_Reg(WRITE_REG + EN_RXADDR, 0x01);  // Enable Pipe0
  SPI_RW_Reg(WRITE_REG + RF_CH, 40);        // Select RF channel 40
  SPI_RW_Reg(WRITE_REG + RX_PW_P0, TX_PLOAD_WIDTH); // Select same RX payload width as TX Payload width
  SPI_RW_Reg(WRITE_REG + RF_SETUP, 0x07);   // TX_PWR:0dBm, Datarate:2Mbps, LNA:HCURR
  SPI_RW_Reg(WRITE_REG + CONFIG, 0x0f);     // Set PWR_UP bit, enable CRC(2 unsigned chars) & Prim:RX. RX_DR enabled..
  SPI_PORT|=CE;                             // Set CE pin high to enable RX device
  //  This device is now ready to receive one packet of 16 unsigned chars payload from a TX device sending to address
  //  '3443101001', with auto acknowledgment, retransmit count of 10, RF channel 40 and datarate = 2Mbps.
}
/**************************************************/
// BYTE type definition
#ifndef API_H
#define API_H
//****************************************************
// SPI(nRF24L01) commands
#define READ_REG        0x00  // Define read command to register
#define WRITE_REG       0x20  // Define write command to register
#define RD_RX_PLOAD     0x61  // Define RX payload register address
#define WR_TX_PLOAD     0xA0  // Define TX payload register address
#define FLUSH_TX        0xE1  // Define flush TX register command
#define FLUSH_RX        0xE2  // Define flush RX register command
#define REUSE_TX_PL     0xE3  // Define reuse TX payload register command
#define NOP             0xFF  // Define No Operation, might be used to read status register
//***************************************************
#define RX_DR    0x40
#define TX_DS    0x20
#define MAX_RT   0x10
//***************************************************
// SPI(nRF24L01) registers(addresses)
#define CONFIG          0x00  // 'Config' register address
#define EN_AA           0x01  // 'Enable Auto Acknowledgment' register address
#define EN_RXADDR       0x02  // 'Enabled RX addresses' register address
#define SETUP_AW        0x03  // 'Setup address width' register address
#define SETUP_RETR      0x04  // 'Setup Auto. Retrans' register address
#define RF_CH           0x05  // 'RF channel' register address
#define RF_SETUP        0x06  // 'RF setup' register address
#define STATUS          0x07  // 'Status' register address
#define OBSERVE_TX      0x08  // 'Observe TX' register address
#define CD              0x09  // 'Carrier Detect' register address
#define RX_ADDR_P0      0x0A  // 'RX address pipe0' register address
#define RX_ADDR_P1      0x0B  // 'RX address pipe1' register address
#define RX_ADDR_P2      0x0C  // 'RX address pipe2' register address
#define RX_ADDR_P3      0x0D  // 'RX address pipe3' register address
#define RX_ADDR_P4      0x0E  // 'RX address pipe4' register address
#define RX_ADDR_P5      0x0F  // 'RX address pipe5' register address
#define TX_ADDR         0x10  // 'TX address' register address
#define RX_PW_P0        0x11  // 'RX payload width, pipe0' register address
#define RX_PW_P1        0x12  // 'RX payload width, pipe1' register address
#define RX_PW_P2        0x13  // 'RX payload width, pipe2' register address
#define RX_PW_P3        0x14  // 'RX payload width, pipe3' register address
#define RX_PW_P4        0x15  // 'RX payload width, pipe4' register address
#define RX_PW_P5        0x16  // 'RX payload width, pipe5' register address
#define FIFO_STATUS     0x17  // 'FIFO Status Register' register address

//************************************************
#endif
#ifndef NRF24L01_h
#define NRF24L01_h

#include "API.h"

//*********************************************
#define SPI_PORT PORTB
#define SPI_DIR  DDRB
#define SPI_IN   PINB
//---------------------------------------------
#define TX_ADR_WIDTH    5   
// 5 unsigned chars TX(RX) address width
#define TX_PLOAD_WIDTH  1  
// 20 unsigned chars TX payload
//---------------------------------------------
#define CE       0x01
// CE_BIT:   Digital Input     Chip Enable Activates RX or TX mode
#define SCK      0x04
// SCK BIT:  Digital Input     SPI Clock

#define MISO     0x10
// MISO BIT: Digital Output    SPI Slave Data Output, with tri-state option
#define CSN      0x02
// CSN BIT:  Digital Input     SPI Chip Select
#define MOSI     0x08
// MOSI BIT: Digital Input     SPI Slave Data Input
#define IRQ      0x20
// IRQ BIT:  Digital Output    Maskable interrupt pin
//*********************************************
#endif

 

ulis
ulis аватар
Offline
Зарегистрирован: 09.03.2011

Менять в библиотеке rx_buf или tx_buf естественно не хочется

ulis
ulis аватар
Offline
Зарегистрирован: 09.03.2011

qwone пишет:

А вы думаете, что ТС написал внятный вопрос.

Ну а что непонятно, как передать показания датчиков, используя предопределенный массив библиотеки

ulis
ulis аватар
Offline
Зарегистрирован: 09.03.2011

wdrakula пишет:

гуглим "union"

ок, гуглю

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Ну, Вы блин, даёте, ну хоть бы подрисали где что!

Самый первый файл это Ваш файл или библиотечный? Как я понимаю - Ваш и его менять можно.

Тогда скажите мне внятно: Вам всегда передают именно эту структуру? Если да, то зачем Вы определили как TX_PLOAD_WIDTH как 32, если размер Вашей стуктуры - всего 10? Вам там достаточно 10? Или бывают другие посылки, когда нужно больше? 

 

ulis
ulis аватар
Offline
Зарегистрирован: 09.03.2011

ЕвгенийП пишет:

Ну, Вы блин, даёте, ну хоть бы подрисали где что!

Самый первый файл это Ваш файл или библиотечный? Как я понимаю - Ваш и его менять можно.

Тогда скажите мне внятно: Вам всегда передают именно эту структуру? Если да, то зачем Вы определили как TX_PLOAD_WIDTH как 32, если размер Вашей стуктуры - всего 10? Вам там достаточно 10? Или бывают другие посылки, когда нужно больше? 

 

Ладно, мне тут подсказали использовать union, разбираюсь .... но на ваши вопросы отвечу - все три файла библиотечные, где первый из них идет как пример. Менять размер TX_PLOAD_WIDTH не нужно, т.к. это размер внутреннего буфера NRF24L01.

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Блин, Вы не понимаете вопроса.

Первый файл - пример. Значит, вместо него будет Ваш, так? И массив rx_buf будет определён в Вашем файле, а не в библиотечном. Это так или нет? Ответьте же наконец - где определяется массив rx_buf - в Вашем скетче или в библиотеке?

Если я когда-нибудь получу ответ на этот вопрос (в чём я уже начал сомневаться), то возможно, я скажу Вам как обойтись без юниона и без всего остального.

ulis
ulis аватар
Offline
Зарегистрирован: 09.03.2011

ЕвгенийП пишет:

Первый файл - пример. Значит, вместо него будет Ваш, так? И массив rx_buf будет определён в Вашем файле, а не в библиотечном. Это так или нет? Ответьте же наконец - где определяется массив rx_buf - в Вашем скетче или в библиотеке?

Если я когда-нибудь получу ответ на этот вопрос (в чём я уже начал сомневаться), то возможно, я скажу Вам как обойтись без юниона и без всего остального.

ЕвгенийП - ау .... зачем вы просили меня  тогда показать секретные файлы, если вы их не смотрели? Естественно, массив отпределен в библиотеке .... опа, пардон ... вы хотите сказать, что первый файл, это вообще пример, который используюя два последних .... тогда, как мы видим, массив определен в примере и заполняется функцией SPI_Read_Buf(RD_RX_PLOAD, rx_buf, TX_PLOAD_WIDTH);

Хорошо, согласен, массив определен в примере, но (моя) структура с данными датчиков определена у меня в моей проге ....

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

Скорее вам надо написать 2 функции. 1- перевод числа в буфере в число оформленое структурой 2 - число оформленое структурой в число в буфере.

ulis
ulis аватар
Offline
Зарегистрирован: 09.03.2011

wdrakula пишет:

гуглим "union"

// Объявляем объединение
union _test
{
  unsigned char buf[32];
  struct mrdata
  {
    float temp;
    int lux;
    int presure;
    int wind;
  };
};

// Создаем экземпляр типа _test
union _test rx;
rx.buf[0] = 0;

void setup()
{
}

void loop()
{
}

Ругается на строчку 16 - UnionTest:17: error: 'rx' does not name a type

Чего в супе не хватает?

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016
// Объявляем объединение
union _test
{
  unsigned char buf[32];
  struct mrdata
  {
    float temp;
    int lux;
    int presure;
    int wind;
  };
};

// Создаем экземпляр типа _test
union _test rx;
rx.buf[0] = 0; //<--- отсюда убрать

void setup()
{
rx.buf[0] = 0; //<--- сюда поставить
}

void loop()
{
}

 

ulis
ulis аватар
Offline
Зарегистрирован: 09.03.2011

qwone пишет:

Спасибо, который раз наступаю на эти грабли ... нет строгости, какие-то экземпляры можно создавать вне setup, какие-то нет ....

ulis
ulis аватар
Offline
Зарегистрирован: 09.03.2011

Ну, в общем, вопрос можно закрывать ... union помог .... некрасиво все это, копаться в памяти, то ли дело сишарп, пора дуню переводить на НЕТ