Go Down

Topic: how to access array via pointer, tunneled through functions? (Read 155 times) previous topic - next topic

_butch_

Hi,

maybe it is quite a dumb  question, but I am experimenting quite a while with it and I don't get the pointer stuff in c++.

Background:
I want to write code for a modular remote control for some rc stuff like cars, robots, whatever.
My target is to make the code modular that I can reuse it in different projects (different input devices (own rc with potis, PS2 Gamepad or with different radios (NRF24L01, HM10 BLE)).
So I want to use the same protocol which should be filled by different hardware and which can be transmitted by different radios.

For the protocol I have written a class called MyRemoteControlProtocolV2.
There I have an array which holds my 16 channels.

I will use RF24 library for sending to NRF24L01 radio.

So I need a way to pass the my protocol value array to the send function. Since I need to be careful with memory usage I thought about using a pointer for passing the value array.

But how do I do it?

Here is my current idea, whcih does not work.


The protocol class (header + ccp)

Code: [Select]

class MyRemoteControlProtocolV2 {
public:



void setChannelValue(uint8_t value, uint8_t channel);

uint8_t * getValueArray();

MyRemoteControlProtocolV2();
virtual ~MyRemoteControlProtocolV2();


private:
void updateCRC();
uint8_t values[PROT_ARRAY_LENGTH+1];
FastCRC8 CRC8; // CRC Object



};


Code: [Select]
#include "MyRemoteControlProtocolV2.h"


MyRemoteControlProtocolV2::MyRemoteControlProtocolV2() {
// initialize values array
memset(values, 0, sizeof (values));


}

MyRemoteControlProtocolV2::~MyRemoteControlProtocolV2() {
// TODO Auto-generated destructor stub
}


/**
 * updates the CRC byte
 */
void MyRemoteControlProtocolV2::updateCRC()
{
Log.trace(F("in MyRemoteControlProtocolV2::updateCRC\n"));

// calculate crc. values[sizeof (values) is CRC-Flag, so DO NOT CALCULATE FOR THIS ENTRY!)
uint8_t myCRC = CRC8.smbus(values, sizeof(values-1));

Log.trace(F("  calculated CRC: %X\n"), myCRC);

// update CRC element in values
values[sizeof (values)] = myCRC;

Log.trace(F("  complete values: "));
for (int i=0; i< sizeof (values); i++)
{
if (i==sizeof (values)-1)
{
Log.trace("%x\n",values[i]);
}
else
{
Log.trace("%x ",values[i]);
}
}

Log.trace(F("end of MyRemoteControlProtocolV2::updateCRC\n"));
}

/**
 * sets / updates a value for a specific channel
 */
void MyRemoteControlProtocolV2::setChannelValue(uint8_t value, uint8_t channel)
{
Log.trace(F("in MyRemoteControlProtocolV2::setChannelValue\n"));

// first check if we are in bounds
if ((signed int)channel < 0 || (signed int)channel > (int) (sizeof (values)-1)) // last value[sizeof(value)] is crc byte which cannot be set
{
// out of bounds
Log.error(F("  channel is out of bounds. Channel requested: %d, available Channels: %d to %d\n"), channel, 0, (sizeof(values)-1));
}
else
{
// in bounds, so process it -> update the channel
Log.trace (F("  setting value %X to channel %d\n"), value, channel);
values[channel]=value;
}

Log.trace(F("end of MyRemoteControlProtocolV2::setChannelValue\n"));
}

/**
 * updates crc and then returns a pointer to array values (contains channels + crc)
 */
uint8_t * MyRemoteControlProtocolV2::getValueArray()
{
updateCRC();
return values;
}



In my .ino file I have following code fragment:

Code: [Select]
/**

MyRemoteControlProtocolV2 rcProtocol;


/**
 * sends the data, based on the selected Interface
 */
void mySend(unsigned char dataToSend[], unsigned char dataLenth, unsigned char radioInterface)
{
char function[]="mySend";
if (millis() - (unsigned long) MIN_SEND_INTERVAL_MS > lastSendTime)
{
// need to send data
#if COMPILE_RADIO_INTERFACE_NRF24L01
if (radioInterface == RADIO_INTERFACE_NRF24L01)
{
#if LOGING_RADIO_SENDING == 1
Log.notice(F("%l - %s - snd NRF24L01: %X size %d" CR), millis(), function,  &dataToSend, dataLenth );
#endif
Log.notice(F("sending\n"));

// trying to debug the array
for (int i=0; i<PROT_ARRAY_LENGTH;i++)
{
Serial.print((int) &dataToSend[i]);
Serial.print(" ");
}

nrf24l01Radio.write(&dataToSend, dataLenth);
lastSendTime=millis();
}
#endif
}
else
{
// no sending yet
#if LOGING_RADIO_SENDING == 1
Log.notice(F("%l - %s - not sending now" CR), millis(), function);
#endif
}

void loop() {

Log.notice(F("reading stick\n"));
// read input of analog sticks
rcProtocol.setChannelValue(sticks[STICK_LEFT].getAxis(AXIS_X)->applyAll(getAnalogValue255(STICK_LX_PIN)), PROT_STICK_LX);
rcProtocol.setChannelValue(sticks[STICK_LEFT].getAxis(AXIS_Y)->applyAll(getAnalogValue255(STICK_LY_PIN)), PROT_STICK_LY);
rcProtocol.setChannelValue(sticks[STICK_RIGHT].getAxis(AXIS_X)->applyAll(getAnalogValue255(STICK_RX_PIN)), PROT_STICK_RX);
rcProtocol.setChannelValue(sticks[STICK_RIGHT].getAxis(AXIS_Y)->applyAll(getAnalogValue255(STICK_RY_PIN)), PROT_STICK_RY);




mySend(rcProtocol.getValueArray(), PROT_ARRAY_LENGTH, seletedRadio);




Serial is writing this fragment:

Code: [Select]
:
T: in MyRemoteControlProtocolV2::updateCRC
   calculated CRC: 0xFD
T:   complete values: T: 7E T: 80 T: 6E T: 5F T: 0 T: 0 T: 0 T: 0 T: 0 T: 0 T: 0 T: 0 T: 0 T: 0 T: 0 T: 0 T: 0 T: 0
T: end of MyRemoteControlProtocolV2::updateCRC
N: 217 - mySend - snd NRF24L01: 0x8FA size 17
N: sending
217 218 219 21A 21B 21C 21D 21E 21F 220 221 222 223 224 225 226 227 


So I expected to see the following in the last line:
7E 80 6E 5F 0 0 0 0 ...
but I think these 217 218 ... are just memory addresses and not the value of this address?


Could you please explain me, how I can access the values from in function mySend?



arduino_new

Code: [Select]

// update CRC element in values
values[sizeof (values)] = myCRC;


index is out of bound

_butch_

Code: [Select]

// update CRC element in values
 values[sizeof (values)] = myCRC;


index is out of bound
thanks, fixed that.

Code: [Select]

// update CRC element in values
values[(sizeof (values))-1] = myCRC;


But problem stays the same. just another address. I think something with my try to use pointers is really wrong
Code: [Select]

T: end of MyRemoteControlProtocolV2::setChannelValue
T: in MyRemoteControlProtocolV2::updateCRC
T:   calculated CRC: 0xFD
T:   complete values: T: 7E T: 80 T: 73 T: 68 T: 0 T: 0 T: 0 T: 0 T: 0 T: 0 T: 0 T: 0 T: 0 T: 0 T: 0 T: 0 T: 0 T: FD
T: end of MyRemoteControlProtocolV2::updateCRC
N: 217 - mySend - snd NRF24L01: 0x8FA size 17
N: sending
217 218 219 21A 21B 21C 21D 21E 21F 220 221 222 223 224 225 226 227

jremington

This:
Code: [Select]
Serial.print((int) &dataToSend[i]);
prints the address of each element in memory. Is that what you intended?

_butch_

This:
Code: [Select]
Serial.print((int) &dataToSend[i]);
prints the address of each element in memory. Is that what you intended?
This:
Code: [Select]
Serial.print((int) &dataToSend[i]);
prints the address of each element in memory. Is that what you intended?
And how do I modify it to get the value of the address?

jremington

The value AT the address is
Code: [Select]
Serial.print(dataToSend[i]);

Or
Code: [Select]
Serial.print(dataToSend[i],HEX); //to use hex representation


Go Up