POV / Propellor Display - Part1

A forum where Flowcode v6 user created components can be shared, discussed and reviewed.

Moderator: Benj

Post Reply
User avatar
Benj
Matrix Staff
Posts: 15312
Joined: Mon Oct 16, 2006 10:48 am
Location: Matrix TS Ltd
Has thanked: 4803 times
Been thanked: 4314 times
Contact:

POV / Propellor Display - Part1

Post by Benj »

Hello All,

I think I may finally be onto something with the mechanics for my hobby propeller display project so I have started to create a Flowcode 6 component to allow me to simulate and develop better firmware.

I am sharing here so that others may benefit from being able to create components with simulations.

Previous working prototype using Flowcode 4 for dsPIC.

[/youtube]

To start with I have created the basis for the simulation which is auto generating the panel objects based on the users property selection.

First I made a few properties to allow the user to change things, number of leds, number of segments, I/O etc. I also included properties to allow the simulation to try and replicate the physical display as much as possible such as LED size, pitch and spacing from the central pivot.

Once the properties were in place I went to the events tab of the project explorer and added a macro for the component -> property event. This macro then fires whenever any of the property values are changed.

Inside the property event macro I added calculations to allow the various properties to correctly calculate some helpful values that might help the end user.

The next job was to create the objects on which to host the simulation. I started by dragging a sphere object onto the panel, giving it a suitable name and then copy/pasting the object on the panel. I selected both objects and clicked the group button to create a new group which I also renamed with something sensible. I then double clicked the original object and changed the visible property to false.

The Sim_DestroyLEDs macro uses the Tree simulation API commands to move through the components on the panel in the group. It deletes all the objects inside the group except for the none visible template object by comparing the objects name with a hardcoded value.

The Sim_BuildDisplay macro takes the position of the none visible template object and then draws the LEDs outward from the center a segment at a time. We do this by working out the vector based on the number of segments vs the current segment index and then moving the position object by the spacing property multiplied by the vector.

Calls to the Destroy and Build macros were then added to the property change event as well as a simulation API call to resize the template object.

Thoughts so far...

The LEDs take a long time to generate if a high number of segments is used. I think on my display I used between 120 and 360 segments so that's lots of pixels to create and maintain. This means the simulation will likely run slow too. You may get a popup saying that the event macro is taking a long time, simply click no and the full display should be drawn eventually.

Therefore I wonder if I can change things up so that the number of segments is automatically reduced as you get closer to the center of the display. This would certainly provide a more efficient way of doing things and should also look better on the physical display. The downside to this is the routine to clock out the data to the LEDs would become more complex and ideally this needs to be as fast as possible to maintain a nice lit pixel and to allow some room for the main application to run.

Here is the component source so far.
POVdisplay0.1.fcfx
(332.28 KiB) Downloaded 521 times
If anyone wants to know more about creating components then these videos might help get you started.

https://www.youtube.com/watch?v=O41_diP ... EGDynfBCsf
https://www.youtube.com/watch?v=RWZcctF ... Fvp-GxBLgc

More to come soon...

User avatar
Benj
Matrix Staff
Posts: 15312
Joined: Mon Oct 16, 2006 10:48 am
Location: Matrix TS Ltd
Has thanked: 4803 times
Been thanked: 4314 times
Contact:

Re: POV / Propellor Display - Part2

Post by Benj »

Next I added A property to allow double buffering to be switched on and off. I found that double buffering can greatly improve the display performance as you can write object to the display RAM and then only show the new objects once you have finished the draw routine. Otherwise you may occasionally output a display signal which is midway through a draw.

I was already getting tired of the display redrawing everytime I changed a property value so I created a variable to store the value of the pixel count and to only redraw the display if the calculated pixel count property changes.

Each pixel on the display requires a section of RAM to hold the current colour value we want to display. I created a byte array named Data and used the GetVarSize event macro to override the size of the array to match the memory size property. The simulation has a vast amount of PC memory available and so will grow the array size as it needs so we don't need to worry about it. Each pixel colour is held in a byte allowing for 8-bit output or 256 individual colours (including off/black). 16-bit colour might be possible depending on how fast your uC is. I will look into creating a variable colour bit size control soon.

The last thing I wanted to add at this stage was a way to set the colours and have them drawn on the object on the panel. I created a new macro named SetPixelColour with parameters for the pixel address and the colour we want to write. As far as the embedded code is concerned we simply assign the colour value to the memory location and the microcontroller will automatically clock out the right value as needed. For the sim we need to do a bit more work via the simulation API calls.

I added the refresh macro to allow the simulation to update when double buffered mode is active. Again the embedded code to do this is as simple as toggling a boolean variable but the simulation also requires that we update the colour of all the LED objects in a single pass.

As we now have colour control I also quickly added a clear macro to initialise the display data and allow us to clear the display buffer.

Here's a screenshot of the test program with 60 segments.
PC1.png
(121.32 KiB) Downloaded 5219 times
Here's a screenshot of the test program with 240 segments, this is the resolution I was previously running the hardware at.
PC2.jpg
PC2.jpg (136.6 KiB) Viewed 8847 times
The white square you can see in the center of the display is the hidden template LED object. This will disappear from the panel when we export the code as a Flowcode component.

Here is the current source code.
POVdisplay0.2.fcfx
(984.44 KiB) Downloaded 548 times
Next I will start on the embedded side code to clock out the data.

User avatar
Benj
Matrix Staff
Posts: 15312
Joined: Mon Oct 16, 2006 10:48 am
Location: Matrix TS Ltd
Has thanked: 4803 times
Been thanked: 4314 times
Contact:

Re: POV / Propellor Display - Part3

Post by Benj »

Here is part 3 of the propeller display component which will focus on clocking out the LED driver signals.

This consists of two key elements.

1) The code to clock out a segment of RAM to the LEDs and perform the PWM to control the RGB channel brightness. Called automatically as part of a timer interrupt.

2) The code to detect a full revolution and adjust the timings of the timer interrupt driving stage 1 so that the correct number of segments is displayed. Called automatically as part of an edge driven interrupt (INT) or masked port interrupt (IOC).

Part 1 was done by creating the PWMControl macro. This checks a global variable for the current sector address and then clocks out the data. I added a colour mode property to allow the user to decide between 3-bit colour or 8-bit colour. Then in the PWMControl macro I started with a decision icon to detect which colour mode was active. The decision is based on a property which is essentially hard coded into the C when you compile to the hardware meaning there is no impact or "bloating" to the generated code.

The two methods to clock out the data are very similar, they involve blanking the LEDs and then loading the output data port with 8 LED signals before toggling the clock pin. The output and clock is repeated until every buffer in the chain has the correct value and then the final 8 LEDs are driven directly from the microcontroller port. The instructables guide has all the information in terms of the circuitry required to drive the clock.

At the end of the macro we move to the next sector address for 3-bit mode or we repeat 3 times to clock out the PWM signals for 8-bit mode before moving on.

Example of 3-bit colour
3-bitColour.jpg
3-bitColour.jpg (94.13 KiB) Viewed 8842 times
Part 2 was done by creating the SpinSync macro which checks the sector address against the required number of segments. When everything is correct and up to speed then the timer will have fired the correct number of times to allow the sector address to match the required number of segments so we don't need to do anything. If the sector address does not match the required count then we alter the timer frequency by altering the rollover value. With this code in place the motor can speed up or slow down and the display should always try and auto fill the correct number of segments. I will later add a variable so we can track and monitor the number of revolutions per second, for example if we wanted a blank display until the motor is up to speed.

The PWMControl macro is farly hardware dependent as it involves changing the timer rollover setting. I have done the code for the chip I am using (dsPIC33FJ128MC204) and the timer I have selected for the job (Timer1). If you have a different chip/timer in mind then let me know. Maybe I could somehow do this more universally via a property where you can enter the C rollover register.

Using the scope I can monitor the outputs to see how the signals will be clocked out in both 3-bit and 8-bit colour modes. I setup the scope by creating a macro tied to the component -> initialise event which calls the macros required to setup the scope traces. This is useful for simulating signals but can also be used with Matrix Ghost enabled hardware and ICT to actually monitor the signals in real time. Unfortunately it is not that easy to fix a E-blocks rig to spin at high speed :D but the Ghost could be used for early sanity checking to ensure things are running as they should on the chip.
PC3.png
(30.75 KiB) Downloaded 5205 times
I noticed the component was still redrawing the objects even when the number of LEDs was not changed so I moved the backup value from a variable into a second hidden property and this is now working much better.

There were then additional edits to the set colour and refresh macros to support the 3-bit colour property. The set pixel colour becomes quite complicated to insert the 3-bit colour into the correct place in the VRAM DATA buffer. For 8-bit colour mode the additional complication moves into the PWMControl macro as we have to work out the LED bit patterns on the fly based on the PWMcount variable. Isn't it fun making versatile components. As long as you keep a clear mind on what your doing and take things a step at a time it is far less daunting.

To help reduce the code in the embedded functions I have started creating simulation macros which will venetually override the embedded macros when the simulation is running. This helps to ensure that no extra code required for the simulation is included in the embedded download. Things like simulation API calls will automatically be removed for you but things like calculations using standard variable types will not. The simulation override is performed in the interface manager but will not become active until we export the program as a component.

I also fixed an inconsistency in the simulation where address 0 was in the center of the display, on the hardware this is the first byte clocked out so it is on the outside of the display. This involved a few minor changes to the Build Display macro to reorder the way the objects are drawn, from inner-> outer to outer->inner.

Here is the latest source.
POVdisplay0.3.fcfx
(405.97 KiB) Downloaded 463 times
This is probably one of the bigger and more complex updates, from here on in it should be fairly simple to add the draw routines and create animations.
More soon...

User avatar
Benj
Matrix Staff
Posts: 15312
Joined: Mon Oct 16, 2006 10:48 am
Location: Matrix TS Ltd
Has thanked: 4803 times
Been thanked: 4314 times
Contact:

Re: POV / Propellor Display - Part3

Post by Benj »

I have now released the full build guide on Instructables if anyone fancies building their own display.

http://www.instructables.com/id/Ultimat ... r-Display/

More work on the component to come soon...

Post Reply