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😕


Thursday, March 23, 2023

Cliff Wall Build Update 1

This is a simple update to show how the cliff walls are progressing.  I don't sit down and do one wall.  I find that I get into a pattern.  By working on different walls at different times, the pattern seems to stay more random.  The wall is 6 studs deep from the edge of the sand green walkway to the top of the cliff.  There are 3 studs at the base up to the first level.  Then one stud of depth is added.  This goes to the base of the top where another one stud depth is.  Finally at the top is the final single stud of depth.  Thus the cliff is fairly steep. 

Here is the start of one of the cliff walls.  This wall start is non-traditional as it has non rectangular slopes in it.  I tried to do something a little different.

Here this wall continues.  There is also a non-traditional portion of the left side.  Then I added a small platform for details to be added.  In this case it is minifig for now.

Here this one is done up to the final level going to the top.  This was finished with more traditional cliff techniques.

Here are two sections that are now done.  This one  is done in traditional techniques.

And this one has some non-traditional techniques.



Wednesday, March 22, 2023

Cliff Wall Interior Update 2

In the last post on the interior I showed mostly rendering of what was happening.  Now that I have worked out the door, I moved on to working on the interior detail at the first floor level.

In this picture you can see the large screen in the center.  The black portion will have a sticker with a screen something like this

This shows the back wall finished.  I included more brackets for more screens.  I looked at including clips for tools on either side of the large screen, but decided it would weaken the wall too much.  Unfortunately changing this later will be difficult.  The other side is the cliff with the multitude of slope parts.

I put in the light bluish gray flooring, two control panels and a few minifigs.Still need to install the overhead lighting and run the wires.  Somehow the wires will run down the right side behind the lime 1x1 round bricks on the right side.  There is a hole in the floor there which allow the wires to down and into the front right support where a connector will be installed.

The final part was to install the roof/second story floor.  If you look at a few pictures back, you see that there are two holes at the top of the wall that 6 studs apart.  This is for 1x8 beams that will help support the roof/floor.

Here is the structure.  The two 1x8 bricks are supported by two 2x14 plates.  The 2x4 bricks help hold the two plates together.  Two 2x12 bricks perpendicular to the 2x8s attach the floor to the side walls.

Then two 6x10 plates on the outside and two 6x6 plates in the center.  


 Not sure what goes on the second floor yet.  This second floor matches up with the gantry level on the hangers.  It could be office space with desks.  I need to add bunk areas but this is not the place to do it.  Or does a kitchen area make sense.  These need to be somewhere else.  For now they will be blank.



 


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.😊


Friday, March 17, 2023

It was a Cool Idea

 


A few weeks ago I mused on whether I had a crazy idea or something cool (Oh so 1960s).

Well I think it is very cool, especially in its first incarnation.  The picture above was the 3D rendering of the assembly.  Here is an assembled PCB

This is the size of 1x2 Brick plate. If you solder from the back, as I will in implementation, then a 1x1 plate/tile will fit in the center.  If you solder strictly on the top, then a 1x2 plate/tile will fit.  The four solder points on the right are a little tight and some care will have to be taken when attaching wires.  Using a 250W Weller Soldering gun and 0.1" diameter solder will be challenging.

The different colors on this discrete part have different illumination characteristics as shown here.

As I suspected, some experimentation was needed to arrive at the correct resistor values.  I have set a current limit of 15mA per resistor for all of my designs.  Most of the the Light Controllers have a minimum drive current of 25mA.  So the 15mA limit sets a nice margin.  As the chart above shows, the GREEN LED is the brightest of the RGB.  It appears to be equivalent with the white.  The RED has a lower Vf, which required a larger resistor to keep the drive current under 15mA.

I needed something to test in.  I have been playing with this Design.

I started modifying this to accommodate the LED PCB.  First it needed to be in the center of the 8x8 plate.  Then I needed a way to suspend the 2x2 transparent light blue round bricks over the center, so that the light will go straight up the column and out the spire (Antenna 4H) on top.  Finally there was going to be some stack up issues when using plates and bricks and I need a way to extend the round bricks.

Here is the first step.  A 4x4 plate with a 1x1 round plate in the center.  The round plate is needed, since it fits inside the 4 studs at the center of the 4x4 plate. I glued a 1x2 tile on to the back of the PCB.  Since there are no tubes on the back of that tile, it can slide on the 1x1 round plate.  After centering the PCB I placed 1x2 bricks on the left, right side and the top left corener.  I used 1x1 round plates in stacks of three to finish the top section.  This allows the wires to pass through the gaps.  Then at the bottom (in the picture above orientation) I used 1x1 round bricks at the corners and the same stacks of 1x1 round plates in the two center positions.  This was needed to accommodate the wires that I soldered on the top, with the wires coming straight off the PCB.  If I had soldered then from the bottom, then a 1x4 brick would have worked. 

This picture shows the 4x4 assembly attached to the 8x8 plate that is on the bottom and the surround support wall, with a gap for the wires.  Now I need to support the transparent round bricks.  Modifying a brick was a possibility, but then I remembered technic plates.  They don't come in Tan, but I am not sure that matters here.

This shows the technic plate in place.  Next was a mismatch in the round brick height and the large  top (8x8 dish) that goes on top.  The round bricks actually hold this top in place, it doesn't seem to want to grab the studs on the macaroni pieces.  In the stack up that was needed to capture the LED PCB and the technic plate caused the transparent round bricks to be on plate short.  So I placed four light blue transparent 1x1 round plates on the technic plate as the picture above shows.  At first I thought I would have to drill out the technic plate hole to let more light through.  Then these four 1x1 plates sort of restrict it even more.  But as the videos below show, there is plenty of light.

So that brings back to this.

You can see the Light Buddy 2 controller on the right.I am not sure this is the final iteration of this design.  I would prefer to have the controller embedded in the unit.  Four of the six LED Channels are used, so there is no need to have it control other devices.  With some more thought, I am sure I can come up with other uses for those two LED channels.

So here are the videos. The first is in minimal background light and the second is almost full background light.  Unfortunately the camera does not have a large amount of dynamic range in light.  Thus the LED lights tend to over power the camera.  It looks much better live, but these videos give a good indication of what it can do.

Now that I see what this can do, I already have come up with RGB specific effects.  More on that later.

Minimal background light. 


 Full background light.









Thursday, March 16, 2023

Solar Shed Update


 

A quick update on the Solar Shed progress.  The snow has melted and there is some sun.  I have not been formerly taking down readings, but in general the battery has charged to slight over 14VDC on it at the day and about 13.8VDC in the morning.  Which is comparable to what I saw on the bench.

Moving to the real world is always going to bring on new issues.  What problems did I have, well 😛

  • For the switch that turns on the LED Lighting, for some reason the weak pullups on that input was off.  The overhead LED  lights would go on and off randomly.  I was never a fan of those weak pullups, not sure why I did not just put a 10K or 100K pullup there.  Space and cost were not a driving factor.
  • Next this switch does not wake up the PIC.  When is the PIC sleeping, at night .  When do I need the light, at night.  It is a simple fix, but I am waiting to gather more changes before fixing this.
  • I had added a relay for selecting power source for PIC and etc, from either the battery or the solar panel.  I implemented the logic to use the Solar Panel as the power source whenever it is above about 8VDC.  But forgot to change the TRIS register for the drivers to an output.  No wonder I could not drive the relay to change the source.  Now as long as there is sufficient solar panel voltage, that powers the PIC and etc.
  • All of the conversion constants moved a little, again.  1% resistors are nice, but they are still only 1% accurate.  Another change is to add an OLED screen that shows the ADC count instead of a calculated voltage.  Maybe that will help refine the conversion chart I showed earlier.
  • The 7.5F supper cap took over 2 mins to charge the first time.  I thought there was a short somewhere since the voltage would not rise.  Then I remembered that an uncharged cap is a short. 

I have been thinking of a good test for the super cap.  What I am thinking now is around 8PM disconnect the battery.  The sun will be down, so no solar power.  Then before the sun lights up the solar panel, check if the PIC is still in sleep mode.  One way is to press one of the buttons that will illuminate on the LEDs.  It is a left over debug routine, that is actually quite useful.  The other is to measure the voltage at the Suoer Cap and see if it is providing sufficient voltage.  Then this test needs to be repeated without the OLED installed.  

The process continues.