Schematic Review Please?

Hi Tom;

Interrupts are being used to wake up the Nano. This is in a weekend fun car and parasitic draw on the battery is a problem. After 10 minutes of inactivity the Nano goes to sleep.

I took your advice and there is only one (1) diode left in the circuit and it is being used for polarity protection. Here is the new schm.
Schematic_Car Alarm V5 with audio amp copy_2022-09-13.pdf (222.8 KB)

Schematic:

I see a number of things I don't understand, however the most obvious is C3 and C5. You have a capacitive divider. I think C5 should be across R1 only.

U1 gain seems odd, it's 1 at DC and goes to ~20 for AC (didn't calc the freq). The output of the the micro is 0 to 5V. It seems like someone copied a ref design which would likely be for a 1V input. You will likely saturate the output of U1 (i.e. drive it so hard the output goes to max).

Why the DC:DC converter. U1 can accept up to 22 volts so why not go right to +12 then make the DC:DC output 5V (or maybe use an linear regulator.

Two more....

Why do you need the amplifier at all? Since you are driving it with a a slightly filtered square wave anyway.

One general comment. It looks like you are copying an existing design, that's fine. However I don't see any input protection from RF and Voltage spikes. Automotive +12 is very electrically dirty. By specification, the +12 can go as high as 50V and will most definitely go to 16.4V
Fog in and Lock in have no protection for voltage spikes which can go from a few hundred to 1500V (for a very short period of time).

Thanks for the input John;

Last first:

I now have optocouplers on Lock and Alarm inputs, per another comment received. That should take care of the spikes and also eliminated the need for the voltage dividers to lower the voltage to the Arduino inputs. This eliminated several resistors and diodes.

Why do you need the amplifier at all? Since you are driving it with a a slightly filtered square wave anyway.

The alarm sits under the hood and the theft alarm is just loud enough with the amp I am using. The lock tone is rather obnoxious at full vol, therefore the vol pot.

Why the DC:DC converter. U1 can accept up to 22 volts so why not go right to +12 then make the DC:DC output 5V (or maybe use an linear regulator.

Latest rev is using a buck convertor +12 or whatever the car is generating, in and 5v out. I am using the buck to power the Arduino (cleaner power) and as the pullup voltage on the opto outputs. With the optos I can use pull down on all of the inputs. I understand the the A like to be pulled down rather than up.

U1 gain seems odd, it's 1 at DC and goes to ~20 for AC (didn't calc the freq). The output of the the micro is 0 to 5V. It seems like someone copied a ref design which would likely be for a 1V input. You will likely saturate the output of U1 (i.e. drive it so hard the output goes to max).

This is a copy of a standard design for the amp chip. I'll double check my schm . Analog is not my thing at all.

Here is the latest schematic. All of the audio amp is now on the right and power/digital on the left of the board.
Schematic_Car Alarm V5_2022-09-14.pdf (213.2 KB)

Thanks for the time and effort!

Hi,

You should be able to EXPORT your schematic as a jpg and insert it into the post.

Tom...
:smiley: :+1: :coffee: :australia:

Hi Tom;

Got it!

Now for code??? Is this correct?

Thanks for the feedback. Steve

type or paste code here
```//Lock and alarm tone replacement for Chrysler Crossfire  S. Hardin

#define PlayStartup 1
#define Debug 1
#include <arduino.h>    // Arduino standard lib Use with PlatformIO IDE only
#include <Bounce2.h>    // debounce the relay contact
#include <MyGlobal.h>   // global vars and program desc and versions
#include <musicNotes.h> // file for notes define and tone arrays
#include <Sound.h>      // functions to make the sounds etc...
#include <BlockNot.h>   // non-program blocking time
#include <avr/sleep.h>  // allow low power sleep mode and ISR wakeup         

Bounce2::Button CarLock   =  Bounce2::Button(); // INSTANTIATE A Button OBJECT for Lock input
Bounce2::Button CarAlarm  =  Bounce2::Button(); // INSTANTIATE A Button OBJECT for ALARM input

BlockNot Fog_Lights_on(10, SECONDS);            //reset FirstTime to 1 every x Whole Seconds
BlockNot SleepTimer(600,SECONDS);               // if noting happens in 10 minutes put Nano to sleep

int FirstTime  = 1;                             //keep track of first time fog lights go from off to on
// forward declare interrupt service routine
void WakeISR(void);
/*******************************************************************************************************/
void setup() 
{ // GPIO pin setup
  // set all unused pins to input to reduce power required 
  for (auto cnt = 2; cnt < 20; cnt++) {pinMode(cnt, INPUT); }

  // now set up the pins being used.
  pinMode(MyGlobal::WakeUp0,        INPUT_PULLUP);   // D2 wake up interupt pin for lock
  pinMode(MyGlobal::WakeUp1,        INPUT_PULLUP);   // D31 wake up interupt pin for alarm
  pinMode(MyGlobal::Amp_Pwr,        OUTPUT);         // D4 speaker amp power when R1 NO contact closed from D4 going high 
  pinMode(MyGlobal::Soft_Tone_Out,  OUTPUT);         // D5 Lock/Beep Tone out for Amped speaker/ next version will have high and low vol. 5 will be soft tone
  pinMode(MyGlobal::Loud_Tone_Out,  OUTPUT);         // D6 Alarm Tone out for Amped speaker
  pinMode(MyGlobal::Fog_Tone_Jmp,   INPUT_PULLUP);   // D8 select beep or no beep when fogs turned on manually
  pinMode(MyGlobal::Lock_Input,     INPUT_PULLUP);   // D12 Car lock Input goes low when optocoupler goes high from lock realy signal
  pinMode(MyGlobal::Alarm_Input,    INPUT_PULLUP);   // D13 Car alarm Input goes low when optocoupler goes high from fogs on signal

  
  /*-------------------------------------------------------------------------------------------------------*/
  // Set up debounce for Lock and Alarm SIGNALS
  CarLock.attach(MyGlobal::Lock_Input, INPUT_PULLUP); // USE OptoCoupler to pull low
  CarLock.interval(10);                               // DEBOUNCE INTERVAL IN MILLISECONDS for lock
  CarLock.setPressedState(HIGH);                      // INDICATE THAT THE high STATE CORRESPONDS lock relay closing

  CarAlarm.attach(MyGlobal::Alarm_Input, INPUT_PULLUP);// USE OptoCoupler to pull low
  CarAlarm.interval(10);                              // DEBOUNCE INTERVAL IN MILLISECONDS for alarm
  CarAlarm.setPressedState(HIGH);                     // INDICATE THAT THE HIGH STATE CORRESPONDS to alarm (fogs on)
  
  MyGlobal::Fog_On_Beep = digitalRead (MyGlobal::Fog_Tone_Jmp);  // read how J1 is set
  
  // #define PlayStartup as 0 if you don't want this to play on start-up, or write your own song.
  #if PlayStartup == 1  
    Sound::Sound(Music::Star_Trek, sizeof(Music::Star_Trek) / 4, 
                   MyGlobal::Soft_Tone_Out,  MyGlobal::Amp_Pwr);
  #endif
} // End Setup
/*******************************************************************************************************/
void loop() 
{
  //******************************* CAR LOCK SECTION *******************************************************************
  CarLock.update();               // check if lock relay has closed
  if (CarLock.pressed())          // if the lock relay is on and debounce is satisfied
  {
    Sound::Sound(Music::Soft_tone_array, sizeof(Music::Soft_tone_array) / 4, 
                 MyGlobal::Soft_Tone_Out, MyGlobal::Amp_Pwr);  
    FirstTime = 1;                // reset FirstTime since we have locked/unlock car 
    resetAllTimers();             // reset fogs on timer and sleep timer                     
  } // end if
  //******************************* CAR ALARM SECTION **********************************************************************
  CarAlarm.update();         
  if (CarAlarm.pressed())    // check if fog lights are on 
  {  
    switch (FirstTime) 
    {                       // if it closes again we want to know it is not the first time
      case 0: // ALARM!!!!
      { // must be an alarm since we have a second on/off during reset delay period
        Sound::Sound(Music::Loud_tone_array, sizeof(Music::Loud_tone_array) / 4, 
                     MyGlobal::Loud_Tone_Out, MyGlobal::Amp_Pwr); 
        resetAllTimers();   // reset fogs on timer and sleep timer we don't want then to time out during alarm
        break;
      } // end case 0
      
      case 1: // fog lights have turned on, maybe manual, maybe an alarm
      {
        FirstTime = 0;
        // Jumper 1 to position 23 (LOW) if you want a tone when you 
        // turn the fog lights on manually.  Jumper 1 (Pull to LOW) position 12 will not beep
        if(MyGlobal::Fog_On_Beep == HIGH)
        {
          Sound::Sound(Music::Beep_tone_array, sizeof(Music::Beep_tone_array) / 4, 
                       MyGlobal::Soft_Tone_Out, MyGlobal::Amp_Pwr);
        } // end if
        break;
      } //end case 1

      default:  // if we get here there is an error
      {
        Sound::ErrTones(1);
        break;
      } // end default
    }  // end switch firsttime
  }  //end if caralarm pressed
  //********************************* Timer to reset FirstTime ********************************************************************
  if (Fog_Lights_on.TRIGGERED) // fog light timer has expired 
  { //reset FirstTime every X seconds so that is not left true after one itteration //
    // this also fixes the problem of going from low to high beam with the fogs on
    FirstTime = 1;  
    //resetAllTimers();
    // Fog_Lights_on.TRIGGERED is reset when timed out 
    // on board LED will flash 10 sec ON / 10 sec off except when asleep
    #if Debug == 1
      int LEDon; 
      LEDon = digitalRead(13);
      if(LEDon == HIGH)
      {
        digitalWrite(13,LOW);
      } // end if
      else
      {
        digitalWrite(13,HIGH);
      }     // end else
    #endif
   } //endif foglights triggered
      //****************************** Timer to put Nano to sleep ***************************************
  if (SleepTimer.TRIGGERED)  // noting has happened in 10 minutes, go to sleep
  {
    /* Set the type of sleep mode we want. Can be one of (in order of power saving):
          SLEEP_MODE_IDLE (Timer 0 will wake up every millisecond to keep millis running)
          SLEEP_MODE_ADC
          SLEEP_MODE_PWR_SAVE (TIMER 2 keeps running)
          SLEEP_MODE_EXT_STANDBY
          SLEEP_MODE_STANDBY (Oscillator keeps running, makes for faster wake-up)
      >>>> SLEEP_MODE_PWR_DOWN (Deep sleep)
    */
      set_sleep_mode (SLEEP_MODE_PWR_DOWN);
      sleep_enable();
    // Ensure we can wake up again by first disabling interupts (temporarily) so
    // the wakeISR does not run before we are asleep and then prevent interrupts,
    // and then defining the ISR (Interrupt Service Routine) to run when poked awake
    noInterrupts();
    attachInterrupt(digitalPinToInterrupt(MyGlobal::WakeUp0), WakeISR, FALLING);
    attachInterrupt(digitalPinToInterrupt(MyGlobal::WakeUp1), WakeISR, FALLING);
    sleep_cpu();                    // And enter sleep mode as set above SLEEP_MODE_PWR_DOWN (Deep sleep)
    //--------------------------------------------------------------------------------------------------
    //("Good night!") Arduino goes to sleep here when awakened it will run WakeISR() first then
    // >>>>>>>>>>>>>>>> after the WakeISR() is run return here and run the code  <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
    interrupts();                    // Allow interrupts now
    resetAllTimers();                // reset the Fog_Lights_on and the Sleep timers
  }  //end if sleeptimer
}  // Void loop end  

void WakeISR( ) 
  { // wake up ISR from Int0 D2 for lock NS Int1 for alarm.
    // Prevent sleep mode, so we don't enter it again, except deliberately, by code
    sleep_disable();
    // Detach the interrupt that brought us out of sleep
    detachInterrupt(digitalPinToInterrupt(MyGlobal::WakeUp0));
    detachInterrupt(digitalPinToInterrupt(MyGlobal::WakeUp1));
  }

Hi John;

I reviewed the audio amp section of the schematic and found 2 errors.

Thanks, you have a keen eye!

Steve

This one looks so properly done actually!

Thanks!

1 Like

The spikes will still come through, you should put a 0.1µF cap at each input to ground and +12 (should be very close to where the wires come in to your enclosure).

This is a copy of a standard design for the amp chip. I'll double check my schm . Analog is not my thing at all.

A typical audio output of a preamplifier would be around 1V rms. You might want to try it before you commit to a PCB.

This eliminated several resistors and diodes.

Resistors are cheap. Consider you will likely not be building 1000's of units. And if that is your goal I will guarantee you will be changing the PCB design before you get to that point. This has nothing to do with you personally, It's just how these things go (I've done this many many times).
So add additional capacitors for filtering and input protection. If you find you don't need them you can always leave them off the board.

Thanks for the reply. I will investigate

Hi,

Have you breadboarded your project to test the prototype?

If not then do that before doing anything about a PCB.

Tom.. :smiley: :+1: :coffee: :australia:

I have a wired proto working in the car now.

Per you suggestion for the 12 v noise.

image

Here is main,cpp

type or paste code here
```//Lock and alarm tone replacement for Chrysler Crossfire  S. Hardin

#define PlayStartup 1
#define Debug 1
#include <arduino.h>    // Arduino standard lib Use with PlatformIO IDE only
#include <Bounce2.h>    // debounce the relay contact  See Global.h for acknowledgement and license
#include <MyGlobal.h>   // global vars and program desc and versions
#include <musicNotes.h> // file for notes define and tone arrays
#include <Sound.h>      // functions to make the sounds etc...
#include <BlockNot.h>   // non-program blocking time See Global.h for acknowledgement and license
#include <avr/sleep.h>  // allow low power sleep mode and ISR wakeup         

Bounce2::Button CarLock   =  Bounce2::Button(); // INSTANTIATE A Button OBJECT for Lock input
Bounce2::Button CarAlarm  =  Bounce2::Button(); // INSTANTIATE A Button OBJECT for ALARM input

BlockNot Fog_Lights_on(10, SECONDS);            //reset FirstTime to 1 every x Whole Seconds
BlockNot SleepTimer(600,SECONDS);               // if noting happens in 10 minutes put Nano to sleep

int FirstTime  = 1;                             //keep track of first time fog lights go from off to on
// forward declare interrupt service routine
void WakeISR(void);
/*******************************************************************************************************/
void setup() 
{ // GPIO pin setup
  // set all unused pins to input to reduce power required 
  for (auto cnt = 2; cnt < 20; cnt++) {pinMode(cnt, INPUT); }

  // now set up the pins being used.
  pinMode(MyGlobal::WakeUp0,        INPUT_PULLUP);   // D2 wake up interupt pin for lock
  pinMode(MyGlobal::WakeUp1,        INPUT_PULLUP);   // D31 wake up interupt pin for alarm
  pinMode(MyGlobal::Amp_Pwr,        OUTPUT);         // D4 speaker amp power when R1 NO contact closed from D4 going high 
  pinMode(MyGlobal::Soft_Tone_Out,  OUTPUT);         // D5 Lock/Beep Tone out for Amped speaker/ next version will have high and low vol. 5 will be soft tone
  pinMode(MyGlobal::Loud_Tone_Out,  OUTPUT);         // D6 Alarm Tone out for Amped speaker
  pinMode(MyGlobal::Fog_Tone_Jmp,   INPUT_PULLUP);   // D8 select beep or no beep when fogs turned on manually
  pinMode(MyGlobal::Lock_Input,     INPUT_PULLUP);   // D12 Car lock Input goes low when optocoupler goes high from lock realy signal
  pinMode(MyGlobal::Alarm_Input,    INPUT_PULLUP);   // D13 Car alarm Input goes low when optocoupler goes high from fogs on signal

  
  /*-------------------------------------------------------------------------------------------------------*/
  // Set up debounce for Lock and Alarm SIGNALS
  CarLock.attach(MyGlobal::Lock_Input, INPUT_PULLUP); // USE OptoCoupler to pull low
  CarLock.interval(10);                               // DEBOUNCE INTERVAL IN MILLISECONDS for lock
  CarLock.setPressedState(HIGH);                      // INDICATE THAT THE high STATE CORRESPONDS lock relay closing

  CarAlarm.attach(MyGlobal::Alarm_Input, INPUT_PULLUP);// USE OptoCoupler to pull low
  CarAlarm.interval(10);                              // DEBOUNCE INTERVAL IN MILLISECONDS for alarm
  CarAlarm.setPressedState(HIGH);                     // INDICATE THAT THE HIGH STATE CORRESPONDS to alarm (fogs on)
  
  MyGlobal::Fog_On_Beep = digitalRead (MyGlobal::Fog_Tone_Jmp);  // read how J1 is set
  
  // #define PlayStartup as 0 if you don't want this to play on start-up, or write your own song.
  #if PlayStartup == 1  
    Sound::Sound(Music::Star_Trek, sizeof(Music::Star_Trek) / 4, 
                   MyGlobal::Soft_Tone_Out,  MyGlobal::Amp_Pwr);
  #endif
} // End Setup
/*******************************************************************************************************/
void loop() 
{
  //******************************* CAR LOCK SECTION *******************************************************************
  CarLock.update();               // check if lock relay has closed
  if (CarLock.pressed())          // if the lock relay is on and debounce is satisfied
  {
    //Sound::Sound(Music::Soft_tone_array, sizeof(Music::Soft_tone_array) / 4, 
    //             MyGlobal::Soft_Tone_Out, MyGlobal::Amp_Pwr);  
    Sound::Sound(Music::ShortNokia, sizeof(Music::ShortNokia) / 4, 
                 MyGlobal::Soft_Tone_Out, MyGlobal::Amp_Pwr);                   
    FirstTime = 1;                // reset FirstTime since we have locked/unlock car 
    resetAllTimers();             // reset fogs on timer and sleep timer                     
  } // end if
  //******************************* CAR ALARM SECTION **********************************************************************
  CarAlarm.update();         
  if (CarAlarm.pressed())    // check if fog lights are on 
  {  
    switch (FirstTime) 
    {                       // if it closes again we want to know it is not the first time
      case 0: // ALARM!!!!
      { // must be an alarm since we have a second on/off during reset delay period
        Sound::Sound(Music::Loud_tone_array, sizeof(Music::Loud_tone_array) / 4, 
                     MyGlobal::Loud_Tone_Out, MyGlobal::Amp_Pwr); 
        resetAllTimers();   // reset fogs on timer and sleep timer we don't want then to time out during alarm
        break;
      } // end case 0
      
      case 1: // fog lights have turned on, maybe manual, maybe an alarm
      {
        FirstTime = 0;
        // Jumper 1 to position 23 (LOW) if you want a tone when you 
        // turn the fog lights on manually.  Jumper 1 (Pull to LOW) position 12 will not beep
        if(MyGlobal::Fog_On_Beep == HIGH)
        {
          Sound::Sound(Music::Beep_tone_array, sizeof(Music::Beep_tone_array) / 4, 
                       MyGlobal::Soft_Tone_Out, MyGlobal::Amp_Pwr);
        } // end if
        break;
      } //end case 1

      default:  // if we get here there is an error
      {
        Sound::ErrTones(1);
        break;
      } // end default
    }  // end switch firsttime
  }  //end if caralarm pressed
 
  //********************************* Timer to reset FirstTime ********************************************************************
  if (Fog_Lights_on.TRIGGERED) // fog light timer has expired 
  { //reset FirstTime every X seconds so that is not left true after one itteration //
    // this also fixes the problem of going from low to high beam with the fogs on
    FirstTime = 1;  
    // Fog_Lights_on.TRIGGERED is reset when timed out 
   } //endif foglights triggered
  
  //****************************** Timer to put Nano to sleep ***************************************

  
  if (SleepTimer.TRIGGERED)  // noting has happened in 10 minutes, go to sleep
  {
    /* Set the type of sleep mode we want. Can be one of (in order of power saving):
          SLEEP_MODE_IDLE (Timer 0 will wake up every millisecond to keep millis running)
          SLEEP_MODE_ADC
          SLEEP_MODE_PWR_SAVE (TIMER 2 keeps running)
          SLEEP_MODE_EXT_STANDBY
          SLEEP_MODE_STANDBY (Oscillator keeps running, makes for faster wake-up)
      >>>> SLEEP_MODE_PWR_DOWN (Deep sleep)
    */
      set_sleep_mode (SLEEP_MODE_PWR_DOWN);
      sleep_enable();
    // Ensure we can wake up again by first disabling interupts (temporarily) so
    // the wakeISR does not run before we are asleep and then prevent interrupts,
    // and then defining the ISR (Interrupt Service Routine) to run when poked awake
    noInterrupts();
    attachInterrupt(digitalPinToInterrupt(MyGlobal::WakeUp0), WakeISR, FALLING);
    attachInterrupt(digitalPinToInterrupt(MyGlobal::WakeUp1), WakeISR, FALLING);
    sleep_cpu();                    // And enter sleep mode as set above SLEEP_MODE_PWR_DOWN (Deep sleep)
    interrupts();                   // Allow interrupts now
    //--------------------------------------------------------------------------------------------------
    //("Good night!") Arduino goes to sleep here when awakened it will run WakeISR() first then
    // >>>>>> After the WakeISR() is run return here and run the code  <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
                       
    resetAllTimers();               // reset the Fog_Lights_on and the Sleep timers
  }  //end if sleeptimer
    // --------------------------------------------------------
    // µController is now asleep until woken up by an interrupt
    // --------------------------------------------------------
  
}  // Void loop end  

void WakeISR( ) 
  { // wake up ISR from Int0 D2 or  Int1 for alarm D3.
    // Prevent sleep mode, so we don't enter it again, except deliberately, by code
    sleep_disable();
    // Detach the interrupt that brought us out of sleep
    detachInterrupt(digitalPinToInterrupt(MyGlobal::WakeUp0));
    detachInterrupt(digitalPinToInterrupt(MyGlobal::WakeUp1));
  }

General acknowledgments:

// MyGlobal.h

 /*                   GNU GENERAL PUBLIC LICENSE
                       Version 3, 29 June 2007

 Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
*/
// Portions of this program were derived from turorials and on-line examples.
// Thanks to all who take the time and effort to post the code and videos. 

/* Sleep routine from below, Thanks to Ralph Bacon.  Benny, Rest in peace */
/* Adapted from Low Power SLEEP modes for Arduino UNO/Nano
   using Atmel328P microcontroller chip video.
   For full details see my video #115
   at https://www.youtube.com/ralphbacon
   This video is #159 to be found at the same place!
   All details can be found at https://github.com/ralphbacon
*/

/* BlockNot is a simple and easy to use Arduino class for the implementation
 * of non-blocking timers, as it is far better to use non-blocking timers
 * with a micro-controller since they allow you to trigger code at defined
 * durations of time, without stopping the execution of your main loop.
 *
 * Written by - Michael Sims
 * Full documentation can be found at: https://github.com/EasyG0ing1/BlockNot
 *
 * See LICENSE file for acceptable use conditions - this is open source
 * and there are no restrictions on its usage, I simply ask for some acknowledgment
 * if it is used in your project.
 * */

/*
  The MIT License (MIT)
  Copyright (c) 2013 thomasfredericks
  Permission is hereby granted, free of charge, to any person obtaining a copy of
  this software and associated documentation files (the "Software"), to deal in
  the Software without restriction, including without limitation the rights to
  use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
  the Software, and to permit persons to whom the Software is furnished to do so,
  subject to the following conditions:
  The above copyright notice and this permission notice shall be included in all
  copies or substantial portions of the Software.
  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
  FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
  COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
  IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
/* * * * * * * * * * * * * * * * * * * * * * * * * * * *
  Main code by Thomas O Fredericks (tof@t-o-f.info)
  Previous contributions by Eric Lowry, Jim Schimpf and Tom Harkaway
  * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

// NewTone Library - v1.0 - 01/20/2013
//
// AUTHOR/LICENSE:
// Created by Tim Eckel - teckel@leethost.com
// Copyright 2013 License: GNU GPL v3 http://www.gnu.org/licenses/gpl-3.0.html
//
// LINKS:
// Project home: http://code.google.com/p/arduino-new-tone/
// Blog: http://arduino.cc/forum/index.php/XXX

Oh wow, That`s useful!

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.