passing char array into function

Alright, I've read, and read. Looked at tutorials and examples, and read more. And I'm still not doing this right. I'm tired of reading :frowning:

uint8_t arr[10] = {3,6,1,2,3,8,4,1,7,2};
void setup()
{
Serial.begin(9600);
}

void loop()
{
dostuff(arr, 10*sizeof(uint8_t));
}
}

void dostuff(uint8_t *a, int BUF)
{
Serial.write(uint8_t *a, BUF);
/more stuff/
//memset(a, 0, 10sizeof(int));
}

Thanks for the help.

Try this:
uint8_t arr[10] = {3,6,1,2,3,8,4,1,7,2};
void setup()
{
Serial.begin(9600);
}

void loop()
{
dostuff(arr, 10* sizeof(uint8_t)); // the name of an array points to the array & you are passing 10 values

}

void dostuff(uint8_t *a, int BUF)
{
Serial.write(a, BUF); // Serial.write wants the array pointer and the number of elements
/more stuff/
//memset(a, 0, 10sizeof(int));
}

Thank you! That seemed to work. Why don't I need a '*' on that last a?

The pointer "a" in your example points to a buffer of bytes. And the serial.Write needs that pointer (the address). If you put a * there (ie. *a) then you dereference the start of the buffer, giving the single number 3 (the first element).

As for this:

  dostuff(arr, 10* sizeof(uint8_t)); // the name of an array points to the array & you are passing 10 values

You are letting the compiler work out how long a uint8_t is (ie. 1) but you are manually counting up to 10. Why not let the compiler do that?

  dostuff(arr, sizeof arr); // the array and its size

[quote author=Nick Gammon link=topic=70831.msg526790#msg526790 date=1314690435]
The pointer "a" in your example points to a buffer of bytes. And the serial.Write needs that pointer (the address). If you put a * there (ie. *a) then you dereference the start of the buffer, giving the single number 3 (the first element).[/quote]
Blurgh, so let me get this straight. *a is the value at the address. and a is the address? *a in serial.write would mean a pointer to the value at the address of the array, which is equivalent to the first element of an array? I think that makes sense. When I was writing the code, I am pretty sure I had those two concepts swapped. I'm going to have to use pointers more, and re-read that tutorial again to fully understand it I think.

Hmmm.....yes....that would make much more sense wouldnt it. :smiley:

Well, I made the suggested changes, and the code is doing pretty much what I want. But I am still getting some weirdness:

uint8_t arr[]={0x42,0xFF, 0xFF};
void setup(){
  Serial.begin(9600);
delay(500);
  Serial.write(0x55);
serial_response();
    dostuff(arr, sizeof(arr)); // the name of an array points to the array & you are passing 10 values
    delay(1000);
}

void loop(){
  serial_response();
}

void dostuff(uint8_t *a, int BUF)
{
  Serial.write(a, BUF);  // Serial.write wants the array pointer and the number of elements
  /*more stuff*/
//  memset(a, 0, BUF);
}

void  serial_response(){
 // delay(1);
    int incomingByte=0;
      if (Serial.available() > 0) {
      incomingByte = Serial.read();
        Serial.print("I received: ");
       Serial.println(incomingByte, HEX);
      }
 }

Now, the serial monitor output is this: UBÿÿ

I know where the U and B are coming from, but the "ÿÿ" Idk how or why that is getting printed to the serial monitor. Any suggestions?

Thanks guys.

The y with the 2 dots over it is how the Serial Monitor shows a 0xFF. You should not be Serial.write()ing stuff that the Serial Monitor is to show.

PaulS:
The y with the 2 dots over it is how the Serial Monitor shows a 0xFF.

Oh, arduino uses their own ascii table. That explains a lot.

PaulS:
You should not be Serial.write()ing stuff that the Serial Monitor is to show.

I'd prefer if the monitor didnt show the tx data anyway. Is there another option? I am only aware of Serial.print and Serial.write. Both of which show output on the serial monitor. Serial.write seemed to be best for sending multiple bytes of data, so I chose that over Serial.print. I need to use the serial monitor to see what my target device's handshake response is.

Oh, arduino uses their own ascii table. That explains a lot.

ASCII only goes 0 to 0x7F.

If you want to see non-printable characters, you could use Serial.print (val, HEX);

I need to use the serial monitor to see what my target device's handshake response is.

If the Arduino is on one end of the serial port, and the Serial Monitor is on the other, how does the "target device" get any data? You can't have two devices on one end of the serial port.

PaulS:

I need to use the serial monitor to see what my target device's handshake response is.

If the Arduino is on one end of the serial port, and the Serial Monitor is on the other, how does the "target device" get any data? You can't have two devices on one end of the serial port.

I am pretty sure you can write to both if the two following statements are true:

1.) Both devices are connected to the master in a parallel configuration
2.) Both devices operate from the same set of commands

I understand what you are saying. If you send it to one, it doesn't necessarily go to the other. The only way I know to go around that is to not use the serial monitor, but then I don't know how to determine if commands are failing. Even if I don't open the serial monitor, isnt the IDE still processing the serial monitor data? It's just not displaying it to the screen?

I mean, I should be able to read the serial monitor or troubleshoot somehow. Commands can fail for numerous reasons beyond poor coding including electrical interference, bad or fried hardware,etc.

*a in serial.write would mean a pointer to the value at the address of the array, which is equivalent to the first element of an array? I think that makes sense.

Yes. Once it is dereferenced you don't know the context any more. So if you dereference it (to get 3, say) then you don't know that there is a 6 after it, because it is no longer the "address of 3" it is just 3.

void dostuff(uint8_t *a, int BUF)

{
  Serial.write(a, BUF);  // Serial.write wants the array pointer and the number of elements
}

As a style thing, I wouldn't call it BUF. All-caps identifiers tend to be used for constants (eg. 42). So it's just confusing to other programmers to do that.

In any case it's buffer-length, right? So a better name would be:

void dostuff(byte *buffer, int len)

As for the write - that writes a series of bytes, hence you see the funny characters. To see them individually you need to print them, eg.

void dostuff(byte *buffer, int len)
{
  for (int i = 0; i < len; i++)
    {
    Serial.print(buffer [i], DEC);  // print as decimal number
    Serial.print (" ");  // separating space
    }  // end of for

  Serial.println ();   // finish line off
}

Note that putting the array subscript in brackets dereferences into the i'th array entry.

I should be able to read the serial monitor or troubleshoot somehow.

One approach (apart from getting a logic analyzer which I personally find invaluable) is to use NewSoftSerial and communicate with your device on (say) pins 2 and 3, and then user hardware serial for debugging.

Another thing you can do for debugging is grab a second Arduino and connect the two together using I2C or SPI (2 wires for I2C, 3 for SPI, plus 5V and Gnd). Then dump debugging information out those ports (assuming you don't need them for anything else).

But for around $150 the logic analyzer tells you what is really arriving (not just what your code thinks it is) and what it is really replying (within the limits of the logic analyzer, but that has been pretty-well debugged).

I did a posting on my forum describing how you could connect two Arduinos together. One as the device being tested, the other to receive debug messages via SPI:

Thanks for the suggestions. I will try the software serial option when I get a chance. I'm moving tomorrow.