Showing posts with label RN4871. Show all posts
Showing posts with label RN4871. Show all posts

Thursday, May 8, 2025

Just Harmony

                                                                                                                                                                                        Designed by Freepik
 Well after a few weeks of work,   I may be there.  The software component lefty to implement is the script manager.  This is mostly software with a dependency on the Non-Voltaile Memory driver.  Since that is working with the config data, what remains is verifying it works on the larger memory needs of the script manager.

The last problem child was the Bluetooth and the RN487x interface.  First the UART driver did not work anything like the previous model.  As a result the Tx function is blocking, kind of, for now.  Not sure how important that is.  In the RN487x implementation, I wait around for the CMD prompt before executing the next instruction.  I could have the ISR process the flag the main loop when this happens, but this is only important on initialization.  For now I am just going to leave it as an inline process that runs to completion.

The Rx function works like before with an ISR that processed the Rx queue from Harmony.  I did have to use the Ring Buffer  implementation.  The normal implementation required that you submit a read request, instead of just using the call back when a byte came in.

There was another problem, but this had to do with Android software  I had thought I had solved this problem several years ago, but it came back.  It has to do with how many bytes are transmitted when writing a Bluetooth Characteristic.  Once transmit 8 (the maximum I set up), then in that session it will always transmit 8.  If you send 4 bytes, it will just stuff the other 4 bytes with the last 8 byte transmission.  You can read about this issue here.

Time to move on and finish this to the point I can start to assemble the new PCBs.  I have a place for at lest on of these 15 channel LED controllers.

 

Saturday, May 3, 2025

More Harmony, Less KAOS and some Stupidity

 

                                                                                                                                                                                         Designed by Freepik

I have spent the last few days working on the I2C driver that I need for the LP5569 LED driver.  This is one component that received a major change from Harmony v2 to v3.  Most of API had their names changed and few things were added/deleted.

First for Brick Lights 1, I changed the board to eliminate the individual connectors for each LED that used the very small two pin connectors, the working proto is shown here. 

I used the 2mm header (2 x 5) that I used in the Brick Buddy 3.    I also changed the BT module to the smaller RN4871.  This also allowed for the board dimensions to shrink 8mm.  This is the new layout.

 

The first picture is the device that I am using for the development, while I wait for the new PCBs to arrive.  I should mention that under Harmony v2, most if not all of this proto was working.  So I know that the design was good.  

After generating all the I2C components in Harmony 3, I started the process of implementing the application layer code.  While Harmony generates the drivers and middleware, you still have to implement the application layer.  That took over a day to get to the point that it would compile  and at least appeared to communicate with the I2C drivers.  This I2C implementation is interrupt driven which for the most part makes it non-blocking.  

No matter what I tried, the driver would report an I2C error when transmitting a simple command.  Trying to follow the execution path down into the driver was not yielding any useful info.  After two frustrating days, I decided to try a different approach.  I have a PIC32MX470 Curiosity board and there was an I2C EEPROM example.  Also the Curiosity board allowed me to connect my Digilent Analog Discovery device very easily.  This device has an I2C decoder built in, thus I can see the commands and the protocol to determine if it is working correctly.  While the EEPROM was responding correctly, the firmware still not see it.  Stupidity number ONE.  The comments for this example were very specific to make sure the CLICK sockets were connected with ZERO ohm resistors.  Well they were not.  The 1K resistors were just enough to screw up the PIC32 read.  Once I got the example code running, I modified it to more resemble the code flow I was using.  Now that I know this was working I could go back to the proto with some confidence.

Well still not working.  Attached the wires for SDA and SCL so  I could watch the I2C protocol exchange on the Digilent device.  First thing I see is the device address is wrong.  With a 7 bit I2C address in Harmony v2 the user was required to shift 1 bit left, but in v3 the driver does that.  Thus the device address had been all wrong.  Stupidity  number TWO.  Once this was changed the I2C exchange started to work, but would not complete.  

Side step, when I first started using TI LED Drivers, I was using the LP5569.  Then COVID and they disappeared. But I could get LP55231, and earlier version that was 90% firmware compatible, though the outputs were inverted.  THE LP55xx driver that I wrote would mostly do both, though I had not completely tested it on the LP55231 since the LP5569 became available again.  The new layout will use the LP5569.  This proto was the only device that actually had the LP55231.

Looking at the  I2C trace, I could see that the final ACK was not coming in.  After hours of research, I found that the LP55231 required a software Chip enable for some commands to work.  How this worked before I am not sure, but I decided to just move on.  I modified the startup loo.  Stupidity  number THREE.

Now the entire initialization of the  LP55231 completes and the status read back shows all the registers are where they should be, just not at reset.  I still need to check if the LEDs actually light up, but for now I have high hopes it will work.

On to the BT module.

 


Monday, May 15, 2023

RN4020 to RN4871 Update 2


In this post and the follow on post, I discussed the changes I have made for this transition to the RN4871.   I am getting near the end of this being done.  After testing with a several Play Store Apps (Nordic, Silicon Labs, and Microchip) I found that the name I assigned to the RN4871 was not showing up in the scan.  Again in the RN4020 this was not an issue, the SDN command was sufficient.  But for the RN4871 or maybe the version of BTLE that is running, this is an issue.  Unless you know the MAC address, the user would have a hard time determining which device listed is the Brick Buddy.  It is not uncommon for me to see 10-15 BTLE devices in my lab.  Not sure where they are all coming from, but these is a lot.  

Well it became apparent from examining those devices I was seeing that had a name attached, they were placing this in the Advertisement.  The RN4871 has an Advertisement limit of 30 bytes (31 bytes in later firmware).  Fortunately I had 11 bytes left from 30. So I added the name and that brought me up to 27 bytes total.  But as with adding the service, you could not just put the name in as text, as here.

NA,09,B_Buddy  

The NA command requires the actual hex bytes that represent the name.  This is alluded to in the RN4871 documentation, but is not really clear.  The 09 is the command for the complete local name.  

NA,09,422D4275646479     

It seems that everything works now.  The Android App finds it, connects automatically and the name is displayed with the last two address octets attached.  The Android App does allow you to name the Brick Buddy device and then bind that name to the MAC address.  From then on, it shows the name instead of the MAC address.  A more user friendly approach when you have multiple Brick Buddy's in a MOC.

Final change will be a check to see if the  RN4871 Non Volatile Memory (NVM) is valid.  Not sure how to do this yet.  I am somewhat concerned that reloading the NVM on every restart will wear this out too soon.  Especially for the device(s) I use for development.  The easiest way is probably to place a flag in the PIC EEPROM (or I2C memory when it is installed) that indicated a valid NVM.  Thus when the NVM is written and all commands have been accepted, the flag would be updated.  I currently have a config word that is kept, I just need to add this to it.


 

 

 

 

Friday, May 5, 2023

Microchip BLE Module Comparison


 This shows the relative size comparison of the Microchip BTLE modules.  Numbers are nice, but a visual portrays much more information.  The RN4871 is the smallest.  The newer RNBD451PE is somewhat larger, but maybe all you need depending on what your device is doing.

Enjoy!

 

 

 

Thursday, May 4, 2023

RN4020 to RN4871 Update

 


I have had my head down while trying to make this transition that I described briefly in this post.  I have had some success and learned a few things along the way.  

I am no BTLE expert and I have tried to slug through the specifications, but it is a tough read for those of us who don't do this on a daily basis.  The RN4020 was 4.2 and the RN4871 says it is 5.0 and beyond.  I am assuming that some enhanced features were added.  My Android code was quite dependent on this real time read feature of the RN4020.  Without this, getting data back was difficult.  

After some reading, I implemented the Notification feature for each characteristic.  I had done this with the Heartbeat characteristic, but now all of the characteristics have this enabled.  This will also enable me to continue to support existing Brick Buddy I controllers.  The Android APP tested to see if Notifications are enabled on the Brick Buddy.  If they are, the new code is implemented, otherwise the Android APP stays with the old methodology.  So now I write to the Characteristic, the 18F26Q71 performs the tasks, updates the characteristic value and then notifies the Android APP the characteristic has changed.  The APP is waiting (in a separate thread) for a few seconds for the 18F26Q71 to respond (plenty of time at 64MHz).

Next issue was finding the the Brick Buddy during scanning.  The Android APP had implemented a scan search on the MyMakerTools UUID.  While it continues to work for RN4020 devices, it failed on all RN4871 devices.  I could scan for it along with every other BTLE device in the house and the neighborhood.  Sometimes I would see 20 devices.  At first I thought this was an issue with the Delphi compiler.  After tracing deep into the library, I decided this was not the issue.  This must be something to do with advertising.  Again, not a BTLE expert and if the spec changed, then I was not seeing it.  I found a note in a RN4870/4871 firmware upgrade document that said:

This led to lots of reading on the NA command, which is about advertising.  So in the RN4871, you have to purposely advertise services.  If the Android APP is filtering on a specific service list, those services must be advertised.  If not filtering on a specific service list, then all reachable BTLE devices show up.  The system will still connect, but it is multi step process that should just happen.

So here is the initialization of the RN4871 across the ASCII UART interface.  Will another sequence work, probably, but I know this works.

  • PZ
  • NA,Z  
reboot here
  • SS,80            ; setup
  • SN,B-Buddy       ; device name
  • SDN,MyMakerTools ; mfg name
  • PS,3425a5cca67643629592a88e132b8b52       ;service
  • PC,b67e3a3b15c941b6a9f2fbf379418d12,12,02 ;characteristic
  • PC,f18e901af3254dfd8cdb68506676dc08,16,08 ;characteristic
  • PC,9bac1d289fc14db097c4896089ad26bb,16,08 ;characteristic
  • PC,39bb1bf917ec41d2b5e4b78551b45740,06,08 ;characteristic
  • NA,01,06         ; set flags
  • NA,07,528b2b138ea89295624376a6cca52534    ;advertised service
  • A                ; turn on advertising


 The first two clear out the services/characteristics and the advertisement data, followed by a reboot.  The next are setup and naming, followed by the service and the characteristics.  The first NA command sets the flags.  The first hex value is the AD Type which is found in Table 2-14 of the RN4870/71 Users Guide.  The next is an 8 bit value that reflects which flags are active.  You will need to search the internet to find this, but 0x06 is the most common value.  The last NA command is the advertised service.  You will notice that is does not match the service.  For whatever reason, the NA, 07 command will not take the value as the PS command does, it needs to be completely byte swapped.  Not the most user friendly, but probably made sense to someone.  Finally I purposely started advertising.  This is supposed to be the default, but it costs very little.  I did not test the initialization without this, so I don't know if the default is works also.

I am back to where I was with the RN4020.  I still need to verify the Android APP with the original Brick Buddy, but that is a task for another day.


 

 

Tuesday, May 2, 2023

Upgrading from RN4020 to RN4871

 


 I am in the process of upgrading the wireless interface for those people who want to install it.   I was hoping that moving from the RN4020 to the RN4871 would be simple and painless.  As is always the case now, it was not.

I use the ASCII interface over a standard serial UART.  While most of the commands are the same, there are changes.

  1. They have included a delimiter on all GATT messages (%) plus a few others.  While it makes the parsing a little easier, it changed the way the parser worked.  
  2. The RN4871 is very sensitive to power and the reset input (see this post).  When I designed Brick Controller 3, I used the PIC nMCLR input to reset the RN4871.  This in turn is driven by TC54 reset controller.  So that part is good, since it appears the RC type resets don't work.  I do have a spare GPIO now, so I could cut/jump that in if it becomes necessary.
  3. There is a transparent UART mode, but I am not sure how much Android work that will entail, if it is even possible.
  4. The most important change was the elimination of the real time read mode.  The mode would send a message across the UART that the phone was about to read the characteristic.  This would allows the PIC just enough time to update the characteristic value before the phone read it.  That is not implemented in the RN4871.  So I am looking at other ways to do this.

I mostly have the interface working.  It seems to be stable, though the code needs some work.  The 18F26Q71 running at 64MHz, is just too fast for a 115200 baud rate.  During initialization, I have to make sure that the RN4871 response has come in before moving on to another command.  While this implemented in essentially "wait for it to happen" code, this needs to move into the switch function of the BT_TASKS subroutine of the main loop.


 

 

 

 

Wednesday, April 5, 2023

More MPLAB Fun!

My next step on the Brick Buddy 3 code development was to implement the Bluetooth Interface.  The Brick Buddy 3 uses a RN4871 instead of the RN4020.  I was hoping that the change over was going to be simple, but that does not look like what will happen.

My plan was to use a Mikroe Click Board with an RN4871 on it.  I also have one with an RN4870, which is just bigger version with more I/O pins.  You can see the RN4871 in the picture above on the left. Well the best laid plans, things did not go as planned.  After several failed starts at communications, I finally managed to get Tx/Rx connected.  The RN4871 reset line also worked as advertised, but the system would reboot itself randomly or sometimes continuously.  In the beginning I had just connected the serial port of the RN4871 to FTDI serial to USB converter and used TeraTerm to watch the RN4871 output.  The %REBOOT% would show up every few seconds.  

Searching the Internet this seemed to be an issue with earlier firmware versions.  Also the RN4871 seemed to be sensitive to voltage ripple.  So I did two things to hopefully improve performance.  First I upgraded the firmware to 1.42.  But that did not seem to do much improvement.  So I backed down to 1.41 and there appeared to be improvement.  Next I had a 10uF capacitor across Vcc and GND, right on the click board.  The multiple resets went away and everything seemed to be more stable.  Which one did it, not sure, but it needed the firmware upgrade.  While this picutre is not very good and my soldering was below average on this, you can see the capacitor across the two pins.

With a stable system I started walking through the code I had been using for the RN4020 with modifications for the RN4871.  It would always hang on the first command.  I started stepping through the command and the while loop would not iterate. It always sent the same character to the RN4871.  No matter how I wrote the code, it would not iterate or would iterate by random numbers. I changed the variables to different types, nothing matter.  First I suspected the ISR was changing things.  But that was not the case.  After a day of this, I decided to install every Pack available for MPLAB 6.00. and for the PICKit4.  Most of them installed, then said they do not apply.  But whatever I did, the loop started iterating correctly. I was then able to walk through the command list and could watch the RN4871  respond to each.  Then I used a generic BTLE tool on my phone to see that the RN4871 was correctly advertising all of the characteristics.  

Now it became obvious that a parser was needed.  Different commands result in different ASCII responses.  Thus this is very similar to the old Hayes AT modem.  Looking around I finally found a parser that was generated by the MPLAB Code Configurator, that was a start at this.  It can be found on Github.  This is where I stopped and moved on to ohter things. If time permits I will come back to this and see if I can get something working in a day or two.