Showing posts with label PIC. Show all posts
Showing posts with label PIC. Show all posts

Monday, April 28, 2025

Harmony or Kaos

 

                                                                                                                                                                                        Designed by Freepik

Short missive on the framework Microchip calls Harmony 3.  Not sure if this is Harmony or is it a cruel replay of KAOS from Get Smart.

While Harmony 2 for PIC32 was tolerable, this new version is lacking.  I have read several forum entries where "experts" are expressing concerns that it may or may not work. And if it works today, no guarantee it will work tomorrow.  The "code suppositories" are just that.  Anyway I need to move to the next version of XC32, but that would require completely replacing about half of the Harmony 2 libraries and that was a non starter.  So a few days ago I started to build a simple project, USB HID and a console port.  Two basic things I need.

Now I admit I rarely used the code configurator for PIC18 projects. So using this for Harmony was a different thing.  Harmony 2 was mostly a text based configurator, except  for the clock and pins.  The documentation of Harmony 3 is mostly for previous revisions and implementations.  Instructional videos from Microchip do not match with using MPLAB 6.25.  The content creator is needed to download what you need for the framework.  Well the latest content is incompatible with the PIC32MX270 and it's components, at least that is the message I kept getting.  That was a day just trying to figure out how that worked.  Then there is a Project Graph where you have to connect the components.  I was an avid user of Borland's Object Vision in 90s, so graphical construction is not new to me.  But this was not intuitive.  When I finally got all the wires drawn on the GUI configuration, it failed to generate all the .h files and thus would not compile.  The first thing I figured out was I did not need the FreeRTOS component.  One thread in the project, no need for an RTOS, but I have to keep deleting it, since the configurator thinks I need/want it. 

I finally stripped the project down to just a console and then all the .h files were generated.  It appears once you get them generated, then the configurator will continue to update them,.  The trick is to get them generated.  Then I added the USB back in, generated the files and it still compiled.  A few more tweaks and the USB HID registered with the laptop and the console port started displaying messages.  So I have a basic system running.

But there is more fun ahead.  They have changed all the names of the common .h and .c files to something else as well as restructured them.  A lot of the common calls/types/functions have changed names.  It appears that many components that used drivers, no longer use them.  So the SysObj model for projects has changed.  When they said there was no compatibility between v2 and v3,  they meant none.  

One final hurdle.  The debugger will not load with MPLAB 6.25 and XC32 v4.40.  The message was 

 [ BootFlash ] at 0x1fc00490, expected 0x409bf800, got 0x00000000.
Could not enter debug mode because programming the debug information failed. Invalid combinations of config bits may cause this problem

which looks like a failure to load the Boot Loader memory, which I believe is where the debug module resides.  The config bits were the ones I have been using for a long time with this PIC32.  I thought this had something to do with the linker or the compiler version.  So I told the configurator not to generate a linker file.  That worked once.  I admit I did not go through this methodically, but in the end it looks like MPLAB 6.25 is the problem.  MPLAB 6.10 works every time, regardless of XC32 version.  I am still not generating a linker file so it using the default linker configuration.  

Not sure what lies ahead, but I am sure it will be challenging and frustrating.

 

Monday, August 14, 2023

MPLAB and XC8 - A Tale of Woe

Where I have been for the last week or so, on another barefoot journey across a LEGO pile with MPLAB and XC8 compiler.  Bottom line,  beware of C compilers claiming improved performance.

My very small Light Controller was depending on the 256 bytes in the EEPROM for config and script storage.  After config storage, that left about 220 bytes for the scripting.  But each LED takes 5 bytes to describe the time, command, state, features and PWM setting.  So a single time slot with all 6 LEDs changing can take 30 bytes.  Thus in 7 time slots all the memory can be used.  I had over 4K left in flash, so I decided to move the scripting there.  I had done this in one of the PIC32s that did not have EEPROM.

And the fun begins.  Harmony in the PIC32 had libraries for doing this, it was fairly easy.  I had written a boot loader for an older PIC, so this cant be that hard.  Well after 3 days on and off trying to make this work, I decided to change course.  Brand new MPLAB project with only the FLASH writing routines and using the MPLAB Code Configurator to generate the FLASH routines.  Their routines were essentially the same as what I wrote.  I could not see any difference that would make it work over what I had done.

But this did not work either.  I spent a huge amount of time trying to debug this with no change.  Then I spent a day reading every FLASH routine posting I could find.  90%+ were using the MCC routines I had generated.  Most problems were related to other things that I had already implemented.  Then I finally found one post where the person could not get FLASH to work.  Microchip told  him to change compilers.  There was an issue in 2.35 and that 2.36 fixed that.  Well 2.36 was a transitory release and I had a choice between 2.40 and 2.41.  Knowing that x.x0 and x.x5 is Microchips release schedule and any other numbers are bug fixes, I went with 2.41.  And what do you know, the dedicated program started writing to the FLASH.

Could it be that simple, of course not.  Compiled the Light Controller and it still failed.  Now to be fair I had slightly rearranged the MCC generated code to fit my overall structure.  So I went back to the dedicated program and pointed all the FLASH routines at my revised code.   Also renamed all the FLASH routines in this dedicated program directory so there was no way they would be included.  And it works just fine.  I then made sure the configuration bits were the same in both programs.  The last thing I did was copy the oscillator startup code from the Light Controller to the dedicated program.  Still works.

Startup code, project properties, compiler settings were the first things to look at and these were all the same.  Something in the startup code?  I cut out the test routine of the dedicated program and placed it as far in the front as possible.  Still would not work.  At this point almost a week has gone by and I am getting no where.  I have been taking breaks to work on other things, one to clear my mind and two to have some sense of progress. 

At some point I remembered some quirky things I had read about EEPROM unlock sequence.  Back to the dedicated program to trace through the assembly code to see how that worked.  The unlock sequence is 0x55 then 0xAA then set the write bit.  The green is the C code and the rest is assembly.  Nothing exciting here, what I would expect.

Then to trace through the Light Controller.  Both are using the exact same code base, there is no difference, no #ifdef, no changes at all.  There are two differences, either of which could cause a problem. Line #187, the BANK command.  Why is that there, that should have been before the sequence started.  Then the real problem is Line #193, another BANK command and inserted just before the write bit.  My understanding is that the unlock sequence is timed and set for exactly 5 instructions.  At a minimum, setting the write bit has to be the next instruction after loading 0xAA.

After some more reading I came up with this assembly code sequence for the unlock.  The C code using inline assembly is in green.  As you can see the generated instructions are exactly 5 instructions long and it works as expected.  

So after a week of messing around with this, it finally works.  I will probably go back and replace the unlock sequence elsewhere with this assembly version, just to make sure that somewhere in the future the compiler doesn't change it's mind and change the C code.
 


Thursday, August 3, 2023

Light Buddy 2 Scripting


Scripting is now coming in two forms.  

  1. Static LED that is time invariant
  2. Time based LED action


The time invariant scripting means that the user will setup the LED actions using this screen.  They will assign the LED effect, any features and the brightness (when available).  Using the LED option on the menu, they will store these settings in the Light Buddy 2.  When the unit powers up, it will load these settings and run forever.  This is equivalent to a one line script that is on repeat forever.

Time based is the normal scripting.  The user assigns the LED action at a given time, saves the step, increments the time base to the next event and continues.with the next LED event.

The issue with the Light Buddy 2 is the script storage.  There is no room for an external EEPROM.  The internal EEPROM storage is about 200 bytes once all the configurations data is set.  That leave about 40 script instructions.  But every LED effect takes an instruction.  If all six LEDs change at one time interval, then 6 bytes are used and that would allow for only 6 time intervals. 

There is about 4K bytes of program space left.  If I allocate 1K to script storage, that would allow for four times the storage.  Writing into program memory on a PIC is not difficult, but care must be taken as to not overwrite program storage.  This is my next task, so that I can increase the available script storage.




Friday, July 28, 2023

Software Progress

 

There is progress.  In this post I talked about interconnection of the LED lighting control and to some extent the Motor control. So I thing I am about at the 98% point.  Both the Brick Buddy 3 and the Light Buddy 2 are working at the same level.  This includes both PC control and Scripting.  I need to some more testing of the script interface, especially the loading of a Script, but after that I may declare victory and move on to the Android software.

The Light Buddy 2 implementation was much easier and went relatively fast. 

This is the LED Control GUI.  You will notice that is very similar to the first picture in the post.  The programming method used is that the GUI controls everything.  The GUI offers what the capability of the hardware is.  All of the underlying programming and communication knows nothing about the hardware.  There is a limit set on the number of LEDs and Motors this software can control and going beyond that makes no sense in the context of what this product set is intended for.

As an example, the Light Buddy 2 has six LED channels it can control and all of the are identical.  The Brick Buddy 3 has ten LED channels.  Nine of them are identical.  The LED 10 is just ON/OFF.  The GUI in the first picture shows that the Features and the Brightness are not available for LED 10.  The drop down control also only has OFF and STEADY in the box.  But after the choice is made for LED 10, the underlying software and firmware in the hardware, has no idea that there is a limitation.  

The Microchip PIC firmware is built on the same premise.  There is are multiple common modules that implement the control.  This control then passes through an abstraction layer in the firmware that implements the control on the hardware.

The scripting follows the same concept.  If the capability is not there, it is not available in the GUI.

I am hoping that this common interface will it make much easier for individuals to use this.



Monday, July 24, 2023

PICkit 5 First Look


 Greetings!   

Summer always seems to be the hardest time to Blog.  Between wanting to get outside and enjoy the fresh air and surroundings and working (specifically Blogging), the working is losing.  But things are happening.

First as I alluded to in this post, I have had concerns about the state of my PICkit 4.  I only use it on the processors that a PICkit 3 won't work on.  At this time that is 18F46Q71 that I use in the Brick Buddy 3.  It will sometimes get into a state that only a complete recycle of everything(PICkit, target PCB and the entire PC) is needed.  You cannot buy PICkit 4 anymore through distribution/Microchip.  I have become worried that the one I have will fail, which would really hurt my development.  This is the main reason I purchased the PICkit 5.  I am also hoping that it will do better with the new processors.

I installed MPLAB X version 6.10 (required).  I first tested with a PICkit 4 and the PIC18FQ71 Brick Buddy 3.  As stated in the previous referenced post, this combination and Version 6.05 would not work.  But with version 6.10, it worked just fine.  Changing out to the PICkit 5, still works as intended.  Now I have not tried any of the SD Card/BT features, so I cannot comment on those.  But the USB interface to MPLAB X works as you would expect.  In a month or two I will try to write more as I get more experience with it.  I am especially looking forward to using the SD Card/BT to program Brick Buddy's in a MOC.


 

 

Tuesday, June 6, 2023

Brick Buddy Scripting


 After days of working on this I may have made some progress. I had done some scripting work on the Light Buddy 2.  Both use the 40bit (5 bytes) format for a script command.  But it never really worked consistently and in the end I built most of those scripts by hand.  

This is the Script Window in the PC APP.  I have the motor section working.  It provides the ability to attach the corresponding sensor to the motor.  Then you can choose whether to have the motor reverse or stop when the sensor activates.  In a Brick Buddy 3, the sensor will only activate on the state going to ground.  Internally the sensor line is tied to 3.3VDC through a 100K resistor.  I wrote a simple script that turns the motor on and attaches the sensor with Motor Action set to reverse.  It runs until you press the button, which immediately reverses the motor.  This is going to provide some interesting possibilities for MOCs.

Here is the test setup.  A scrap PCB board that I attached four momentary SPST push buttons.  This allows me to test the sensor inputs.

What is missing in the scripting setup is the LED features selection.  I discussed the different LED styles and features in this post.  

On the Main Control Widow, I have a possible solution.  The issue is that the features are not mutually exclusive,  You can have multiple features.  In a traditional Windows Combination Box you can only choose one item.  This picture shows a combination box with individual check boxes for each item.  Thus you area allowed to choose multiple items.  The display of the current selections is not ideal, as you can see to the left of the drop down box.  Also the component does not allow for the drop down box to widen to show the selections.  This feature will require some more research. Ii really did not want to develop my own component, but I may have not other choice.

I did achieve my goal, I have written and installed the script for the Vertical Generator.  The Auto Start now works, so for Brick Fest LIVE, its apply power and it is off and running.  Next task is to do the same for the Vertical Generator.






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.


 

 

 

 

Monday, April 10, 2023

Brick Buddy 3 Its Alive

 

Well kind of.  The light flashes (see yellow arrow) which means the main loop is working.  As you can see all of the through hole connectors need to be installed and a few other parts.  I can start testing the LED control right a way and then move on to motor control.  The only mistake so far is on the back side.  I added an I2C EEPROM for more memory storage of scripts.  This type of memory does not have the restrictions on it as does using any left over program flash for this purpose.  The clip holds the Tag-Connect ICSP connection for the PICKit.  For now I am using the on chip EEPROM.  When the time comes, I will "jury rig" something to make the connection and have the memory.

But the first day was a roller coaster.  It works then it doesn't.  And it all came down to writing internal EEPROM with the debugger attached.  This is FYI for anyone using PIC18FxxQxx processors, but might apply to K processors also.  

I added the FTDI part (did not have the assembler do any backside parts), Windows recognized the FTDI part and my Brick Controller PC APP that controls all my boards connected just fine.  I needed to do some Win APP updates for this board, so I downloaded the firmware just to reduce the variables.  This is the same base code that runs in all boards.

It downloaded just fine and started running.  I disconnected the ICSP,  unplugged the USB and reconnected and nothing.😮  No lights, no connections, just nothing.  How do you find a problem, without a debugger.  Okay, the ICSP has three wires PGC, PGD and MCLR.  Has to be MCLR or some power up config.  Checked all of that, everything looks good.

I have an LED on a PORT pin.  So I built an infinite while loop that toggles the LED, just in case I needed to look at it on a scope. Put the loop as far in the beginning of the code as I could and it works.  Now I started moving the loop further down the initialization until it failed.  It failed while writing to the EEPROM.

I have base code that gets the serial number, evaluates it and then decides if it is valid (generally fails on all 0xFF, which is a new programmed part).  If it fails, it will save a generic serial number that will validate, but that I know indicates the serial number needs updating.  Also a good test of read/write of wherever the storage is.  I have had problems in the recent past with some newer processors (non Q type) where the solution was to use the library to read/write.  But for my code for this Q processor, I just followed the data sheet example.  When I tried to use the library, the compiler said use the MCC, the library is deprecated.  I examined the MCC generated code and other than using ASM in the lock sequence, there appeared to be no difference, except.....

All of these new processors are 24 bit address for ALL memory.  I noticed the MCC code was intentionally loading all three NVMADR registers.  Where in other processors with 256 bytes of EEPROM, the upper bits really did not matter.  Well in this PIC, they do, if you are not using the debugger.  With the debugger attached, you dont need to load the upper 16 bits, but a normal production start and yes you need to correctly load those 16 bits.  Don't understand it, but that is the way it works.

Now I can get back to updating the Win APP.



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.


Friday, March 24, 2023

How Not To Code

 

This is going to be a detailed technical post on MPLB X, XC8 PIC C compiler and how not to code a project.  Or to put it simply, how not to be stupid.

The above picture is a Curiosity HPC Development Board that I talked about in this post.  This was to help me get most of the code structure working for the Brick Buddy III as shown here.

The processor on the PCB is a PIC18F26Q71.  Fairly new, but with a very nice of features and lots of program FLASH and RAM.  But it was going to be weeks before I received one from assembly.  Thus the HPC was put into use.  Instead of putting a PIC18F26Q71 in the HPC (it does have a 28 pin socket underneath the 40 pin DIP), I chose to use the 40 pin version, a PIC18F46Q71.  The only difference between the two, besides the physical 28 pins vs 40 pins, is the PIC18F46Q71 has an extra PORT (PORT D).  

The Brick Buddy III code is a derivative of Brick Buddy II and Light Buddy II.  I have not started a project completely from scratch in a long time.  Using common libraries as I explained in this post means that only the main control loop and the hardware initialization is unique, unless there is a new peripheral of some kind.  Once I updated the initialization, I started compiling the code with the PIC18F26Q71 as the processor.  This PIC has the new I2C controller and thus there was a few days of just getting the code to compile.  During the compilation, there were multiple error messages having do with available PIC ports.  Brick Buddy II is a 44 pin device and thus has a PORT D.  All of this had to be changed to accommodate the PIC PORTS available on the PIC18F26Q71.

Once that was done I started trying to see if I could get some of the basic structure working.  This include the serial interface to the PC, the I2C EEPROM that stores configuration and scripts (which would also validate the I2C software driver for the LP5569 IC LED driver).  Finally working on the Bluetooth code for the RN4871.  This BT module is similar to the RN4020, but I am sure there will be some minor road bumps.

Once I had my standard LED heartbeat running, I moved on to the serial interface.  The PCB contains a FTDI USB to UART interface IC.  So I used one of my lab ones to connect the PC to the HPC Development Board with three jumper wires (Rx, Tx & GND).  And nothing worked.

Most PICs have a Peripheral Pin Select (PPS) module.  This allows you to move digital peripheral  features to different pins.  It is basically a large switch matrix.   Some PICs can move the peripherals to any pin while others will restrict a peripheral to a subset of the PORTS.  Thus there is code at initialization that has to be executed to move the peripheral output to the desired pin.  This is shown here

        #if defined(USE_PCB)
            INT2PPS = 0x01;         // assign INT1 to RA0
            INT0PPS = 0x08;         // assign INT0 to RB0
            U1RXPPS = 0x0B;         // assign Rx1 to RB3    --RN4871
            U2RXPPS = 0x0C;         // assign Rx2 to RB4    --Console
            I2C1SCLPPS = 0x13;      // assign SCL1 to RC3        
            I2C1SDAPPS = 0x14;      // assign SDA1 to RC4

            RC3PPS = 0x20;          // assign SCL1 to RC3
            RC4PPS = 0x21;          // assign SDA1 to RC4
            RB2PPS = 0x15;          // assign Tx1 to RB2    --RN4871
            RB5PPS = 0x18;          // assign Tx2 to RB5    --Console
            RC2PPS = 0x0D;          // assign CCP1 to RC2
            RC5PPS = 0x0E;          // assign CCP2 to RC5
            RC6PPS = 0x0F;          // assign PWM1 to RC6
            RC7PPS = 0x11;          // assign PWM2 to RC7
        #elif defined(USE_DEV_BRD)
            INT2PPS = 0x15;         // assign INT1 to RC5
            INT0PPS = 0x0C;         // assign INT0 to RB4
            U1RXPPS = 0x10;         // assign Rx1 to RC0    --RN4871     
            U2RXPPS = 0x0D;         // assign Rx2 to RB5    --Console
            //U2RXPPS = 0x19;         // assign Rx2 to RD1    --Console
            I2C1SCLPPS = 0x13;      // assign SCL1 to RC3        
            I2C1SDAPPS = 0x14;      // assign SDA1 to RC4

            RC3PPS = 0x20;          // assign SCL1 to RC3
            RC4PPS = 0x21;          // assign SDA1 to RC4
            RC1PPS = 0x15;          // assign Tx1 to RC1    --RN4871
            RD0PPS = 0x18;          // assign Tx2 to RD0    --Console
            RC2PPS = 0x0D;          // assign CCP1 to RC2
            RC5PPS = 0x0E;          // assign CCP2 to RC5
            RC6PPS = 0x0F;          // assign PWM1 to RC6
            RC7PPS = 0x11;          // assign PWM2 to RC7
            RD1PPS = 0x00;
        #endif

What this also shows is that I have a conditional compile. One version for the PCB and one for the HPC Development Board.  What I found was that UART2 Rx pin would not work on any of the PORT D pins, even though the data sheet clearly indicated that it good be moved to either PORT B or PORT D.  The UART2 Tx pin worked on any of the PORT D pins I placed it on.  I verified that there was a signal present using my Digilent Analog Discover 2 (which I highly recommend).  Thus I moved the UART2 Rx pin to PORT B and all was good.  I needed to make progress, so I moved on.  Though I did post in the Microchip Support Forum what had happened.

Well someone commented on the post.  When I read the comment, I immediately knew that person had the correct answer and I had fallen again for what I discussed a month ago in this post.  Embarrassment does not even begin to describe how I felt.

Here is the initialization code with the issue

    TRISA = 0xFF;
    TRISB = 0xFF;
    TRISC = 0xFF;
    LATA = 0;
    LATC = 0;
    ANSELA = 0x00;                //all digital
    ANSELB = 0x00;                //all digital
    ANSELC = 0x00;                //all digital
    ADCON0 = 0x00;                //A2D off
    ADCON1 = 0x00;                //+ref is Vdd and -ref is Vss
#if defined (USE_PCB)
    mLED_TRIS = OUTPUT_PIN;       // make it an output
#elif defined(USE_DEV_BRD)
    mLED_B_TRIS = OUTPUT_PIN;     // make it an output
    mLED_Y_TRIS = OUTPUT_PIN;     // make it an output
#endif
    

I had the foresight to place a conditional compile for the heartbeat LED (mLED_B & mLED_Y) to control the TRIS control for the pin.  But if you look directly above that, you will notice there is no mention of either TRISD or ANSELD.

Now TRISx controls whether the PORT pin is an input or an output.  The default is INPUT, but I always like to set them all to inputs and then let the code determine which pins are inputs and which are outputs. ANSELx controls whether the PORT is an analog input pin or a digital I/O pin.  The default is analog input pin, but again I choose to make all port pins digital I/O and then let the code set those pins that will have an analog input..  But this code fragment does not set PORT D to digital I/O and thus all the PORT D pins are analog inputs.

Now the quirk in these PICs is that a digital output (TRISx = 0) will override the analog input selection.  But a digital input will not override the analog input selection.  If you think about this, that only makes sense.  When you want an analog input ( e.g. ADC input) you will set the TRIS register to input and the ANSEL register to input.  The only setup for the processor to know that you want a digital input is the ANSEL register has to be set correctly.  So here is what the code fragment looks like now.

    // Make all digital inputs for now and let init routines set the tris bits that  need to be outputs.
    TRISA = 0xFF;
    TRISB = 0xFF;
    TRISC = 0xFF;
    LATA = 0;
    LATC = 0;
    ANSELA = 0x00;                //all digital
    ANSELB = 0x00;                //all digital
    ANSELC = 0x00;                //all digital
    ADCON0 = 0x00;                //A2D off
    ADCON1 = 0x00;                //+ref is Vdd and -ref is Vss
#if defined (USE_PCB)
    mLED_TRIS = OUTPUT_PIN;       // make it an output
#elif defined(USE_DEV_BRD)
    TRISD = 0xFF;
    LATD = 0x00;
    ANSELD = 0x00;                // all digital
    mLED_B_TRIS = OUTPUT_PIN;     // make it an output
    mLED_Y_TRIS = OUTPUT_PIN;     // make it an output
#endif

 

Live and learn, maybe😕


Tuesday, March 21, 2023

Solar Shed Update 2


 This is a really quick update.  The weather has been very cloudy the past few days.  So I disconnected the solar panel from the circuit.  The battery was at 14.40 VDC.  Three days later when I checked the battery, it was at 13.45VDC.  So it is obviously going to last one night and may last many days with little sun.

I have made the changes I discussed in the last Update Post.  They are installed, but there are issues.  This means I really need to take the laptop out to the shed and work on it there.  Most importantly the LED lighting turns on now. But it won't turn off.  The OLED does display the counts as an alternate screen, but it is updating too fast.  

Finally based on the voltge drop over 3 days, not sure what the super cap is going to add.  What it will do is stretch the battery out.  So if there is no solar power for many days and the LED lighting is used, it will stretch the battery in those circumstances.  Under normal operation, it is just providing a surge for the circuit.


Monday, March 20, 2023

MPLAB X Issues


I thought I would get a head start on the firmware for Brick Buddy 3 while waiting for the PCBs to arrive.  I would use the Curiosity HPC development board I had originally used in the Solar Shed project.  The HPC is on the right.

This is the only development board I have that would hold a 28 pin PIC.  I decided to just go with a PIC18F46Q71, which is the 40 pin version.  The attractive part is the two Mikroe Click sockets on this board.  One could be the RN4871 Bluetooth module and the other would some generic I2C Click board (I2C EEPROM memory) so that I can work out the I2C driver.  This was also driven by the need to check out the new common libraries I discussed earlier in this post. The Q71 family has the improved full featured standalone I2C module instead of the standard MSSP that has been in PIC18F for a very long time.  The PIC18F Q71 offered great PWM capability, 28 pin SSOP, good amount of memory ( FLASH and RAM) and some other goodies that escape me now.  Oh and I could buy it.  

And the fun begins.  There are now two versions of this Curiosity HPC.  All of the Curiosity boards have built in PICkits.  Well version 1 ( what I have) is based on PICKit3 and the version 2 on PICKit4.  And wouldn't you know it, version 1 of the HPC will not support the PIC18FxxQyy devices.  No biggee, there is a 6 pin ICSP header. I removed R13, R14, R15 which were the resistors on PGC, PGD and MCLR.  These three resistors connect back to the built in debugger.  Removing them isolates the built in debugger hardware.  I soldered on a 6 pin header to the ICSP pads, connect my PICKit4 and I should be good.

Well that was awful naive of me.  First off only the latest versions of MPLAB X will program these chips.  The earlier versions were happy to compile the code, but connect to the PICKit4, not happening.  So I downloaded the latest version MPLAB X  6.05.  It connects, blank tests, reads the memory, but when you program/debug it just hangs at the programming the configuration memory, which is the first memory area it tries to program.

This mess started last week.  I tested another 40 pin dip I had (PIC18F46K40), no issues.  So the connection is good.  So I must have damaged the PIC18F46Q71.  What else could it be.  

I was not smart enough to order two PIC18F46Q71 parts when I ordered the first one.  So another Digi-Key order and wait for arrival.  Side note: USPS delivered in 3 days, 1st class.

I then started again.  And the same result.  Posted in the Microchip Forums, not much help.  After trying all kinds of stuff, I finally went to another computer.  Maybe the computer is corrupted.  But instead of version 6.05, I installed the supposedly buggy 6.00.  And it works.  Went back to the original computer, removed 6.05, installed 6.00 and it works.  For grins, I re-installed 6.05 and it still doesn't work.  So not sure what the definition of "buggy" is anymore.

At this point I claimed victory and will just stick with 6.00 for this one project.  Filed a case and updated the forum with my results. Maybe it will save someone else the hassle. If you have acces to the Microchip forum and want more details, search for "SOLVED : PIC18F46Q71 will not program"

More than I thought to just get a simple development board up and running, but that seems to be always the case.😊


Wednesday, March 15, 2023

Building Common Libraries

Brick Controller 2

Brick Controller 3

 Light Buddy 1

Light Buddy 2


 I am up to four devices now that have some form of common LED lighting.  Two of which have motor controllers, the basic PWM interface.  As I keep developing new LED lighting effects, going back to each one of these devices and making the changes is getting too time consuming.  Not to mention that I am not getting consistent effects.  

Earlier I started on a quest to make a common library of firmware that can be updated and then automatically apply across all the device platforms.  After a few days of work and frustration 😎, I have achieved success.  Though there is still some testing to be done, but the basics work.  Here is a short description of how I got there.

The two LED controllers I am using right now are LP5569 and LP55231.  I use these because they are mostly firmware compatible with each other.  Though one is a low side driver and the other is a high side driver.  When I am not using these LED controllers, I use the built in PWM controllers in the PIC processors.  Finally when the LED is very basic, either off or on, then the control is the generic IO control of the PIC processor.  Regardless of the driving source, my hardware designs abstract the source away and present a consistent hardware interface of a low side driver.  

Both the LP5569 and LP5231 have I2C interfaces.  These were the only devices in any of these designs that had an I2C interface, thus the I2C driver was intertwined in the LP55xx code. The first step was to extract the I2C driver code and make it a standalone module.  While this was not difficult, it take some time to "unwind" all the code.  Now I can add other I2C devices, without having to include I2C driver code. 

Next was to unwrap the the LED effect (STYLE + FEATURE) from the driving source (LP55xx or PIC).  This meant creating two different modules, one for the LP55xx and one for generating the LED effect.  As has been described in previous posts, the LED effects reduces to a PWM value in either the controller or the PIC processor.  Thus the module I call PWMCtrl, generates this single PWM value for any 100ms time slice.  Then if a LP55xx is the destination, the value is passed to that module for writing into the LP55xx IC.  (Actually because of the way these ICs are set up, all nine channels are updated in a single transfer.  Thus I wait until all the LP55xx LED channels have their PWM values updated before transferring data.)  If the destination is the PIC processor, then it is a simple register update.

The final change was actually splitting the PWMCtrl module into a common section and a local section.  The local section contains all of the device initialization, the cooperative task function and any hardware dependence.  The common section is mostly the LED effects generator.  This code computes the PWM value needed. Thus I now have one place where all effects are calculated, which provides consistent looking effects.  I have not looked very carefully at this split.  There probably is a way to combine these through some MACRO definitions.  But that will be for later.....


Monday, February 20, 2023

Solar Shed Update

 

As I explained in the previous post on the Solar Shed, I redesigned the PCB, since the HPC Curiosity Board was consuming too much power.  My plan is to build this in phases (which was a good idea as explained later).  These phases will be and probably in this order:

  • DC-DC converter
  • 3.3 VDC LDO
  • PIC processor, buttons and LEDs
  • LT1085 LDO
  • Relays and FET drivers
  • ADC Input
  • Misc

Once the first three are done, I will work on getting the PIC firmware running.  May have to fake the ADC inputs, but that is OK.  Really all I will be trying to do is ensure the PIC runs and the buttons?LEDs work.  Once that is done, then the rest should go very quickly.

No Power

Following the list above I built the DC-DC converter section.  I literally took the design from the train LED controller, which works, and placed that design on this PCB.  Well there was no 5VDC.   My first thought was that the resistor divider network was in backwards, ie somehow the reference designators had not been placed correctly during PCB layout.  I measured the resistance in circuit, which is always iffy, since there is no way to see what the equivalent circuit really is.  The 20K measured 16K and the 120K, measured 55K.  So I pulled the 120K and replaced it with a 110K, that was in the original design.  Still no 5VDC.

Nothing was getting hot, the converter just wasn't starting.  I poked around with a DVOM looking at the voltages everywhere, other than no output voltage nothing seemed wrong.  Touched up most of the small solder joints, just to make sure they were connected, even though the DVOM showed connections.  Then did continuity checks where I could, still nothing.

 

Then I carefully looked at the inductor.  These can be hard to get the solder to flow onto the connections.  The picture shows what should be sufficient solder, but these are Lead Free, thus that is silver solder and will need more heat to flow properly.  Plus I didn't help the issue by using the very small tip on the Metcal Soldering Station.  I changed to the bigger tip (see picture below) and reflowed both connections on the inductor.  And that solved the problem😊.  Note to self, don't take short cuts, especially with the inductors and any parts that have silver solder on them already.


 

Installed the 3.3VDC LDO and the 3.3VDC came right up.  So I am ready to move on and install the PIC processor and related items.

This is why I try to build these in phases.  I have lots of experience building these types of boards by hand, but things happen.



Friday, January 27, 2023

Solar Shed - Update

 

We had 12" of snow and this completely covered the solar panel.  This caused the battery to completely drain.  That is the battery voltage was less than 10VDC.  Which leads me to this

  1. Probably need a cutoff relay to disconnect the battery when there is no charging voltage and the battery voltage falls below a certain value.
  2. If the battery is disconnected, then the controller needs power from somewhere else, probably a combination of the solar panel and a very large cap.
  3. Which leads to the Curiosity HPC board is not going to work.  Need a custom board that I can put to sleep to save power.  75-90mA is just too much current.

Oh well more fun designing.