The documentation for Arduino/Genuino 101's CurieBLE library states the following, in the section "Service Design Patterns":
A characteristic value can be up to 20 bytes long. This is a key
constraint in designing services. [...] You could also combine readings into a single characteristic, when a given sensor or actuator has multiple values associated with it.
[e.g. Accelerometer X, Y, Z => 200,133,150]
This is more efficient, but you need to be careful not to exceed the 20-byte limit. The accelerometer characteristic above, for example, takes 11 bytes as a ASCII-encoded string.
However, the typed Characteristic constructors available in the API are limited to the following:
BLEBoolCharacteristic
BLECharCharacteristic
BLEUnsignedCharCharacteristic
BLEShortCharacteristic
BLEUnsignedShortCharacteristic
BLEIntCharacteristic
BLEUnsignedIntCharacteristic
BLELongCharacteristic
BLEUnsignedLongCharacteristic
BLEFloatCharacteristic
BLEDoubleCharacteristic
None of these types of Characteristics appear to be able to hold a 20-byte string. (I have tried the BLECharCharacteristic, and it appears to pertain to a single char, not a char array.)
Using CurieBLE, how does one go about using a string as a characteristic value, as described in the documentation as an efficient practice?
Yours issue described here in official arduino 101 example. Few strings of code how to set an array:
BLECharacteristic heartRateChar("2A37", // standard 16-bit characteristic UUID
BLERead | BLENotify, 2);
...
const unsigned char heartRateCharArray[2] = { 0, (char)heartRate };
heartRateChar.setValue(heartRateCharArray, 2);
As you can see characteristic's value set using "setValue" function with desired array as an argument. You can pass a String as char* pointing to an array.
Related
I started learning on Contiki OS. I am trying to analyze few parameters like energy efficiency, latency, delivery ratio etc with different deployment scenarios. First I should change some parameter like:
Channel check rate to 16/s (I use rpl-sink)
RPL mode of operation to NO_DOWNWARD_ROUTE
Send interval to 5s
UDP application packet size to 100 Bytes
Could you please tell me how to change these parameter in Contiki 2.7?
My answers for reference:
Channel check rate to 16/s (I use rpl-sink)
#undef NETSTACK_RDC_CHANNEL_CHECK_RATE
#define NETSTACK_RDC_CHANNEL_CHECK_RATE 16
RPL mode of operation to NO_DOWNWARD_ROUTE
It's called non-storing mode. To enable it:
#define RPL_CONF_WITH_NON_STORING 1
Send interval to 5s
Depends on the application; there is no standard name for this parameter. If we're talking about ipv6/rpl-collect/, you should #define PERIOD 5 in project-conf.h.
UDP application packet size to 100 Bytes
The payload is constructed in udp-sender.c:
uip_udp_packet_sendto(client_conn, &msg, sizeof(msg),
&server_ipaddr, UIP_HTONS(UDP_SERVER_PORT));
So in order to change the payload size, you need to change the size of the locally-defined anonymous struct variable called msg. You can add some dummy fields to it, for example.
struct {
uint8_t seqno;
uint8_t for_alignment;
struct collect_view_data_msg msg;
char dummy[100 - 2 - sizeof(struct collect_view_data_msg)];
} msg;
I am creating a game using the Mifare tags embedded in 8 different playing pieces. I will be using an Arduino NANO with the MFRC522 (library https://github.com/miguelbalboa/rfid) to do the actual reading of the tags, and am using an ER301 reader/writer (with eReader software) to assign playing piece numbers to them. I will be creating multiples of each piece to head off any issues I would have with loss due to breakage or theft (due to these being rather unique playing pieces). Since there will be 8 different pieces, and 4 copies of each piece, that would be 32 UIDs to keep up with. I would rather assign a different number to each of pieces, and the same number of each piece to its duplicates - so only 8 numbers to keep up with.
My question is - how do I read a certain block and sector with the MFRC522?
Specifically, sector 2, block 8 - because this is where the Hex equivalent of the playing piece number shows up (when it is assigned as a Product Name with the eReader software and the ER301 writer). I understand using the library for the MFRC522 to read the UID, but this is a bit more in-depth than my understanding.
I have written several Sketches for the Arduino, but this is my foray into the world of RFID, and is quite a bit more extensive than my previous Arduino projects. Once I can read the specific sector & block, the Arduino NANO will output a binary representation (on 4 of the digital I/Os) of which playing piece was placed.
The library you are using provides dedicated methods to perform read and write operations on MIFARE tags:
StatusCode MIFARE_Read(byte blockAddr, byte *buffer, byte *bufferSize);
StatusCode MIFARE_Write(byte blockAddr, byte *buffer, byte bufferSize);
Since your description (sector 2, block 8) suggests that you are using MIFARE Classic tags, you would also need to authenticate to the tag in order to perform read/write operations. Thus, you would also need the authentication method:
StatusCode PCD_Authenticate(byte command, byte blockAddr, MIFARE_Key *key, Uid *uid);
Just as you would use the library to read the UID
if (mfrc522.PICC_ReadCardSerial()) {
Serial.print(F("Card UID:"));
dump_bytes(mfrc522.uid.uidByte, mfrc522.uid.size);
}
you could also access these read/write methods:
MFRC522::StatusCode status;
MFRC522::MIFARE_Key key;
byte buffer[18];
byte size = sizeof(buffer);
for (byte i = 0; i < MFRC522::MF_KEY_SIZE; ++i) {
key.keyByte[i] = 0xFF;
}
if (mfrc522.PICC_ReadCardSerial()) {
status = mfrc522.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_A, 8, &key, &(mfrc522.uid));
if (status == MFRC522::STATUS_OK) {
status = mfrc522.MIFARE_Read(8, buffer, &size);
if (status == MFRC522::STATUS_OK) {
Serial.print(F("Data (block = 8): "));
dump_bytes(buffer, 16);
}
}
}
Note that I assume block 8 (= sector 2, block 0) to be readbale using key A and that key A is set to the default transport key FF FF FF FF FF FF. If your other reader changed those values, you need to adapt the code accordingly. Moreover I used the pseudo-method dump_bytes(array, length) to indicate that the interesting value is the first length bytes of array. An implementation that actually prints those values is up to you.
Btw. a full example on how to use the library for read/write operations actually ships together with the library!. So you could just take a look at ReadAndWrite.ino on how to use that library.
I'm following the sparkfun tutorial for connecting an arduino to electric imp. I only have one arduino and imp, so I'm trying to get whatever I type in the arduino serial monitor to display in the imp node using server.show().
I've modified one of the functions in the sparkfun code to look like this:
function pollUart()
{
imp.wakeup(0.00001, pollUart.bindenv(this)); // schedule the next poll in 10us
local byte = hardware.uart57.read(); // read the UART buffer
// This will return -1 if there is no data to be read.
while (byte != -1) // otherwise, we keep reading until there is no data to be read.
{
// server.log(format("%c", byte)); // send the character out to the server log. Optional, great for debugging
// impeeOutput.set(byte); // send the valid character out the impee's outputPort
server.show(byte)
byte = hardware.uart57.read(); // read from the UART buffer again (not sure if it's a valid character yet)
toggleTxLED(); // Toggle the TX LED
}
}
server.show(byte) is only displaying seemingly random numbers. I have an idea of why this is, I just don't know how to fix it because I'm not that familiar with UARTs and squirrel.
local byte = hardware.uart57.read(); reads in the ascii characters from the arduino in byte form (I think), and they're not being 'translated' into their ascii characters before I use server.show(byte).
How do I do this in squirrel?
Also, I think polling every 10us is the wrong way to go here. I'd like to only poll when there's new information, but I also don't know how to do that in squirrel. Can someone point me to an example where this happens?
Thanks!
I think you are passing the wrong data type to the show method of the server object. The electric imp docs state that it takes a string, server.show(string). I think that local is the correct type to receive the value from hardware.uart57.read(). You can tell from the docs as well. So, you need to find a way to cast your byte to a string. I bet you could find the answer here. From what I read Squirrel use's Unicode so there is a probably a function that takes Unicode bytes and loads them into a string object.
Is there are a standard accepted way to byte-swap UUIDs for transmission over a network (or file storage)? (I want to send/store the 16 raw bytes rather than convert the UUID to a string representation.)
I thought at first I should partition the UUID into 4 32-bit integers and call htonl on each of them, but that didn't smell right. A UUID has internal structure (from RFC 4122):
typedef struct {
unsigned32 time_low;
unsigned16 time_mid;
unsigned16 time_hi_and_version;
unsigned8 clock_seq_hi_and_reserved;
unsigned8 clock_seq_low;
byte node[6];
} uuid_t;
Would it be correct to do:
...
uuid.time_low = htonl( uuid.time_low );
uuid.time_mid = htons( uuid.time_mid );
uuid.time_hi_and_version = htons( uuid.time_high_and_version );
/* other fields are represented as bytes and shouldn't be swapped */
....
before writing, and then the correpsonding ntoh...calls after reading at the other end?
Thanks.
Yes, that is the correct thing to do.
Each number (time_low, time_mid, time_hi_and_version) are subject to byte ordering. the node field is not. clock_seq_hi_and_reserved and clock_seq_low are also subject to byte ordering, but they are each one byte, so it doesn't matter.
Of course, it is up to you to make sure that you choose the right ordering on both ends, or understand what the ordering is on the other end if you don't control it. Microsoft of course uses little endian for their UUIDs. You can see Microsoft's definition of a UUID here.
I'd like to disable RTSControl using boost::asio::serial_port::set_option function. and also be able to raise or lower the DTR line?
boost::asio::serial_port_base::baud_rate baud_option(115200);
serialPort.set_option(baud_option);
The standard options work great, but I can't figure out, how to change the
DCB structure, or how to control the RS232 signal lines.
Settable serial port option requirements (emphasis mine):
In the table below, X denotes a serial
port option class, a denotes a value
of X, ec denotes a value of type
error_code, and s denotes a value of
implementation-defined type storage
(where storage is the type DCB on
Windows and termios on POSIX
platforms), and u denotes an
identifier.