SparkFun Forums 

Where electronics enthusiasts find answers.

Everything with the AmbiqSuite SDK tools and software are welcome here.
By paulvha
I had already developed a solution for BLE communicating between Apollo3 and Linux ( Raspberry Pi/ Ubuntu). I have now extended this for BLE between 2 Apollo3 boards, one running as client other as server.

Based on the Ambiq Amdtp client menu structure : It can exchange test data, set the server led on /off, perform a simple chat, set and read any digital pin, read any analog pin, read the internal temperature , provide the battery level in percentage and (if enabled on the server) provide BME280 data to the client

It will work on both with the current 1.0.30 Apollo3 board library, as well as the adjusted library containing the more secure EXACTLE/Cordio from Ambiq 2.3.2 using the normal Arduino interface structure.
User avatar
Confirmed working for redboard nano as server and Edge2 as client.

WOW...hooked both up to two com ports and ran Termite on Com3 - Server, Com4 - Client. Turned on client debug. Can chat back and forth, turn on lights, etc. etc. and...follow the command sequence.

REALLY, REALLY EXCEPTIONALLY NICE WORK HERE. WHAT A TOOL for exploring BLE on these boards with Windows10 and Arduino. I used SDK 2.4.2 and Core 1.0.30 - both unmodified. WOW!

User avatar
By mysparkfun71451
What great timing for you to have provided your code! I was just getting ready to create a new post regarding what I believed to be errors in the calculation of battery voltage and temperature, in the Ambiq SDK 2.2.0 (and probably all versions) examples such as "(SDK)\boards\apollo3_evb\examples\adc_vbat", when I downloaded and looked at what you did. And I found that you have made the same corrections that I believe were needed. The first is that in the examples the FIFO sample value gets scaled by dividing by 65,636, which would be correct for a 16 bit value, but the ADC registers are only 14 bit, which should use 16,384 as the scaling factor as you have done. For VBATT I get a sample value of 12,206 (using a reference voltage of 1.5V) which results in VCC = 3.35 V using the 14 bit scale value and 0.84 V using the 16 bit scale factor. Obviously, the 3.35 V result is reasonable, whereas the 0.84 V result is not. The other error, which I haven't figured out yet, is that the temperature FIFO sample value is about 43,840, which is impossible given a 14 bit register. I think the problem is related to the use of a 10 bit, instead of 14 bit, resolution for temperature in the example problem. Oddly enough, the resulting temperature, using the incorrect 16 bit scaling factor as done in the example, is about 72 degF as compared to my room thermostat reading of 69 degF. I'll have to study your code at length to know what you've done, but it appears at a quick glance that you have taken the default values for resolution which are 14 bit. Since your results are in close agreement with an independent temperature measurement your code appears to be working correctly. Another error that I think is present in the example, although it does not affect the results, are the expected temperature and voltage ranges given respectively as -40 F to 225 F and 0.825 V to 1.283 V. The given temperature range results in a maximum difference of 265 F or 147 C. For a specified sensitivity of 3.8 mV/C, for the temperature sensor, the resulting voltage difference would be 559 mV as compared to the given range of 458 mV. I believe that a more credible expected temperature range would be the maximum operating range for the chip, which is given in the Apollo3 Blue data sheet as -40 C to 85 C (-40 F to 185 F) for which the expected voltage difference would be 475 mV. I don't find anywhere in the data sheet document where a temperature range or voltage reference point is given for the temperature sensor.
One additional error that I have found is in the Arduino "Example4_analogRead" problem for which the equations are correct but the result gives a temperature of 40 C (104 F) instead of the expected 21 C (70 F). I believe the problem relates to the internal pad number of 102 that is assigned to the temperature sensor. I have not found any documentation to validate the correct values for these pads. The battery voltage divider, which is assigned pad number 103, provides a correct result of about 3.32 V.
I'm looking forward to further exploring and executing Paul's work.
User avatar
By mysparkfun71451
The explanation for the temperature result being reasonable in the example problem referred to above, which uses a 16 bit scale factor, is as follows:
The FULL_SAMPLE from the FIFO is used for temperature, which includes the 6 fraction bits. A bit mask of 0xFFC0 is then applied, which zeros the fraction bits. Then, since a 10 bit precision was used for temperature, the resulting value that includes 6 additional bits is a 16 bit number (the same as shifting the 10 bit number left 6 bits). Therefore, using a 16 bit scaling factor is appropriate and gives a correct result. Alternatively, a 14 bit precision can be used and the FULL_SAMPLE shifted right 6 bits and then use a 14 bit scaling factor. However, use of the code "g_ui16ADCTEMP_code = AM_HAL_ADC_FIFO_SAMPLE(sSample.ui32Sample);" will grab the sample without the 6 fraction bits and the 14 bit scaling factor can be applied without any further bit shifting. In Paul's code, a default precision of 14 bits is used and the sample is obtained without the 6 fraction bits. Then a 14 bit scale factor is applied.
User avatar
By mysparkfun71451
This post got pretty far off topic with some good exchanges of information, but for those of you interested in the original topic, I have an update if you've made it this far. The recommendation to use pMsg->connOpen.peerRpa[0] to locate the friendly name, gets you in the ball park by coincidence but is not the best way. The advertised data, including the friendly name, is packaged in the data for a scan report. The start of this data can be accessed using pMsg->scanReport.pData[0]. The length of the data field is obtained from pMsg->scanReport.len. The actual data is made up of packets that begin with a packet length, then a type and then the packet data. The data type, the second byte of a packet, is 0x9 for the friendly name (i.e. DM_ADV_TYPE_LOCAL NAME) if it exists and the name will begin at the third byte. A type 0x8, if it exists, is for a shortened version of the name DM_ADV_TYPE_SHORT_NAME. A friendly name packet, if it exists, may not be the first data packet. Therefore, the data field has to be searched for a type 0x8 or 0x9 to find the name. To perform this search one starts at location pData[0], which contains the length of the first data packet (Length1). However, the length only includes the type and data bytes. The second byte of the first packet at pData[1] will be the type. If the type is not 0x8 or 0x9 then the next data packet begins at pData[Length1+1] and the next data packet type is at pData[Length1+2}. The entire data field, up to the length pMsg->scanReport.len can then be searched by hopping from one data packet to the next. Not all devices advertise a friendly name so the search may come up empty and the device will have to be identified by it's address found at pMsg->scanReport.addr.
User avatar
By rowanham
Hey, I want to thank people for the off-topic discussion. I have been looking for the right venue to ask about the decoding of the ADC values when reading the Apollo3 temperature transducer, and now I have found what I am sure is the answer! I wll dig into this next week.
(I'm actually not all that interested in the temperature data - I am just using it to test my code. I am really interested in the accuracy of the ADC measurements on raw voltage, but that will come with the fullness of time.)
 Topic permissions

You can post new topics in this forum
You can reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum