esp-idf BLE scanning - bluetooth-lowenergy

I am working ESP-idf to program my ESP32 board. My Goal is to make it scan for a specific BLE (Bluetooth Low Energy) Device.
I figured out how to make it scan by using one of the examples that are provided by "Espressif" called "ibeacon_demo.c"
the thing is I don't know how to extract the address of any searched device and have it as string so I can compare it with the my BLE device address.
ibeacon_demo.c:
https://github.com/pycom/pycom-esp-idf/blob/master/examples/bluetooth/ble_ibeacon/main/ibeacon_demo.c
I am pretty sure there is something has to be done in this statement:
if (esp_ble_is_ibeacon_packet(scan_result->scan_rst.ble_adv, scan_result->scan_rst.adv_data_len)){
esp_ble_ibeacon_t *ibeacon_data = (esp_ble_ibeacon_t*)(scan_result->scan_rst.ble_adv);
ESP_LOGI(DEMO_TAG, "----------iBeacon Found----------");
esp_log_buffer_hex("IBEACON_DEMO: Device address:", scan_result->scan_rst.bda, BD_ADDR_LEN );
esp_log_buffer_hex("IBEACON_DEMO: Proximity UUID:", ibeacon_data->ibeacon_vendor.proximity_uuid, ESP_UUID_LEN_128);
uint16_t major = ENDIAN_CHANGE_U16(ibeacon_data->ibeacon_vendor.major);
uint16_t minor = ENDIAN_CHANGE_U16(ibeacon_data->ibeacon_vendor.minor);
ESP_LOGI(DEMO_TAG, "Major: 0x%04x (%d)", major, major);
ESP_LOGI(DEMO_TAG, "Minor: 0x%04x (%d)", minor, minor);
ESP_LOGI(DEMO_TAG, "Measured power (RSSI at a 1m distance):%d dbm", ibeacon_data->ibeacon_vendor.measured_power);
ESP_LOGI(DEMO_TAG, "RSSI of packet:%d dbm", scan_result->scan_rst.rssi);
}
here is the API reference for the example I used "ibeacon_demo.c"
[https://docs.espressif.com/projects/esp-idf/en/latest/api-reference/bluetooth/esp_gap_ble.html#_CPPv428esp_ble_gap_update_whitelistb13esp_bd_addr_t22esp_ble_wl_addr_type_t][1]

You question is 2 parts, how to extract the address and how to compare it to the one your looking for.
The first is already answered for you, as this sample is extracting the address and putting it in the log:
esp_log_buffer_hex("IBEACON_DEMO: Device address:", scan_result->scan_rst.bda, BD_ADDR_LEN );
But your second question take a deeper understanding of how to compare byte arrays. I can try to help you understand the second part by telling you that the address is a byte array and that it is 6 bytes long, that's what the BD_ADDR_LEN constant is telling you.
Now you must compare the 2 byte arrays.
After you figure that out you can get into public and random addresses. But for now that's enough.

Related

Trying to interface with an Aanderaa RCM9

I have an older Aanderaa RCM9 (https://epic.awi.de/id/eprint/45145/1/RCM9.pdf) that is missing its Data Storage Unit and its reader. They don't produce these anymore nor do they service the model. It would be a shame to toss an otherwise nice piece of equipment, so I thought to try and get a serial feed from the terminal or DSU output and log on an Arduino with an SD card. I have tried to connect with a TTL-RS232 converter, and there seems to be a consistent Tx from the instrument, it comes in batches, but reads out in CoolTerm as "............" I've tried different terminal configurations, and connections, but that's the best I get. Here's how it looks inside: https://imgur.com/a/xxCPUlQ
Any thoughts??
I am afraid that the output is the old Aanderaa PDC4 serial format where long pulses (81ms) represents zeros and short (27ms) represents ones in a 10 bit binary word framed in a 4 second window.

Interrupt vector addresses in ATMega2560

I have a question concerning the addresses of the interrupt vectors in ATMega2560.
According to the data sheet, the vectors are at the program addresse $0000, $0002, $0004, ..., $0070.
After disassembling code of an ATMega2560 (on an Arduino Mega board) I noticed that the vector are at the addresses $0000, $0004, $0008, ..., $00E0.
I assume that (2) is correct. According to the AVR Instruction set manual a jmp instruction has a 4 Byte opcode which fits this assumption (and the assembler uses the jmp instruction to jump to the ISR).
But why does the data sheet then tell something different? Or is my understanding maybe totally wrong?
Thanks a lot for all answers and kind regards!

Modifying hex codes to produce a larger output

I was working on this project : http://elm-chan.org/works/sd8p/report.html
and I failed in every possible way from the start. Now that the .Hex files have been uploaded, and the fuses written, when I plugged the SD card in, nothing happened. Nothing at all. Directly asking for a solution might be impossible here as I have no idea what went wrong. So instead I tested the speaker's positive connection with the arduino serial plotter, and I found some interesting results. The output gave some cool irregular pattern of waves,similar to what I would expect from a sound output. But there was no sound, and I suspect that it was because of the output size being too small.(60/1023 is around 0.06 volts, 200/1023 is around 0.2 volts and the bigger output at 500++ levels out, so it shouldn't produce a sound.)
So now I would like to ask whether I can change the fuses of the .hex file(or the hex file itself, but its big.) to produce a larger output. I have not much understanding in hex files or even AVR devices, so any hep at all would be useful.
Thanks in advance.
the graphs
Please let me know if any other information is needed.
Your voltage output on a GPIO pin is limited to your supply voltage, so no you probably can't fix your problem by changing the software or the fuse bits. Depending on your current supply voltage, you might be able to crank that higher, which would increase your voltage output of the PWM, but the supply voltage can only go so high without damaging the chip.
That being said, you need to disconnect the amp and speaker from the AVR and probe the output pin of the PWM and make sure that it is actually producing a signal on that pin. The plots that you posted with that amplitude look like they are nothing but random electrical noise to me.

Arduino - create dynamic rules

I want to create a program for arduino in order to be able to add and remove rules controlling some pins, whenever i want and not hardcode them.
For example a rule like this:
if pin1=HIGH and pin2=LOW then pin3=HIGH
i want to turn into this:
if(pin1 == HIGH && pin2 == LOW){
digitalWrite(pin3, HIGH);
}
Lets say we pass the rule via the command line as a string.
How could i convert this string into a rule? Is something like this possible?
Your second piece of code:
if(pin1 == HIGH && pin2 == LOW){
digitalWrite(pin3, HIGH);
}
is compiled by your IDE into machine code. That machinecode is then uploaded to the Arduino and then executed.
Therefore you cannot just send some string like this
if pin1=HIGH and pin2=LOW then pin3=HIGH
to the Arduino because after your programm transformed that into the desired form the complete IDE and compiler stuff is missing on the Arduino side. And a C++ compiler tool chain is big - several tens of megabytes! There is no place for that on the Arduino.
What you can do: Invent a simple language for your rules and develop an interpreter for that which then runs on the Arduino.
Perhaps you also don't need to reinvent the wheel - Google for simple BASIC interpreters running on the AVR CPUs and adapt one of them.
What you are asking for is possible but with much work on your part.
Approach 1 (think big):
What you are looking for is a software implementation equivelant to how PAL's (programmable array logic) and CPLD's (complex programmable logic device) operate. If you read this article, you will get some ideas on how this is done in hardware:
Wikipedia article on PLD's
A PAL can create arbitray combinational logic rules between a set of inputs and outputs, i.e. anything you can express as a logical equation of AND's, OR's and NOT's can be programmed. It is programmed by "burning" a set of fuses that connect the inputs to logics gates and then to outputs. What is uploaded to these devices is just a set of 0's and 1's.
You could implement such a thing in software with an array of 0's and 1's to represent the fuses. The hard code would run over the array and calculate the output. You would need to develop the method to load the array with the correct fuses.
A common method by which PAL's are programmed is with the language VHDL. The compiler for this language takes an expression like yours and translates it to the set of AND's, OR's and NOT's that the PAL can use. A search will yield endless discussion of this language, for example:
A VHDL tutorial
You would have to create the compiler that takes the text input and determines the fuses. You would be undertaking some significant tasks:
a domain specific language parser (I can recommend ANTLR),
a PAL compiler (I can't recommend anyone do this themselves), and
the Arduino code to emulate a PAL.
By the time you create your own equivalent of VHDL and PAL's, you'll probably be thinking you could have just put a PAL chip on a proto board and been done.
Approach 2 (more practical):
The simpler method to achieve the same result is a truth table. A truth table is the equivalent of some set of logical expressions. To implement a truth table, translate your logic expressions to a table with one row for each input case. Here is an example of a truth table of two inputs that drive an output:
IN1 IN2 OUT
0 0 1
0 1 0
1 0 1
1 1 1
The code for such a truth table implementation looks like this:
const int IN1 = 6;
const int IN2 = 7;
const int OUTA = 13;
byte table[4] = {1, 0, 1, 1};
void loop() {
int in1;
int in2;
byte outbit;
size_t ix;
//
in1 = digitalRead(IN1);
in2 = digitalRead(IN2);
ix = in2 * 2 + in1;
outbit = table[ix];
digitalWrite(OUTA, outbit);
}
The complete expression of the logic rules is the array of 4 bytes. To "program" an new output equation, you just send a new set of 4 values, for your specific equation you send "0 0 1 0". Your program would receive the list of values and store them in the table array. As soon as the new values/rules are stored, the function of the output would change.
This type of programmable logic is feasible as long as you have enough RAM to store the table. For 4 inputs you just need 16 values, for 5 you need only 32.
Your question raises a keen point in electronics design: you need to pick the right device for the right problem. Code is not always better or easier. Avoid the hammer-nail trap (when your only tool is a hammer every problem looks like a nail). A PAL/CPLD and microcontroller are a powerful combination.
To add to the truth table approach mentioned by #jdr5ca, it's a good idea to understand the controller used in the arduino as well as using the ardiuno libraries.
Pins 0 to 7 are port D and pins 8 to 15 port B. Each port is represented as three single byte registers - PORT_ which is output/bias resistor, PIN_ which is input state and DDR_ which is direction. When you call digitalRead(pin) the code sees which range the pin is in, reads PIN_ for that port, then bit-shifts and masks the value to give just that pin's state. Which is handy for reading one pin at a time, but a less convenient than if you're reading several.
So if you create a truth table with 256 entries, you can write the output of pins 8 to 15 from the values of inputs 0 to 7 using a single line, rather than decoding the registers to pins then encoding them again:
byte table[256] = {0};
void loop() {
PORTB = table[PIND];
}
You can then add something to read from the serial and load new values into the table on the fly.

Serial output of ascii string giving higher voltage for more binary zeroes

I'm controlling a motor bridge via a serial port by using the voltage from the pins on the serial plug directly.
This would normally only give me the RTS and DTR pins to use (controllable through PySerial) as motor controls; however, if I send a string through the data out pin, I can generate enough voltage to control the motor bridge.
My question is--
Why do I get a higher voltage for characters with more binary zeroes in them?
A string of "~" (01111110)gets me only 1.3 volts, 'Z' (01011010) gets about 2 volts, and "#" (01000000)clears the 3 volt threshold I need operate the motor bridge.
It's not really a problem, but I feel I'm missing something conceptually important here as I assumed it would be the opposite (more binary ones = higher voltage).
Thanks in advance.
Hans Passant had the right answer: inverted outputs on RS-232. I'm just putting it so this questions doesn't stay open.

Resources