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 ?
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)
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...
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 ?
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.
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.
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.