Weird serial values

I donwloaded the code for the knock sensor with the piezo sensor. I wanted to change the code a little bit so as to be able not only to have a "knock!" string report but to retrieve all sampled values of the knock sensor. I managed to do it in Max/MSP with the serial external but the data I'm getting in is quite weird : I declared my variable as an byte (not relevant) but what I get in Max is just three different discrete values. Something like 255, 123 and 0 randomely distributed. And I checked the signal on an oscilloscope and the sensor behave normally. The "bits" (because in fact we could speak about continuous signal anymore) I receive in Max make me wonder if it could be possible that an encoding occurs on the USB line (some kind of Manchester encoding) ? And if so, how is it possible to get the continuous data back ?

Best

Sylvain

Hello sylvain

could you place your code to test...

eric

Well, actually I just tried to adapt the example code given on Arduino website ...
I may be missing something.
Here it is :

int knockSensor = 0;
byte val = 0;

void setup() {
pinMode(ledPin, OUTPUT);
beginSerial(9600);
}

void loop() {
val = analogRead(knockSensor);
printByte(val);
// delay(10); // we have to make a delay to avoid overloading the serial port
}

I tried also to declare "val" as an int, because I thought that it was the cause why the values were ranging within 0-255 (instead of 0-1024), but the values are the same even with an int. I skipped the delay as it was not apparently overloading the seial port.
At first, I tried the strict code of "Knock sensor" example and it was working stangely since with the threshold fixed at 100, it was always knocking (even at rest, without knocking the sensor ...) and if I tried to give an upper threshold (250 for example), it was not knocking at all anymore (rest or not)

Hope I missed something

Sylvain

Hi!

I was having problems with this just yesterday...

If you want to print on your serial monitor the binary representation of a byte, the only way I managet to do this is by storing in an int the decimal value on the byte and the call printBinary. This is, for example:

int val = 65;

printBinary (val);

What you will get on your serial monitor is then: 1000001

Since we are at it, if I want to work with an array of bytes, which function can I use to display on my serial monitor the contents of this array?

I tried something like:

byte testArray [3] = {0xff, 0x15, 0x18};

printByte (testArray [0]);

And printed a weir square character on my serial monitor.

I have tried all the print functions, and none work.

I also tried to force a cast

printBinary ( (int) testArray [0]);

And it doesn't seem to work either...

I was so desperate yesterday that I started writing a function to convert a byte into a decimal int, but I am having problems dealing with the masks.... UFF!

Could somebody give me a clue of what I am doing wrong? I am sure that it will be a silly and obvious thing...

Thanx a lot!

Cristina

Hi,

thanks Cristina for this remark, I was quite silly not to notice that.
But, actually it does not explain why the values are bounded within 0-255 instead of the 0-1024 specification.
More, even if I am able to retrieve the bits one by one, and that I can do a 8 bits conversion to an int, Arduino does not tell me where the number starts and ends, so as to say that I am not sure to convert the right numbers.
I guess there are no start/stop bits flags, are they ?

Sylvain

printByte() always sends a single byte over the serial port. A byte (8 bits) can only hold values between 0 and 255.

If you want to send a value from the analog input as a single byte, just divide it by 4 first:

printByte(analogRead(0) / 4);

If you'd rather send it as a sequence of digits, e.g. '1', '0', '2', '3', use printInteger:

printInteger(analogRead(0));

To display an array of bytes, you can use a loop. For example, to send a byte for each byte in the array:

int i;
for (i = 0; i < 3; i++)
  printByte(testArray[i]);

To display the digits in the decimal representation of each byte, use printInteger:

int i;
for (i = 0; i < 3; i++) {
  printInteger(testArray[i]);
  printString(" ");
}

Hey dave!

How u doing?

Thanks for the tip, but actually my problem is not how to display an array.

I am working with bytes, and for some reason when I do for instance:

byte b = 00100001;
printByte(b);

I get a weird square in my serial monitor.

I have managed to solve this by writing a function binary2decimal() that i just posted, and that way I can print doing

printBinary (binary2decimal(b));

A second question I had regards casting.

Can we force castings in arduino? For instance:

byte b = 0xff;
int i = (int) b;

or

long time = millis();

int truncatedTime = (int) time;
(I am conscious that this last one would truncate the long, and just take the lowes significance byte).

Any insight on these metaphysical questions would be great!

Thanks a lot,

Cristina

Hi,

what I do is as simple as this in Arduino 03 :

void setup() {
beginSerial(19200);
}

void loop() {
printInteger(analogRead(1));
}

And in processing, I run this simple program :

import processing.serial.*;

Serial port;

void setup()
{
size(200, 200);
port = new Serial(this, "/dev/cu.usbserial-4B412", 19200);

void draw()
{
while (port.available() > 0) {
serialEvent(port.read());
}
}

void serialEvent(int serial)
{
println(int(serial));
}

And the problem is that the values I get are bounded between 48 and 52, approximately. Even if I knock the sensor ...
What I expected was to have approwimately zero at rest and decrerasing values when knocking the sensor, what I get on the oscillo actually.

sylvain

The problem with your code is that printing on the serial port is a slow process while the signals coming from the sensor move fast.

try something like this

val = analogRead(1);

if (val > 100) {
printInteger(val);
}

this will read very fast the input and will print only the values that are more than 100... (this is a random number , you need to find the right value for you) this will make your app more responsive.

hope this helps

Cristina, your printByte example has two problems. First:
byte b = 00100001;
assigns to b the value of the octal number 100001 = 8^5 + 1 = 32769. This is because in C, numbers starting with 0 are taken to be octal (numbers starting with 0x are hexadecimal and decimal numbers don't have a prefix). You can't write binary constants in C (and thus Arduino). We are thinking about creating some #define's to let you use short binary constants, like B001000001 or BIN00100001 or ... Any suggestions for the names?

Second, printByte() sends a single byte over the serial port. It doesn't print the ASCII representation of the string of digits of the byte. In this case, it probably sends the byte 1, which isn't a printable ASCII character, hence the weird square you see in the serial monitor. If you want to print the string representation of the digits of the byte, use printInteger() for base 10, printBinary() for binary, etc. You should be able to just do printBinary(b) without needing your binary2decimal routine.

You can indeed use casts in Arduino, just as in C (and similar to Java). If you're going from a smaller data type to a larger one, you don't even need one, e.g.
byte b = 10;
int n = b;

The other way around it's a good idea to use them:
long l = millis();
printInteger((int) l); // though in release 0004, printInteger will take a long.

Hope that helps.