Author Topic: Staples Easy Button  (Read 16980 times)

Chuck Claunch

  • Newbie
  • *
  • Posts: 11
Staples Easy Button
« on: March 08, 2014, 11:50:55 am »
Hello, I'm new to these forums and new to the Digispark.  I'm a software developer by trade and dabble in hardware projects.  At work we have a few of the Staples Easy Buttons and I thought it'd be fun to hack one up and change the sound that comes out (we particularly like the idea of The Price Is Right's "lose" sound for when someone screws up).  I also think it'd be fun to get a 3D printed button that says "fail" instead of "easy". 

I've searched all over and found this project which plays audio via an ATTiny85: http://elm-chan.org/works/sd8p/report.html.  It seemed like a good starting point, however I don't need it to be that complicated.  I also saw this PIC based project:  http://www.instructables.com/id/YEAAAUGH-WHHAT-OKKKAY-Lil-Jon-Easy-Button/step2/Soldering-it-up/ which seemed nice, except I didn't care to go PIC.  I do like his use of a program to convert the wav file to an array which can be included in the software.

So my requirements are:
  • Re-use the Easy Button case, with no outward appearance changes.
  • Re-use the Easy Button's two AAA batteries to power it.
  • Re-use the Easy Button's simple speaker.
  • Play the sound then shut off (so it's not constantly powered)

My current status is I have the Digispark with headers soldered on and the blink program working!  I figure my next step is to figure out how I'm going to power it.  Is it possible to use two AAA batteries to power it long enough for a quick sound to play and then shut off?  My first goal is to get it hooked up to the button and have the blink program run for say, fifteen seconds, then shut off.

Any suggestions / links / constructive criticisms are appreciated!

-Chuck

JeffRand

  • Newbie
  • *
  • Posts: 44
Re: Staples Easy Button
« Reply #1 on: March 12, 2014, 07:20:31 pm »
If you want to power it with two AAA batteries (~3v), you're going to need to boost the voltage. The boost shield should help with that. http://digistump.com/products/12

I was thinking about how you would go about powering it completely off. Maybe a relay that is energized when you press the button, then the Digispark would keep it energized until it is done playing the sound. Once the sound is finished the Digispark would release the relay disconnecting the power again, until the next time the button is pressed.

Chuck Claunch

  • Newbie
  • *
  • Posts: 11
Re: Staples Easy Button
« Reply #2 on: March 12, 2014, 08:30:37 pm »
Oh ok, didn't realize I'd need to boost it.  I could possibly just modify it to take a different battery.  Would a 9V be ok?  I also don't terribly mind the possibility of just powering it via USB, as it does just sit on a desk, after all.  I suppose in the case of powering via USB it'd just be "on" all the time and any time I hit the button it would reset the Digispark and play the sound?

JeffRand

  • Newbie
  • *
  • Posts: 44
Re: Staples Easy Button
« Reply #3 on: March 13, 2014, 06:01:08 am »
A 9V battery would be okay as long as you make sure to wire it to VIN, so that the on-board regulator would bring the voltage back down to 5V. You wouldn't get a lot of life out of it though. A 9V battery is actually a bunch of smaller batteries in series.

If you power it over USB, you could leave the Digispark running and connect the button to one of the input pins. Then each time it see's that the button is pressed, it could play the sound. Doing it this way would eliminate the wait you would have when the Digispark is reset.

The Digispark normally waits for 5 seconds on startup, to see if you're going to program it. The only way around that would be to change the bootloader to one of Bluebie's jumper versions that would go right to your program without delay. See http://digistump.com/wiki/digispark/tricks for more details on eliminating the 5 second delay.

Chuck Claunch

  • Newbie
  • *
  • Posts: 11
Re: Staples Easy Button
« Reply #4 on: March 13, 2014, 04:44:29 pm »
Cool.  I thought I read somewhere about a "sleep mode" of sorts?  I can't seem to find it now.

JeffRand

  • Newbie
  • *
  • Posts: 44
Re: Staples Easy Button
« Reply #5 on: March 13, 2014, 05:09:12 pm »
I just looked at the datasheet http://www.atmel.com/Images/Atmel-2586-AVR-8-bit-Microcontroller-ATtiny25-ATtiny45-ATtiny85_Datasheet.pdf and it does have a sleep mode that will reduce the power consumption. Although it wouldn't be completely off. You can wake it with an interrupt that can be triggered by a pin change.

I haven't tried using sleep mode, but it shouldn't be too hard to set up.

Chuck Claunch

  • Newbie
  • *
  • Posts: 11
Re: Staples Easy Button
« Reply #6 on: March 14, 2014, 08:11:58 am »
So I'm working on the generate the sound part of the project.  I saw a very simple example for the analog write, and since my sounds will  just be a giant array of analog values, I figured my first attempt (just to get something to come out of the speaker) would be to loop through and write some values to the output and just hook up the speaker.  The result is basically a kind of a siren sound (sweeping from roughly 1KHz to 5KHz, according to an analyzer app I have). 

Here's the code that did that:
Code: [Select]
void setup()
{
  pinMode(4, OUTPUT);
}

void loop()
{
  for (int i = 10; i < 230; i++)
  {
    analogWrite(4, i);
    delay(15);
  }
}

It's obvious from my example that I need to get that frequency way down (talking/music needs to get much lower than 1KHz).  So the next part to figure out is how to set the PWM output.  I saw a nice example for Arduino here which is well commented, but I'm not exactly sure how those TCCR2A and OCR2A, etc settings apply to the DigiSpark.  I'm also not sure if/how I can set the DigiSpark to "use internal clock" or "set fast PWM mode".  Any ideas?

JeffRand

  • Newbie
  • *
  • Posts: 44
Re: Staples Easy Button
« Reply #7 on: March 15, 2014, 06:09:33 pm »
Hey, I did some searching and found this youtube video. http://youtu.be/SsoAYs4A24Q

It has a link to http://elm-chan.org/works/sd8p/report.html. That software should be a lot easier to use, since they have it working for the ATTiny85.

Do you plan on adding some external storage for the sound samples? You won't have much room on the Digispark itself.

Chuck Claunch

  • Newbie
  • *
  • Posts: 11
Re: Staples Easy Button
« Reply #8 on: March 15, 2014, 09:32:15 pm »
Yeah thanks!  That is exactly the one I found as well (linked in the original post).  That's one reason I chose to go with the Digispark.  I figured if the ATTiny85 could do that then surely I could get a Digispark to simply play a single sound.  I think his project is much more complicated than I need to get, as I just want it to have a single sound and have no need for the SD card reading.  I've gotten that part taken care of with that other library which converts a sound file to a header file of bytes.

In that guy's play() function, some of the stuff is unfamiliar to me:
Code: [Select]
FRESULT play (
const char *dir, /* Directory */
const char *fn /* File */
)
{
DWORD sz;
FRESULT res;
BYTE sw;
WORD btr;


wdt_reset();

xsprintf((char*)Buff, PSTR("%s/%s"), dir, fn);
res = pf_open((char*)Buff); /* Open sound file */
if (res == FR_OK) {
sz = load_header(); /* Check file format and ready to play */
if (sz < 1024) return 255; /* Cannot play this file */

FifoCt = 0; FifoRi = 0; FifoWi = 0; /* Reset audio FIFO */

if (!TCCR1) { /* Enable audio out if not enabled */
PLLCSR = 0b00000110; /* Select PLL clock for TC1.ck */
GTCCR =  0b01100000; /* Enable OC1B as PWM */
TCCR1 = MODE ? 0b01100001 : 0b00000001; /* Start TC1 and enable OC1A as PWM if needed */
TCCR0A = 0b00000010; /* Statr TC0 as interval timer at 2MHz */
TCCR0B = 0b00000010;
TIMSK = _BV(OCIE0A);
ramp(1);
}

pf_read(0, 512 - (Fs.fptr % 512), &rb); /* Snip sector unaligned part */
sz -= rb;
sw = 1; /* Button status flag */
do { /* Data transfer loop */
wdt_reset();

btr = (sz > 1024) ? 1024 : (WORD)sz;/* A chunk of audio data */
res = pf_read(0, btr, &rb); /* Forward the data into audio FIFO */
if (rb != 1024) break; /* Break on error or end of data */
sz -= rb; /* Decrease data counter */

sw <<= 1; /* Break on button down */
} while ((PINB & 1) || ++sw != 1);
}

while (FifoCt) ; /* Wait for audio FIFO empty */
OCR1A = 128; OCR1B = 128; /* Return output to center level */

return res;
}
So what I don't follow is all the caps keywords which obviously correspond to some pins or settings in the chip.  He's got the code commented well but I don't know how those would correspond to the Digispark.

I fiddled around with the included TinySoftPwm library and managed to get an annoying buzzing out of the speaker with this code (it's a start I guess!)
Code: [Select]
#include <TinySoftPwm.h>

void setup()
{
  TinySoftPwm_begin(500, 0);
}

void loop()
{
  static uint32_t startUs = micros();
  static uint32_t startMs = millis();

  if ((micros() - startUs) >= 500)
  {
    startUs = micros();
    TinySoftPwm_process();
  }
 
  if ((millis() - startMs) >= 10)
  {
    startMs = millis();
    TinySoftPwm_analogWrite(1, 100);
  }
}

JeffRand

  • Newbie
  • *
  • Posts: 44
Re: Staples Easy Button
« Reply #9 on: March 15, 2014, 11:14:19 pm »
Oops, sorry I didn't notice that I posted the same link you did.  :-[

The code from ELM is writing directly to the registers and uses a lot of assembly language. I'll see if I can dig up some simpler examples, as I am interested in playing audio on the Digispark as well. Although I plan to use some external storage for the audio files. Your sound clip will have to be very short in order to fit within the program space since we're limited to about 6K.

Chuck Claunch

  • Newbie
  • *
  • Posts: 11
Re: Staples Easy Button
« Reply #10 on: March 16, 2014, 07:11:19 am »
Hmm I may need to actually consider the SD card solution.  I hate to add more hardware though as the goal is for it to be as simple as possible.  The sound I'd like to play is about 48KB, and I'd like some extra space just in case I wanted to add longer sounds.

I think that's the next step once I get a sound to actually play.  I have the sound in a header file already and can easily pare it down so that it fits in the given 6KB.  That will help me get the code working to play the sound, then I can tackle the storage issue.

JeffRand

  • Newbie
  • *
  • Posts: 44
Re: Staples Easy Button
« Reply #11 on: March 16, 2014, 09:57:16 am »
I found a really great example on the Adafruit site. http://learn.adafruit.com/trinket-audio-player/overview. In their example, they use a 1MByte flash IC for storage. It is a small 8 pin DIP. I pared down their example to play a 100 byte sine wave without using the flash memory. Here's my code:
Code: [Select]
uint16_t sample_rate;
volatile uint32_t  index = 0L;
uint8_t data[100];

void setup() {
  // Load the array of data with a single sine wave
  for(index=0;index<=100;index++) {
    data[index]=sin(((float) index/100.0)*6.2832) * 127 + 128;
  }

  sample_rate = 44000;               // 44KHz

  PLLCSR |= _BV(PLLE);               // Enable 64 MHz PLL
  delayMicroseconds(100);            // Stabilize
  while(!(PLLCSR & _BV(PLOCK)));     // Wait for it...
  PLLCSR |= _BV(PCKE);               // Timer1 source = PLL

  // Set up Timer/Counter1 for PWM output
  TIMSK  = 0;                        // Timer interrupts OFF
  TCCR1  = _BV(CS10);                // 1:1 prescale
  GTCCR  = _BV(PWM1B) | _BV(COM1B1); // PWM B, clear on match
  OCR1C  = 255;                      // Full 8-bit PWM cycle
  OCR1B  = 127;                      // 50% duty at start

  pinMode(4, OUTPUT);                // Enable PWM output pin

  TCCR0A = _BV(WGM01) | _BV(WGM00);  // Mode 7 (fast PWM)
  TCCR0B = _BV(WGM02) | _BV(CS01);   // 1:8 prescale
  OCR0A  = (((F_CPU / 8L) + (sample_rate / 2)) / sample_rate) - 1; // only good down to 8050 Hz
  TIMSK = _BV(OCIE0A);               // Enable compare match, disable overflow
}

void loop() { }

ISR(TIMER0_COMPA_vect) {
  OCR1B = data[index];
  if(++index >= 100) {               // End of audio data
    index = 0;                       // We must repeat!
  }
}
If you need a sample rate lower than 8050Hz, you will need to change the prescaler to divide by a larger number.


Chuck Claunch

  • Newbie
  • *
  • Posts: 11
Re: Staples Easy Button
« Reply #12 on: March 16, 2014, 08:59:01 pm »
Very cool, thanks!  Now I just need to figure out how "data" is laid out in a sound.  When I run that code I do get the sine wave, but if I swap in place the sound data I have, I get nothing.

b1rf

  • Newbie
  • *
  • Posts: 1
Re: Staples Easy Button
« Reply #13 on: May 27, 2014, 12:53:57 pm »
Hey Chuck, did you ever get things sorted out?

Highly curious as I'm not having much luck making noise on my digispark

Chuck Claunch

  • Newbie
  • *
  • Posts: 11
Re: Staples Easy Button
« Reply #14 on: May 27, 2014, 01:34:22 pm »
I had to table the project for a while as I'm getting married soon!  I'm sure I'll get back to it eventually.