mirror of
https://github.com/thunderbug1/Spherebot-Host-GUI.git
synced 2026-03-06 09:56:46 +01:00
Version 2.0
This commit is contained in:
BIN
SphereBot Arduino/SoftwareServo.zip
Normal file
BIN
SphereBot Arduino/SoftwareServo.zip
Normal file
Binary file not shown.
128
SphereBot Arduino/SphereBot/SoftwareServo.cpp
Normal file
128
SphereBot Arduino/SphereBot/SoftwareServo.cpp
Normal file
@@ -0,0 +1,128 @@
|
||||
#include "SoftwareServo.h"
|
||||
|
||||
SoftwareServo *SoftwareServo::first;
|
||||
|
||||
#define NO_ANGLE (0xff)
|
||||
|
||||
SoftwareServo::SoftwareServo() : pin(0),angle(NO_ANGLE),pulse0(0),min16(34),max16(150),next(0)
|
||||
{}
|
||||
|
||||
void SoftwareServo::setMinimumPulse(uint16_t t)
|
||||
{
|
||||
min16 = t/16;
|
||||
}
|
||||
|
||||
void SoftwareServo::setMaximumPulse(uint16_t t)
|
||||
{
|
||||
max16 = t/16;
|
||||
}
|
||||
|
||||
uint8_t SoftwareServo::attach(int pinArg)
|
||||
{
|
||||
pin = pinArg;
|
||||
angle = NO_ANGLE;
|
||||
pulse0 = 0;
|
||||
next = first;
|
||||
first = this;
|
||||
digitalWrite(pin,0);
|
||||
pinMode(pin,OUTPUT);
|
||||
return 1;
|
||||
}
|
||||
|
||||
void SoftwareServo::detach()
|
||||
{
|
||||
for ( SoftwareServo **p = &first; *p != 0; p = &((*p)->next) ) {
|
||||
if ( *p == this) {
|
||||
*p = this->next;
|
||||
this->next = 0;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SoftwareServo::write(int angleArg)
|
||||
{
|
||||
if ( angleArg < 0) angleArg = 0;
|
||||
if ( angleArg > 180) angleArg = 180;
|
||||
angle = angleArg;
|
||||
// bleh, have to use longs to prevent overflow, could be tricky if always a 16MHz clock, but not true
|
||||
// That 64L on the end is the TCNT0 prescaler, it will need to change if the clock's prescaler changes,
|
||||
// but then there will likely be an overflow problem, so it will have to be handled by a human.
|
||||
pulse0 = (min16*16L*clockCyclesPerMicrosecond() + (max16-min16)*(16L*clockCyclesPerMicrosecond())*angle/180L)/64L;
|
||||
}
|
||||
|
||||
uint8_t SoftwareServo::read()
|
||||
{
|
||||
return angle;
|
||||
}
|
||||
|
||||
uint8_t SoftwareServo::attached()
|
||||
{
|
||||
for ( SoftwareServo *p = first; p != 0; p = p->next ) {
|
||||
if ( p == this) return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void SoftwareServo::refresh()
|
||||
{
|
||||
uint8_t count = 0, i = 0;
|
||||
uint16_t base = 0;
|
||||
SoftwareServo *p;
|
||||
static unsigned long lastRefresh = 0;
|
||||
unsigned long m = millis();
|
||||
|
||||
// if we haven't wrapped millis, and 20ms have not passed, then don't do anything
|
||||
if ( m >= lastRefresh && m < lastRefresh + 20) return;
|
||||
lastRefresh = m;
|
||||
|
||||
for ( p = first; p != 0; p = p->next ) if ( p->pulse0) count++;
|
||||
if ( count == 0) return;
|
||||
|
||||
// gather all the SoftwareServos in an array
|
||||
SoftwareServo *s[count];
|
||||
for ( p = first; p != 0; p = p->next ) if ( p->pulse0) s[i++] = p;
|
||||
|
||||
// bubblesort the SoftwareServos by pulse time, ascending order
|
||||
for(;;) {
|
||||
uint8_t moved = 0;
|
||||
for ( i = 1; i < count; i++) {
|
||||
if ( s[i]->pulse0 < s[i-1]->pulse0) {
|
||||
SoftwareServo *t = s[i];
|
||||
s[i] = s[i-1];
|
||||
s[i-1] = t;
|
||||
moved = 1;
|
||||
}
|
||||
}
|
||||
if ( !moved) break;
|
||||
}
|
||||
|
||||
// turn on all the pins
|
||||
// Note the timing error here... when you have many SoftwareServos going, the
|
||||
// ones at the front will get a pulse that is a few microseconds too long.
|
||||
// Figure about 4uS/SoftwareServo after them. This could be compensated, but I feel
|
||||
// it is within the margin of error of software SoftwareServos that could catch
|
||||
// an extra interrupt handler at any time.
|
||||
for ( i = 0; i < count; i++) digitalWrite( s[i]->pin, 1);
|
||||
|
||||
uint8_t start = TCNT0;
|
||||
uint8_t now = start;
|
||||
uint8_t last = now;
|
||||
|
||||
// Now wait for each pin's time in turn..
|
||||
for ( i = 0; i < count; i++) {
|
||||
uint16_t go = start + s[i]->pulse0;
|
||||
|
||||
// loop until we reach or pass 'go' time
|
||||
for (;;) {
|
||||
now = TCNT0;
|
||||
if ( now < last) base += 256;
|
||||
last = now;
|
||||
|
||||
if ( base+now > go) {
|
||||
digitalWrite( s[i]->pin,0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
31
SphereBot Arduino/SphereBot/SoftwareServo.h
Normal file
31
SphereBot Arduino/SphereBot/SoftwareServo.h
Normal file
@@ -0,0 +1,31 @@
|
||||
#ifndef SoftwareServo_h
|
||||
#define SoftwareServo_h
|
||||
|
||||
#include "Arduino.h"</wprogram.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
class SoftwareServo
|
||||
{
|
||||
private:
|
||||
uint8_t pin;
|
||||
uint8_t angle; // in degrees
|
||||
uint16_t pulse0; // pulse width in TCNT0 counts
|
||||
uint8_t min16; // minimum pulse, 16uS units (default is 34)
|
||||
uint8_t max16; // maximum pulse, 16uS units, 0-4ms range (default is 150)
|
||||
class SoftwareServo *next;
|
||||
static SoftwareServo* first;
|
||||
public:
|
||||
SoftwareServo();
|
||||
uint8_t attach(int); // attach to a pin, sets pinMode, returns 0 on failure, won't
|
||||
// position the servo until a subsequent write() happens
|
||||
void detach();
|
||||
void write(int); // specify the angle in degrees, 0 to 180
|
||||
uint8_t read();
|
||||
uint8_t attached();
|
||||
void setMinimumPulse(uint16_t); // pulse length for 0 degrees in microseconds, 540uS default
|
||||
void setMaximumPulse(uint16_t); // pulse length for 180 degrees in microseconds, 2400uS default
|
||||
static void refresh(); // must be called at least every 50ms or so to keep servo alive
|
||||
// you can call more often, it won't happen more than once every 20ms
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,5 +1,11 @@
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Copyright 2011 by Eberhard Rensch <http://pleasantsoftware.com/developer/3d>
|
||||
* Original Code: Copyright 2011 by Eberhard Rensch <http://pleasantsoftware.com/developer/3d>
|
||||
*
|
||||
* Modified by Alexander Balasch
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -24,13 +30,14 @@
|
||||
* !!!!!!!!
|
||||
*/
|
||||
|
||||
#include <TimerOne.h>
|
||||
#include <SoftwareServo.h>
|
||||
#include "TimerOne.h"
|
||||
#include "SoftwareServo.h"
|
||||
#include "StepperModel.h"
|
||||
|
||||
|
||||
#define TIMER_DELAY 64
|
||||
#define TIMER_DELAY 256
|
||||
|
||||
#define VERSIONCODE "Spherebot 2.0"
|
||||
/*
|
||||
* PINS
|
||||
*/
|
||||
@@ -51,7 +58,7 @@
|
||||
#define YAXIS_DIR_PIN 14
|
||||
#define YAXIS_STEP_PIN 15
|
||||
#define YAXIS_ENABLE_PIN 21
|
||||
#define YAXIS_MS1_PIN 19 //don´t make this connection!! ADC6 and ADC7 can not be used as a digital pin ( I made the pull up connection manually)
|
||||
#define YAXIS_MS1_PIN 19 //don´t make this connection!! ADC6 and ADC7 can not be used as a digital pin ( I made the pull up connection manually)
|
||||
#define YAXIS_MS2_PIN 28
|
||||
//#define YAXIS_MS3_PIN 18
|
||||
#define YAXIS_ENDSTOP_PIN -1 //13
|
||||
@@ -107,12 +114,14 @@ double feedrate = 300.; // mm/minute
|
||||
double zoom = DEFAULT_ZOOM_FACTOR;
|
||||
|
||||
const double maxFeedrate = 2000.;
|
||||
|
||||
// ------
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
Serial.print("EBB 1.0\n");
|
||||
Serial.print(VERSIONCODE);
|
||||
Serial.print("\n");
|
||||
|
||||
clear_buffer();
|
||||
|
||||
@@ -254,6 +263,7 @@ void get_command() // gets commands from serial connection and then calls up sub
|
||||
{
|
||||
clear_buffer();
|
||||
Serial.flush();
|
||||
Serial.print("Overflow Error");
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -282,9 +292,10 @@ boolean getValue(char key, char command[], double* value)
|
||||
|
||||
void check_for_version_controll(char command)
|
||||
{
|
||||
if(command == 'v')
|
||||
if(command == 'V')
|
||||
{
|
||||
Serial.print("EBB 1.0\n");
|
||||
Serial.print(VERSIONCODE);
|
||||
Serial.print("\n");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -297,7 +308,7 @@ void process_commands(char command[], int command_length) // deals with standard
|
||||
}
|
||||
if (command_length>0 && command[0] == 'G') // G code
|
||||
{
|
||||
//Serial.print("proces G: \n");
|
||||
//Serial.print("process G: \n");
|
||||
int codenum = (int)strtod(&command[1], NULL);
|
||||
|
||||
double tempX = xAxisStepper.getCurrentPosition();
|
||||
@@ -415,7 +426,7 @@ void process_commands(char command[], int command_length) // deals with standard
|
||||
for(int i=0;i<100;i++)
|
||||
{
|
||||
SoftwareServo::refresh();
|
||||
delay(4);
|
||||
delay(80);
|
||||
}
|
||||
servoEnabled=false;
|
||||
}
|
||||
@@ -451,16 +462,18 @@ void process_commands(char command[], int command_length) // deals with standard
|
||||
zoom = value/100;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
//done processing commands
|
||||
if (Serial.available() <= 0) {
|
||||
//if (Serial.available() <= 0) {
|
||||
Serial.print("ok:");
|
||||
Serial.println(command);
|
||||
//Serial.println(command);
|
||||
Serial.print("\n");
|
||||
}
|
||||
//}
|
||||
}
|
||||
|
||||
/* This code was ported from the Makerbot/ReplicatorG java sources */
|
||||
209
SphereBot Arduino/SphereBot/TimerOne.cpp
Normal file
209
SphereBot Arduino/SphereBot/TimerOne.cpp
Normal file
@@ -0,0 +1,209 @@
|
||||
/*
|
||||
* Interrupt and PWM utilities for 16 bit Timer1 on ATmega168/328
|
||||
* Original code by Jesse Tane for http://labs.ideo.com August 2008
|
||||
* Modified March 2009 by Jérôme Despatis and Jesse Tane for ATmega328 support
|
||||
* Modified June 2009 by Michael Polli and Jesse Tane to fix a bug in setPeriod() which caused the timer to stop
|
||||
* Modified June 2011 by Lex Talionis to add a function to read the timer
|
||||
* Modified Oct 2011 by Andrew Richards to avoid certain problems:
|
||||
* - Add (long) assignments and casts to TimerOne::read() to ensure calculations involving tmp, ICR1 and TCNT1 aren't truncated
|
||||
* - Ensure 16 bit registers accesses are atomic - run with interrupts disabled when accessing
|
||||
* - Remove global enable of interrupts (sei())- could be running within an interrupt routine)
|
||||
* - Disable interrupts whilst TCTN1 == 0. Datasheet vague on this, but experiment shows that overflow interrupt
|
||||
* flag gets set whilst TCNT1 == 0, resulting in a phantom interrupt. Could just set to 1, but gets inaccurate
|
||||
* at very short durations
|
||||
* - startBottom() added to start counter at 0 and handle all interrupt enabling.
|
||||
* - start() amended to enable interrupts
|
||||
* - restart() amended to point at startBottom()
|
||||
* Modiied 7:26 PM Sunday, October 09, 2011 by Lex Talionis
|
||||
* - renamed start() to resume() to reflect it's actual role
|
||||
* - renamed startBottom() to start(). This breaks some old code that expects start to continue counting where it left off
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* See Google Code project http://code.google.com/p/arduino-timerone/ for latest
|
||||
*/
|
||||
#ifndef TIMERONE_cpp
|
||||
#define TIMERONE_cpp
|
||||
|
||||
#include "TimerOne.h"
|
||||
|
||||
TimerOne Timer1; // preinstatiate
|
||||
|
||||
ISR(TIMER1_OVF_vect) // interrupt service routine that wraps a user defined function supplied by attachInterrupt
|
||||
{
|
||||
Timer1.isrCallback();
|
||||
}
|
||||
|
||||
|
||||
void TimerOne::initialize(long microseconds)
|
||||
{
|
||||
TCCR1A = 0; // clear control register A
|
||||
TCCR1B = _BV(WGM13); // set mode 8: phase and frequency correct pwm, stop the timer
|
||||
setPeriod(microseconds);
|
||||
}
|
||||
|
||||
|
||||
void TimerOne::setPeriod(long microseconds) // AR modified for atomic access
|
||||
{
|
||||
|
||||
long cycles = (F_CPU / 2000000) * microseconds; // the counter runs backwards after TOP, interrupt is at BOTTOM so divide microseconds by 2
|
||||
if(cycles < RESOLUTION) clockSelectBits = _BV(CS10); // no prescale, full xtal
|
||||
else if((cycles >>= 3) < RESOLUTION) clockSelectBits = _BV(CS11); // prescale by /8
|
||||
else if((cycles >>= 3) < RESOLUTION) clockSelectBits = _BV(CS11) | _BV(CS10); // prescale by /64
|
||||
else if((cycles >>= 2) < RESOLUTION) clockSelectBits = _BV(CS12); // prescale by /256
|
||||
else if((cycles >>= 2) < RESOLUTION) clockSelectBits = _BV(CS12) | _BV(CS10); // prescale by /1024
|
||||
else cycles = RESOLUTION - 1, clockSelectBits = _BV(CS12) | _BV(CS10); // request was out of bounds, set as maximum
|
||||
|
||||
oldSREG = SREG;
|
||||
cli(); // Disable interrupts for 16 bit register access
|
||||
ICR1 = pwmPeriod = cycles; // ICR1 is TOP in p & f correct pwm mode
|
||||
SREG = oldSREG;
|
||||
|
||||
TCCR1B &= ~(_BV(CS10) | _BV(CS11) | _BV(CS12));
|
||||
TCCR1B |= clockSelectBits; // reset clock select register, and starts the clock
|
||||
}
|
||||
|
||||
void TimerOne::setPwmDuty(char pin, int duty)
|
||||
{
|
||||
unsigned long dutyCycle = pwmPeriod;
|
||||
|
||||
dutyCycle *= duty;
|
||||
dutyCycle >>= 10;
|
||||
|
||||
oldSREG = SREG;
|
||||
cli();
|
||||
if(pin == 1 || pin == 9) OCR1A = dutyCycle;
|
||||
else if(pin == 2 || pin == 10) OCR1B = dutyCycle;
|
||||
SREG = oldSREG;
|
||||
}
|
||||
|
||||
void TimerOne::pwm(char pin, int duty, long microseconds) // expects duty cycle to be 10 bit (1024)
|
||||
{
|
||||
if(microseconds > 0) setPeriod(microseconds);
|
||||
if(pin == 1 || pin == 9) {
|
||||
DDRB |= _BV(PORTB1); // sets data direction register for pwm output pin
|
||||
TCCR1A |= _BV(COM1A1); // activates the output pin
|
||||
}
|
||||
else if(pin == 2 || pin == 10) {
|
||||
DDRB |= _BV(PORTB2);
|
||||
TCCR1A |= _BV(COM1B1);
|
||||
}
|
||||
setPwmDuty(pin, duty);
|
||||
resume(); // Lex - make sure the clock is running. We don't want to restart the count, in case we are starting the second WGM
|
||||
// and the first one is in the middle of a cycle
|
||||
}
|
||||
|
||||
void TimerOne::disablePwm(char pin)
|
||||
{
|
||||
if(pin == 1 || pin == 9) TCCR1A &= ~_BV(COM1A1); // clear the bit that enables pwm on PB1
|
||||
else if(pin == 2 || pin == 10) TCCR1A &= ~_BV(COM1B1); // clear the bit that enables pwm on PB2
|
||||
}
|
||||
|
||||
void TimerOne::attachInterrupt(void (*isr)(), long microseconds)
|
||||
{
|
||||
if(microseconds > 0) setPeriod(microseconds);
|
||||
isrCallback = isr; // register the user's callback with the real ISR
|
||||
TIMSK1 = _BV(TOIE1); // sets the timer overflow interrupt enable bit
|
||||
// might be running with interrupts disabled (eg inside an ISR), so don't touch the global state
|
||||
// sei();
|
||||
resume();
|
||||
}
|
||||
|
||||
void TimerOne::detachInterrupt()
|
||||
{
|
||||
TIMSK1 &= ~_BV(TOIE1); // clears the timer overflow interrupt enable bit
|
||||
// timer continues to count without calling the isr
|
||||
}
|
||||
|
||||
void TimerOne::resume() // AR suggested
|
||||
{
|
||||
TCCR1B |= clockSelectBits;
|
||||
}
|
||||
|
||||
void TimerOne::restart() // Depricated - Public interface to start at zero - Lex 10/9/2011
|
||||
{
|
||||
start();
|
||||
}
|
||||
|
||||
void TimerOne::start() // AR addition, renamed by Lex to reflect it's actual role
|
||||
{
|
||||
unsigned int tcnt1;
|
||||
|
||||
TIMSK1 &= ~_BV(TOIE1); // AR added
|
||||
GTCCR |= _BV(PSRSYNC); // AR added - reset prescaler (NB: shared with all 16 bit timers);
|
||||
|
||||
oldSREG = SREG; // AR - save status register
|
||||
cli(); // AR - Disable interrupts
|
||||
TCNT1 = 0;
|
||||
SREG = oldSREG; // AR - Restore status register
|
||||
resume();
|
||||
do { // Nothing -- wait until timer moved on from zero - otherwise get a phantom interrupt
|
||||
oldSREG = SREG;
|
||||
cli();
|
||||
tcnt1 = TCNT1;
|
||||
SREG = oldSREG;
|
||||
} while (tcnt1==0);
|
||||
|
||||
// TIFR1 = 0xff; // AR - Clear interrupt flags
|
||||
// TIMSK1 = _BV(TOIE1); // sets the timer overflow interrupt enable bit
|
||||
}
|
||||
|
||||
void TimerOne::stop()
|
||||
{
|
||||
TCCR1B &= ~(_BV(CS10) | _BV(CS11) | _BV(CS12)); // clears all clock selects bits
|
||||
}
|
||||
|
||||
unsigned long TimerOne::read() //returns the value of the timer in microseconds
|
||||
{ //rember! phase and freq correct mode counts up to then down again
|
||||
unsigned long tmp; // AR amended to hold more than 65536 (could be nearly double this)
|
||||
unsigned int tcnt1; // AR added
|
||||
|
||||
oldSREG= SREG;
|
||||
cli();
|
||||
tmp=TCNT1;
|
||||
SREG = oldSREG;
|
||||
|
||||
char scale=0;
|
||||
switch (clockSelectBits)
|
||||
{
|
||||
case 1:// no prescalse
|
||||
scale=0;
|
||||
break;
|
||||
case 2:// x8 prescale
|
||||
scale=3;
|
||||
break;
|
||||
case 3:// x64
|
||||
scale=6;
|
||||
break;
|
||||
case 4:// x256
|
||||
scale=8;
|
||||
break;
|
||||
case 5:// x1024
|
||||
scale=10;
|
||||
break;
|
||||
}
|
||||
|
||||
do { // Nothing -- max delay here is ~1023 cycles. AR modified
|
||||
oldSREG = SREG;
|
||||
cli();
|
||||
tcnt1 = TCNT1;
|
||||
SREG = oldSREG;
|
||||
} while (tcnt1==tmp); //if the timer has not ticked yet
|
||||
|
||||
//if we are counting down add the top value to how far we have counted down
|
||||
tmp = ( (tcnt1>tmp) ? (tmp) : (long)(ICR1-tcnt1)+(long)ICR1 ); // AR amended to add casts and reuse previous TCNT1
|
||||
return ((tmp*1000L)/(F_CPU /1000L))<<scale;
|
||||
}
|
||||
|
||||
#endif
|
||||
70
SphereBot Arduino/SphereBot/TimerOne.h
Normal file
70
SphereBot Arduino/SphereBot/TimerOne.h
Normal file
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* Interrupt and PWM utilities for 16 bit Timer1 on ATmega168/328
|
||||
* Original code by Jesse Tane for http://labs.ideo.com August 2008
|
||||
* Modified March 2009 by Jérôme Despatis and Jesse Tane for ATmega328 support
|
||||
* Modified June 2009 by Michael Polli and Jesse Tane to fix a bug in setPeriod() which caused the timer to stop
|
||||
* Modified June 2011 by Lex Talionis to add a function to read the timer
|
||||
* Modified Oct 2011 by Andrew Richards to avoid certain problems:
|
||||
* - Add (long) assignments and casts to TimerOne::read() to ensure calculations involving tmp, ICR1 and TCNT1 aren't truncated
|
||||
* - Ensure 16 bit registers accesses are atomic - run with interrupts disabled when accessing
|
||||
* - Remove global enable of interrupts (sei())- could be running within an interrupt routine)
|
||||
* - Disable interrupts whilst TCTN1 == 0. Datasheet vague on this, but experiment shows that overflow interrupt
|
||||
* flag gets set whilst TCNT1 == 0, resulting in a phantom interrupt. Could just set to 1, but gets inaccurate
|
||||
* at very short durations
|
||||
* - startBottom() added to start counter at 0 and handle all interrupt enabling.
|
||||
* - start() amended to enable interrupts
|
||||
* - restart() amended to point at startBottom()
|
||||
* Modiied 7:26 PM Sunday, October 09, 2011 by Lex Talionis
|
||||
* - renamed start() to resume() to reflect it's actual role
|
||||
* - renamed startBottom() to start(). This breaks some old code that expects start to continue counting where it left off
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* See Google Code project http://code.google.com/p/arduino-timerone/ for latest
|
||||
*/
|
||||
#ifndef TIMERONE_h
|
||||
#define TIMERONE_h
|
||||
|
||||
#include <avr/io.h>
|
||||
#include <avr/interrupt.h>
|
||||
|
||||
#define RESOLUTION 65536 // Timer1 is 16 bit
|
||||
|
||||
class TimerOne
|
||||
{
|
||||
public:
|
||||
|
||||
// properties
|
||||
unsigned int pwmPeriod;
|
||||
unsigned char clockSelectBits;
|
||||
char oldSREG; // To hold Status Register while ints disabled
|
||||
|
||||
// methods
|
||||
void initialize(long microseconds=1000000);
|
||||
void start();
|
||||
void stop();
|
||||
void restart();
|
||||
void resume();
|
||||
unsigned long read();
|
||||
void pwm(char pin, int duty, long microseconds=-1);
|
||||
void disablePwm(char pin);
|
||||
void attachInterrupt(void (*isr)(), long microseconds=-1);
|
||||
void detachInterrupt();
|
||||
void setPeriod(long microseconds);
|
||||
void setPwmDuty(char pin, int duty);
|
||||
void (*isrCallback)();
|
||||
};
|
||||
|
||||
extern TimerOne Timer1;
|
||||
#endif
|
||||
BIN
SphereBot Arduino/TimerOne-r11.zip
Normal file
BIN
SphereBot Arduino/TimerOne-r11.zip
Normal file
Binary file not shown.
Reference in New Issue
Block a user