The Let's Play Archive

SHENZHEN I/O

by Quackles

Part 22: Post-Assignment Optimization #2: Building a Better Buzzer

Building a Better Buzzer

Wow, thanks for your outpouring of support! It looks like there were, in all, three different 'camps' of solutions. I'll discuss each in no particular order.

And Gate Version

pumpinglemma posted:

I see a way to cut the cost and maybe the power - you could replace dat's role by p0, throw in an AND gate between p0 and p1, and switch out the MC6000 for the cheaper model.

But I certainly don't think that would give a 30% reduction.





This was a clever idea - abstracting the "pulse AND on" logic to a logic gate. It's certainly cheaper than my final solution (¥5 / 284 pwr), at ¥4 / 238 pwr (16% reduction). The fact that it still pulses every time unit is probably what keeps the MC from saving too much power, but it's pretty smart. Thanks @pumpinglemma!


The next two versions both rely on a fact I'd missed about the radio:

RichardA posted:

Hint2: The radio has an internal buffer.

Meaning, that when data comes in to the radio, you don't need to read it on the same time unit as when it shows up. The radio will hold the data in its buffer until you're ready.
I'm at least half tempted to blame the datasheet for being unclear, even though I did quote the relevant line (ft "buffer") right in my post.

With this in mind, you don't have to check the radio when a pulse is being made - just when you'd be about to make a pulse.


Buffered Radio - The Hacky Solution

I call this version The Hacky Solution because, at a certain level, it's a hack, relying on the fact that the doorbell (transmitter) always sends a 1 followed by a 0 later. This is exploited because it toggles on or off whenever any data is received, not bothering to check the packet's actual value.





While this solution is certainly efficient in both cost and power (¥3 / 146 pwr - 49% reduction), it does have the pitfall of potentially getting stuck so that the buzzer is on when the button is not being pushed (perhaps if the 'off' data packet is lost due to signal interference) with no way to get it back to normal (pressing and releasing the button won't reset it).

I don't normally make hacky solutions on the job out of respect for the intention of the specifications, but it's a cool optimization! Thanks, @Sydin and @Grayshift!


Buffered Radio - The Clean Solution





This solution is basically the same as the Hacky Solution, except it stores the data packet in acc and checks the value before pulsing (or not). This is what @RichardA was hinting at - thanks Richard! - with his hints.
The solution uses ¥3 and 176 power (38% reduction) - David is happy to hear about the improvement, and it looks like this is how it's going to go out on the market!


Reader Comments and So On

Carbon dioxide posted:

I think a much more sensible way to do this than using nops is by using the X-bus because an X-bus connection between two chips will block the reading chip until the writing chip is ready to send something. I wonder how much power it would save to take the prototype and change nothing other than making the inter-chip connection using the X-bus and removing the nops.

It's a good idea, but there's a fly in the ointment. XBus doesn't really work like simple I/O, where the data is always available after it's been written. For each XBus read, there has to be exactly associated XBus write - you can't read the same packet twice after writing it once*. And if you write a packet, there had better be someone to read it in the same time unit or the writing MC blocks and it's an error.**

So, even if you have MC #2 wait for XBus to turn on, you either have to keep sending XBus packets every time you want MC #2 to pulse - and if you send a packet during the pulse while MC #2 isn't listening, error.

*I/O Expanders don't work like this, because they don't have code and so always respond to every XBus read/write as it comes in.
**I'll explain more about this in my upcoming post.


I did think of a hybrid approach where MC #1 signals MC #2 to turn on with XBus, and then sets a simple I/O pin to tell MC #2 to stay on (or not). Of course, then, you're back to needing at least one nop to adjust the timing...



 

(In case you're wondering: ¥6, 279 avg power.)


mercenarynuker posted:

I know everyone is posting streamlined elegant solution ideas, but could we see some kind of burly, over-engineered, trashy solution to one of these as well?

Believe me, just hang around me long enough and I'll post a few of those. :P


klafbang posted:

I agree with this, and add that I also like that the "best" solution isn't shown but left as an exercise to the thread.

I'm not gonna do this every time, but the more a problem bothers me, the more likely I am to ask for help.


TooMuchAbstraction posted:

It bugs me that you can use nops to precisely align instruction execution timing across two different chips. That doesn't feel very realistic to me.

This only works 'cause they're both 诚尚Micro MCs, the chips have the same effective clock speed, and every instruction (not counting slp or XBus-I/O instructions, which we're deliberately not using) takes the same amount of time to run. I don't think I'd be able to pull it off, otherwise.

RichardA posted:

Also in the Infrared Sensor it might be possible to fit in a slp acc, with acc being the time until the sensor is armed instead of looping and checking each time-step.

I'm going to work on this and get back to you, actually. That's a good idea - the only issue is that the calculation of how long to wait vs run only needs to be done once - but there's also the consideration of how long to wait or run the first time when the device is started in the middle of an off (or on) period.

Carbon dioxide posted:

All you need to do is have your design pass a bunch of test runs.

In the words of Jie (I may be paraphrasing a bit): "There is a difference between finishing a design and finishing a design well."


BTW, here's the radio's full datasheet.



Anyone want to take any guesses on how you're supposed to pronounce "C2S-RF901", exactly?