BlueNRG Bluetooth: how to receive data via chateractic - bluetooth-lowenergy

Currently I implement code bluetooth low engine (BLE) for STM32L476 + X-NUCLEO-IDB04A1 base on example "sensor demo".
In "Sensor Demo" example, it only code to send data to smart phone. And don't have receive data.
I think can use function below to read data:
tBleStatus aci_gatt_read_charac_val(uint16_t conn_handle, uint16_t attr_handle)
And can read data from HCI_Event_CB(hciReadPacket->dataBuff);
However I don't know how to get parameter "uint16_t attr_handle" for function
tBleStatus aci_gatt_read_charac_val(uint16_t conn_handle, uint16_t attr_handle)
Could you explain for me about this problem?

That would be the value of the handle for this connection.
When IDB04A1 successfully connects to the smart phone, it shall send a HCI_LE_META_EVENT with information for this connection. Connection_Handle can be found in the event, to be specific, a 16-byte value:
(offset 6 | offset 5)

Related

Sim800L lag/delay before incoming calls are visible to arduino

I use SIM800L GSM module to detect incoming calls and generally it works fine. The only problem is that sometimes it takes up to 8 RINGS before the GSM module tells arduino that someone is calling (before RING appears on the serial connection). It looks like a GSM Network congestion but I do not have such issues with normal calls (I mean calls between people). It happens to often - so it cannot be network/Provider overload. Does anybody else had such a problem?
ISP/Provider: Plus GSM in Poland
I don't put any code, because the problem is in different layer I think
sorry that I didn't answer earlier. I've tested it and it turned out that in bare minimum code it worked OK! I mean, I can see 'RING' on the serial monitor immediately after dialing the number. So it's not a hardware issue!
//bare minimum code:
void loop() {
if(serialSIM800.available()){
Serial.write(serialSIM800.read());
}
if(Serial.available()){
serialSIM800.write(Serial.read());
}
}
In my real code I need to compare calling number with the trusted list. To do that I saved all trusted numbers in the contact list on the sim card (with the common prefix name 'mytrusted'). So, in the main loop there's if statement:
while(mySerial.available()){
incomingByte = mySerial.read();
inputString += incomingByte;
}
if (inputString.indexOf("mytrusted") > 0){
isTrusted = 1;
Serial.println("A TRUSTED NUMBER IS CALLING");
}
After adding this "if condition" Arduino sometimes recognize trusted number after 1'st call, and sometimes after 4'th or 5'th. I'm not suspecting the if statement itself , but the preceding while loop, where incoming bytes are combined into one string.
Any ideas, what can be improved in this simply code?
It seems, I found workaround for my problem. I just send a simple 'AT' command every 20 seconds to SIM800L (it replies with 'OK' ). I use timer to count this 20 seconds interval (instead of simply delay function)
TimerObject *timer2 = new TimerObject(20000); //AT command interval
....
timer2->setOnTimer(&SendATCMD);
....
void SendATCMD () {
mySerial.println("AT");
timer2->Stop();
timer2->Start();
}
With this simple modification Arduino always sees incoming call immediately (after 1 ring)

Count unread SMS using AT command

How to count unread SMS or revived SMS using AT command?
void UnreadMEssage() {
fonaSS.println("AT+CMGF=0");
delay(1000);
fonaSS.println("AT+CMGL=\"REC UNREAD\",1");
}
Using this code, I can show the all received text messages, but I want to count the unread SMS.
Answering in reference to this blog :
There is no direct command to count the number of unread messages . We can use AT+CMGL command in a modified way to count unread messages .
Use the command AT+CPMS? to find out how many messages are stored in your SIM in total.
Use AT+GMGL=<stat> for each status other than 0 "REC UNREAD" and count the number of messages for each of these.
Add each of these counts together and subtract that from the total memory used as reported by +CPMS and you've got the number of unread messages.
P.B : If you don't mind "reading" the messages just do the +CMGL for status 0 "REC UNREAD" and count, i.e those messages will be marked as read.
The AT command +CPMS (Preferred Message Storage) is used to figure out,
Select the message storage area that will be used when sending, receiving, reading, writing or deleting SMS messages.
Find the number of messages that are currently stored in the message storage area.
Find the maximum number of messages that can be stored in the message storage area.
try AT+CPMS? to list the available spaces. and issue a command like this,
AT+CPMS="SM","SM","SM"
the response should show used space,available space repeatedly like this,
+CPMS: "SM",19,20,"SM",19,20,"SM",19,20
here is SM signifies SIM card space and a list of available options is below. A typical response shows,
+CPMS: used1,max1,used2,max2,used3,max3
Based on the count, read each response using AT+CMGR=x (x is the index of the message) and parse the response for "REC UNREAD" and subtract to get read messages.
PS:
here, SM is storage area in SIM card. others are,
SM. msg storage area on the SIM card.
ME. msg storage area on the GSM/GPRS modem or device. A larger storage
space than SIM card(SM).
MT. all msg storage areas associated with the your modem or device.
BM. broadcast message storage area.
(In some devices, ME & MT -> Flash message storage.)
SR. It refers to the status report message storage area. It is used to
store status reports.
TA. Terminal Adaptor msg storage area.

MCP2515 OBD II multiple PID

I am using a raspberry Pi and arduino CAN schield which is using a MCP2515 and SPI to request a single OBD II PID.
I am able to request and receive a single PID from my OBD emulator (Freematics). I know that is possible to request multiple PIDs (up to 6 PIDs) in a single query.
Whenever I use other kind of messages, I receive only the first request. Can anybody maybe help?
Here is the message for single PID which is working (C++):
msg.id = 0x7DF; //ID_QUERY
msg.header.rtr = 0;
msg.header.length = 0x08;
msg.data[0] = 0x02;
msg.data[1] = 0x01;
msg.data[2] = PID; //Whatever PID I want!
Message for multiple request that is not working:
msg.id = 0x7DF; //ID_QUERY
msg.header.rtr = 0;
msg.header.length = 0x08;
msg.data[0] = 0x07; //! Also it is not working with 0x08
msg.data[1] = 0x01;
msg.data[2] = PID0;
msg.data[3] = PID1;
msg.data[4] = PID2;
msg.data[5] = PID3;
msg.data[6] = PID4;
msg.data[7] = PID5;
Our Freematics OBD II emulator does not support sending multiple responses. One of our test vehicles, a 2010 Toyota corolla does. In our experience it is best to send a test command at startup to see if the device we're communicating with supports multiple responses or not. For our application we send the command 00 twice,
010000
If the response its greater than 25 characters, we know the device supports multiple commands as it responded to both 00 commands. If the response is less than 25 characters, we know the device responded to just the first 00 command and consequently only supports one command at a time. checking how many responses were received could be done multiple ways, but length has worked well for us so far.
Based on your use case, it may be enough to only send single commands. But if you really need the increased speed of multiple commands, add a check at start up to see if the device responds to multiple commands and then construct your messages based on the results. Dont forget to end your messages with the expected number of response lines to further increase speed. See the attached taken from: http://elmelectronics.com/DSheets/ELM327DS.pdf
Sending canbus messages through mcp2515 is a litle bit tricky.
First of all Freematics OBD Emulator support no multiple PID requests. Secondly, the multiple PID request should be sent with ISO 15765 format. when you send a multiple request, he ECU would response only with one "First Frame" message and will wait for the "Flow Control" message from the sender. After receiving the flow control, ECU will continue to sending the responses based on your flow control setting.
For more information about the CAN-Bus messages and how "First Frame" and "Single Frame" works, read the below links:
googleBooks, ISO_15765-2, hackaday (dot) com

Reading a long text from GPRS Shield with Arduino

I am having hell with this and I know it is probably really simple. I am trying to read a text message from my Seeed GPRS shield. I have the shield setup as a software serial and I am displaying the information received from the GPRS to the serial monitor. I am currently sending all AT commands over serial while I work on my code. To display the data from the software serial to the serial monitor, I am using the following code.
while(GPRS.available()!=0) {
Serial.write(GPRS.read());
}
GPRS is my software serial obviously. The problem is, the text is long and I only get a few characters from it. Something like this.
+CMGR: "REC READ","1511","","13/12/09,14:34:54-24" Welcome to TM eos8
This text is a "Welcome to T-Mobile" text that is much longer. The last few characters shown are scrambled. I have done some research and have seen that I can mod the serial buffer size to 256 instead of the default 64. I want to avoid this because I am sure there is an easier way. Any ideas?
Have you tried reading into a character array, one byte at a time? See if this helps:
if (GPRS.available()) { // GPRS talking ..
while(GPRS.available()) { // As long as it is talking ..
buffer[count++]=GPRS.read();     
// read char into array
if(count == 64) break; // Enough said!
}
Serial.write(buffer,count); // Display in Terminal
clearBufferArray();
count = 0;
}
You need to declare the variables 'buffer' and 'count' appropriately and define the function 'clearBufferArray()'
Let me know if this helps.
Looks like this is simply the result of the lack of flow control in all Arduino serial connections. If you cannot pace your GPRS() input byte sequence to a rate that guarantees the input FIFO can't overflow, then your Serial.write() will block when the output FIFO fills. At that point you will be dropping new GPRS input bytes on the floor until Serial output frees up more space.
Since the captured output is apparently clean up to about 64 bytes, this suggests
a) a 64 byte buffer,
b) a GPRS data rate much higher than the Serial one, and
c) that the garbage data is actually the occasional valid byte from later in the sequence.
You might confirm this by testing the return code from Serial.write. If you get back zero, that byte is getting lost.
If you were using 9600 for Serial and 57600 for GPRS, I would expect somewhat more than 64 bytes to come through before the output gets mangled, but if the GPRS rate is more than 64x the Serial rate, the entire output FIFO could fill up within a single output byte transmission time.
Capturing to an intermediate buffer should resolve your issue, as long as it is large enough for the whole message. Similarly, extending the size of either the source (in conjunction with testing the Serial.write) or destination (without any additional code) FIFOs to the maximum datagram size should work.
I've had the same problem trying to read messages and get 64 characters. I overcame it by adding a "delay(10)" in the loop calling the function that does the read from the GPRS. Seems to be enough to overcome the race scenario. - Using Arduino Mega.
void loop() {
ReadmyGPRS();
delay(10); //A race condition exists to get the data.
}
void ReadmyGPRS(){
if (Serial1.available()){ // if data is comming from GPRS serial port
count = 0; // reset counter
while(Serial1.available()) // reading data into char array
{
buffer[count++]=Serial1.read(); // writing data into array
if(count == 160)break;
}
Serial.write(buffer,count);
}
}

Using ElectricImp server.show() and Arduino

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.

Resources