Software

Links to software topics:

Communication between computer and device

Data format

One possible format would be to send a list of tuples (start time, duration, color, which LED). This probably wouldn't work well for the gradient though. If we have predefined gradients that the device is aware of, we could have say gradient 1 be a red gradient, gradient 2 be a blue gradient, etc, and then we could have a format of like (gradient number, start percent, end percent, start time, end time, which LED) where start and end percent is the distance into the gradient to start and end, and the device would use how much time you want it to take to go across that gradient and use that to show the appropriate color in the gradient.

During one of our meetings, we discussed an alternative. We feel we can assume we will have 8 colors/gradients or less. Thus we need 3 bits per LED to represent which gradient. If we assume we want to use 2 bytes for a time period, we can assign one byte to each LED. Since 3 of those 8 bits will be which color/gradient, that leaves us with 5 bits for other stuff. We can divide each gradient up into 32 (2^5) discretized levels and use those 5 bits to represent which level in the gradient you should be at that time period. Using this method we need 2 bytes per time period, and we decided a simple way of doing things would be to make a huge map in memory representing a long period of time where every 2 bytes represents a time. However, the RAM on a microcontroller is pretty limited so there will be a limit on how many discrete time events we can represent. We have to impose some sort of time granularity on the apps in order to fit it all into memory if we use this method. What we can do is the device can look at what color it was supposed to be at the last discrete time step and what color it is supposed to be at the next discrete time step and figure out how far between thsoe two steps it is, and adjust its color such that it will make a smooth transition from the one step to the next.

Some calculations:
24 hours in a day
60 minutes in an hour
=1440 minutes in a day

2 bytes per time step

granularity of 1 minute = 1440 time steps * 2 bytes = 2880 bytes per 24 hours
granularity of 2.5 minutes = (1440 minutes / 2.5) time steps * 2 bytes = 576 time steps * 2 bytes = 1152 bytes per 24 hours
granularity of 5 minutes = (1440 minutes / 5) time steps * 2 bytes = 288 time steps * 2 bytes = 576 bytes per 24 hours

Since RAM on microcontrollers are pretty limited (probably only around 4kb), and the program needs some space to run in, this massive lookup table limits how much time we can keep track of on the device.
At 1 minute granularity, we can keep track of 24 hours of data. This means that a person would have to sync once every 24 hours.
At 2.5 minute granularity, we can keep track of 24 - 48 hours of data.
At 5 minute granularity, we can keep track of 24 - 120 hours of data.

Most people schedule things to occur on the 15 minute markers (usually even on the 30 minute markers) so 5 minute granularity should be fine for a scheduling app. However, some plugins may want more than 5 minute granularity. We have to decide on a granularity.

This method was designed because of its simplicity (the device just needs a pointer that moves along two byte blocks, some logic to wrap around and keep track of which day you are on, the sync-ing logic, and some lookup tables to translate a gradient number and gradient step into the outputs to the LEDs, and a timer to keep track of time, plus probably some other small pieces of code). This method was also designed to gracefully handle the possible worst case scenario of having events (this applies more to the widgets) very often. An alternative method would be to keep a data structure of time and gradient information but this would require more than 2 bytes per LED. Thus, if a widget requires the colors to change very often, the microcontroller could possible run out of information.

We could allow the app to let the person set the granularity and if a widget needs a finer granularity, if the person wants the widget displayed, the device can change its granularity and adjust all events accordingly. However, before this is done, the user should be warned that syncing will take a while since the laptop has to transmit a lot of data and the device has to do a lot of shifting of memory.

We could cut the number of available colors down to 7 and use a value ov 3'b000 in those 3 bits to represent the start of a time block where no events could occur and the other 5 bites could represent how many time blocks to skip. This would allow you to compress 32 event blocks into 1 event block if no events occur in those 32 blocks.

Using the above, we could have the app automatically compress the data to save space. However, if something in the app decides to schedule/make something appear in one of the compressed areas, all memory after it has to be moved backwards in order to create an event block for this new event, which could be time consuming.

We could allow the app to let the person specify time when they are "asleep" and the orb should be "turned off" during that time. Then the app could compress the event blocks (using the above method) for the period where the person is sleeping. If the person wants to change when they are sleeping, you can have the app warn them that all event data will have to be re-sync-ed and that may take a while.

Another hack is to have each LED have its own block of memory (instead of having it go through 2 byte pairs). That way the LED's can use separate granularity. We can say each LED gets 1440 bytes of memory (which is enough memory for 24 hours of data at 1 minute granularity) and what ever widget controls that LED gets to set the granularity of those 1440 bytes. Thus, we can have the scheduling app set the granularity to 5 minutes and get 5 days worth of scheduling information on the orb at one time, but have a stock market or bus schedule app set the granularity to 1 minute and only get 24 hours of data.

Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-ShareAlike 3.0 License