mirror of
https://github.com/digistump/DigistumpArduino.git
synced 2025-09-17 17:32:25 -07:00
Add OLED library - update tiny wire libraries - add support for all PWM channels and PWM on pin 8
This commit is contained in:
@@ -0,0 +1,67 @@
|
||||
SoftRcPulseOut library
|
||||
======================
|
||||
|
||||
**SoftRcPulseOut** is pseudo-asynchronous library designed to generate RC pulse signals. RC pulse signals are intended to command servos, **E**lectronic **S**peed **C**ontrollers (**ESC**), Brushless Controllers and any devices expecting such a command signal.
|
||||
|
||||
Some examples of use cases:
|
||||
-------------------------
|
||||
* **Servo/ESC/Brushless Controller tester**
|
||||
* **Servo sequencer** (look at RcSeq library which uses _SoftRcPulseOut_)
|
||||
* **Robot wheels using modified Servo to support 360° rotation**
|
||||
* **RC pulse stretcher** (in conjunction with **SoftRcPulseIn** library)
|
||||
|
||||
Supported Arduinos:
|
||||
------------------
|
||||
* **ATmega368 (UNO)**
|
||||
* **ATmega2560 (MEGA)**
|
||||
* **ATtiny84 (Standalone)**
|
||||
* **ATtiny85 (Standalone or Digispark)**
|
||||
* **ATtiny167 (Digispark pro)**
|
||||
|
||||
Tip and Tricks:
|
||||
--------------
|
||||
Develop your project on an arduino UNO or MEGA, and then shrink it by loading the sketch in an ATtiny or Digispark (pro).
|
||||
|
||||
API/methods:
|
||||
-----------
|
||||
* The **SoftRcPulseOut** library uses the same API as the regular **SoftwareServo** library:
|
||||
* attach()
|
||||
* attached()
|
||||
* detach()
|
||||
* write()
|
||||
* read()
|
||||
* setMinimumPulse()
|
||||
* setMaximumPulse()
|
||||
* refresh()
|
||||
|
||||
* Two additional methods allow using µs rather than angle in ° :
|
||||
* write_us()
|
||||
* read_us()
|
||||
|
||||
* Methods for version management:
|
||||
* LibVersion
|
||||
* LibRevision
|
||||
* LibTextVersionRevision
|
||||
|
||||
* Synchronization:
|
||||
* By giving **_1_** or **_true_** as optional argument for the **SoftRcPulseOut::refresh()** method, the pulses are refreshed immediately (without waiting for the usual 20ms).
|
||||
|
||||
* the **SoftRcPulseOut::refresh()** method returns **_1_** or **_true_** when the pulses have been refreshed. Testing this return value provides a 20ms timer.
|
||||
|
||||
Design considerations:
|
||||
---------------------
|
||||
The **SoftRcPulseOut** library relies on a 8 bit timer. This allows using it even on little MCU (such as ATtiny85) which do not have any 16 bit timer.
|
||||
|
||||
Whereas a 8 bit timer is used for pulse generation, the jitter is limited by using anticipated interrupt masking.
|
||||
|
||||
Interrups are only masked during rising and falling edges of the pulse signals.
|
||||
|
||||
CAUTION:
|
||||
-------
|
||||
The end user shall also use asynchronous programmation method in the loop() function (not too long blocking functions such as delay(1000): the **SoftRcPulseOut::refresh()** method shall be called at least every 50ms).
|
||||
|
||||
Contact
|
||||
-------
|
||||
|
||||
If you have some ideas of enhancement, please contact me by clicking on: [RC Navy](http://p.loussouarn.free.fr/contact.html).
|
||||
|
@@ -1,13 +1,15 @@
|
||||
#include "SoftRcPulseOut.h"
|
||||
/*
|
||||
Update 01/03/2013: add support for DigiSpark (http://digistump.com): automatic Timer selection (RC Navy: p.loussouarn.free.fr)
|
||||
|
||||
Update 01/03/2013: add support for Digispark (http://digistump.com): automatic Timer selection (RC Navy: p.loussouarn.free.fr)
|
||||
Update 19/08/2014: usage with write_us and read_us fixed
|
||||
|
||||
English: by RC Navy (2012)
|
||||
=======
|
||||
<SoftRcPulseOut>: a library mainly based on the <SoftwareServo> library, but with a better pulse generation to limit jitter.
|
||||
It supports the same methods as <SoftwareServo>.
|
||||
It also support Pulse Width order given in microseconds. The current Pulse Width can also be read in microseconds.
|
||||
The refresh method can admit an optionnal argument (force). If SoftRcPulseOut::refresh(1) is called, the refresh is forced even if 20 ms are not elapsed.
|
||||
The refresh() method returns 1 if refresh done (can be used for synchro and/or for 20ms timer).
|
||||
http://p.loussouarn.free.fr
|
||||
|
||||
Francais: par RC Navy (2012)
|
||||
@@ -16,6 +18,7 @@
|
||||
Elle supporte les memes methodes que <SoftwareServo>.
|
||||
Elle supporte egalement une consigne de largeur d'impulsion passee en microseconde. La largeur de l'impulsion courante peut egalement etre lue en microseconde.
|
||||
La methode refresh peut admettre un parametre optionnel (force). Si SoftRcPulseOut::resfresh(1) est appelee, le refresh est force meme si 20 ms ne se sont pas ecoulee.
|
||||
La methode refresh() retourne 1 si refresh effectue (peut etre utilise pour synhro et/ou 20ms timer).
|
||||
http://p.loussouarn.free.fr
|
||||
*/
|
||||
|
||||
@@ -26,7 +29,7 @@
|
||||
#if (TIMER_TO_USE_FOR_MILLIS==1)
|
||||
#define SOFT_RC_PULSE_OUT_TCNT TCNT1 //For example for ATtiny85
|
||||
#else
|
||||
#define SOFT_RC_PULSE_OUT_TCNT TCNT0 //For example for ATtiny84
|
||||
#define SOFT_RC_PULSE_OUT_TCNT TCNT0 //For example for ATtiny84 and ATtiny167
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -34,60 +37,69 @@ SoftRcPulseOut *SoftRcPulseOut::first;
|
||||
|
||||
#define NO_ANGLE (0xff)
|
||||
|
||||
SoftRcPulseOut::SoftRcPulseOut() : pin(0),angle(NO_ANGLE),pulse0(0),min16(34),max16(150),next(0)
|
||||
SoftRcPulseOut::SoftRcPulseOut() : pin(0), angle(NO_ANGLE), pulse0(0), min16(34), max16(150), next(0)
|
||||
{}
|
||||
|
||||
void SoftRcPulseOut::setMinimumPulse(uint16_t t)
|
||||
{
|
||||
min16 = t/16;
|
||||
min16 = t / 16;
|
||||
}
|
||||
|
||||
void SoftRcPulseOut::setMaximumPulse(uint16_t t)
|
||||
{
|
||||
max16 = t/16;
|
||||
max16 = t / 16;
|
||||
}
|
||||
|
||||
uint8_t SoftRcPulseOut::attach(int pinArg)
|
||||
{
|
||||
pin = pinArg;
|
||||
angle = NO_ANGLE;
|
||||
pin = pinArg;
|
||||
angle = NO_ANGLE;
|
||||
pulse0 = 0;
|
||||
next = first;
|
||||
first = this;
|
||||
digitalWrite(pin,0);
|
||||
pinMode(pin,OUTPUT);
|
||||
return 1;
|
||||
next = first;
|
||||
first = this;
|
||||
digitalWrite(pin, LOW);
|
||||
pinMode(pin, OUTPUT);
|
||||
return (1);
|
||||
}
|
||||
|
||||
void SoftRcPulseOut::detach()
|
||||
{
|
||||
for ( SoftRcPulseOut **p = &first; *p != 0; p = &((*p)->next) ) {
|
||||
if ( *p == this) {
|
||||
*p = this->next;
|
||||
this->next = 0;
|
||||
return;
|
||||
}
|
||||
for ( SoftRcPulseOut **p = &first; *p != 0; p = &((*p)->next) )
|
||||
{
|
||||
if ( *p == this )
|
||||
{
|
||||
*p = this->next;
|
||||
this->next = 0;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SoftRcPulseOut::write(int angleArg)
|
||||
{
|
||||
if ( angleArg < 0) angleArg = 0;
|
||||
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.
|
||||
#ifdef TIMER0_TICK_EVERY_X_CYCLES
|
||||
pulse0 = (min16*16L*clockCyclesPerMicrosecond() + (max16-min16)*(16L*clockCyclesPerMicrosecond())*angle/180L)/TIMER0_TICK_EVERY_X_CYCLES;
|
||||
#ifdef MS_TIMER_TICK_EVERY_X_CYCLES
|
||||
pulse0 = (min16 * 16L * clockCyclesPerMicrosecond() + (max16 - min16) * (16L * clockCyclesPerMicrosecond()) * angle / 180L) / MS_TIMER_TICK_EVERY_X_CYCLES;
|
||||
#else
|
||||
pulse0 = (min16*16L*clockCyclesPerMicrosecond() + (max16-min16)*(16L*clockCyclesPerMicrosecond())*angle/180L)/64L;
|
||||
pulse0 = (min16 * 16L * clockCyclesPerMicrosecond() + (max16 - min16) * (16L * clockCyclesPerMicrosecond()) * angle / 180L) / 64L;
|
||||
#endif
|
||||
}
|
||||
|
||||
void SoftRcPulseOut::write_us(int PulseWidth_us)
|
||||
void SoftRcPulseOut::write_us(uint16_t PulseWidth_us)
|
||||
{
|
||||
SoftRcPulseOut::write(map(PulseWidth_us,min16*16,max16*16,0,180));
|
||||
if ( PulseWidth_us < (min16 * 16)) PulseWidth_us = (min16 * 16);
|
||||
if ( PulseWidth_us > (max16 * 16)) PulseWidth_us = (max16 * 16);
|
||||
#ifdef MS_TIMER_TICK_EVERY_X_CYCLES
|
||||
pulse0 = (PulseWidth_us * clockCyclesPerMicrosecond()) / MS_TIMER_TICK_EVERY_X_CYCLES;
|
||||
#else
|
||||
pulse0 = (PulseWidth_us * clockCyclesPerMicrosecond()) / 64L;
|
||||
#endif
|
||||
angle = map(PulseWidth_us, min16 * 16, max16 * 16, 0, 180);
|
||||
}
|
||||
|
||||
uint8_t SoftRcPulseOut::read()
|
||||
@@ -95,114 +107,123 @@ uint8_t SoftRcPulseOut::read()
|
||||
return angle;
|
||||
}
|
||||
|
||||
uint8_t SoftRcPulseOut::read_us()
|
||||
uint16_t SoftRcPulseOut::read_us()
|
||||
{
|
||||
return map(angle,0,180,min16*16,max16*16);
|
||||
#ifdef MS_TIMER_TICK_EVERY_X_CYCLES
|
||||
return((pulse0 * MS_TIMER_TICK_EVERY_X_CYCLES) / clockCyclesPerMicrosecond());
|
||||
#else
|
||||
return((pulse0 * 64L) / clockCyclesPerMicrosecond());
|
||||
#endif
|
||||
}
|
||||
|
||||
uint8_t SoftRcPulseOut::attached()
|
||||
{
|
||||
for ( SoftRcPulseOut *p = first; p != 0; p = p->next ) {
|
||||
if ( p == this) return 1;
|
||||
}
|
||||
return 0;
|
||||
for ( SoftRcPulseOut *p = first; p != 0; p = p->next )
|
||||
{
|
||||
if ( p == this) return (1);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
uint8_t SoftRcPulseOut::refresh(bool force /* = false */)
|
||||
{
|
||||
uint8_t RefreshDone=0;
|
||||
uint8_t count = 0, i = 0;
|
||||
uint16_t base = 0;
|
||||
SoftRcPulseOut *p;
|
||||
static unsigned long lastRefresh = 0;
|
||||
unsigned long m = millis();
|
||||
if(!force)
|
||||
{
|
||||
// if we haven't wrapped millis, and 20ms have not passed, then don't do anything
|
||||
if ( m >= lastRefresh && m < lastRefresh + 20) return(RefreshDone);
|
||||
}
|
||||
RefreshDone=1; //Ok: Refresh will be performed
|
||||
lastRefresh = m;
|
||||
uint8_t RefreshDone = 0;
|
||||
uint8_t count = 0, i = 0;
|
||||
uint16_t base = 0;
|
||||
SoftRcPulseOut *p;
|
||||
static uint32_t lastRefresh = 0;
|
||||
uint32_t m = millis();
|
||||
|
||||
if(!force)
|
||||
{
|
||||
// if we haven't wrapped millis, and 20ms have not passed, then don't do anything
|
||||
if ( (m - lastRefresh) < 20UL ) return(RefreshDone);
|
||||
}
|
||||
RefreshDone = 1; //Ok: Refresh will be performed
|
||||
lastRefresh = m;
|
||||
|
||||
for ( p = first; p != 0; p = p->next ) if ( p->pulse0) count++;
|
||||
if ( count == 0) return(RefreshDone);
|
||||
for ( p = first; p != 0; p = p->next ) if ( p->pulse0 ) count++;
|
||||
if ( count == 0 ) return(RefreshDone);
|
||||
|
||||
// gather all the SoftRcPulseOuts in an array
|
||||
SoftRcPulseOut *s[count];
|
||||
for ( p = first; p != 0; p = p->next ) if ( p->pulse0) s[i++] = p;
|
||||
// gather all the SoftRcPulseOuts in an array
|
||||
SoftRcPulseOut *s[count];
|
||||
for ( p = first; p != 0; p = p->next ) if ( p->pulse0) s[i++] = p;
|
||||
|
||||
// bubblesort the SoftRcPulseOuts by pulse time, ascending order
|
||||
s[0]->ItMasked=0;
|
||||
for(;;)
|
||||
{
|
||||
uint8_t moved = 0;
|
||||
for ( i = 1; i < count; i++)
|
||||
{
|
||||
s[i]->ItMasked=0;
|
||||
if ( s[i]->pulse0 < s[i-1]->pulse0)
|
||||
{
|
||||
SoftRcPulseOut *t = s[i];
|
||||
s[i] = s[i-1];
|
||||
s[i-1] = t;
|
||||
moved = 1;
|
||||
}
|
||||
}
|
||||
if ( !moved) break;
|
||||
// bubblesort the SoftRcPulseOuts by pulse time, ascending order
|
||||
s[0]->ItMasked = 0;
|
||||
for(;;)
|
||||
{
|
||||
uint8_t moved = 0;
|
||||
for ( i = 1; i < count; i++ )
|
||||
{
|
||||
s[i]->ItMasked = 0;
|
||||
if ( s[i]->pulse0 < s[i - 1]->pulse0 )
|
||||
{
|
||||
SoftRcPulseOut *t = s[i];
|
||||
s[i] = s[i - 1];
|
||||
s[i - 1] = t;
|
||||
moved = 1;
|
||||
}
|
||||
}
|
||||
for ( i = 1; i < count; i++)
|
||||
if ( !moved ) break;
|
||||
}
|
||||
for ( i = 1; i < count; i++ )
|
||||
{
|
||||
if ( abs(s[i]->pulse0 - s[i - 1]->pulse0) <= 5)
|
||||
{
|
||||
s[i]->ItMasked = 1; /* 2 consecutive Pulses are close each other, so do not unmask interrupts between Pulses */
|
||||
}
|
||||
}
|
||||
// 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/SoftRcPulseOut after them. This could be compensated, but I feel
|
||||
// it is within the margin of error of software SoftRcPulseOuts that could catch
|
||||
// an extra interrupt handler at any time.
|
||||
noInterrupts();
|
||||
for ( i = 0; i < count; i++ ) digitalWrite( s[i]->pin, 1);
|
||||
interrupts();
|
||||
|
||||
uint8_t start = SOFT_RC_PULSE_OUT_TCNT;
|
||||
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;
|
||||
#ifndef MS_TIMER_TICK_EVERY_X_CYCLES
|
||||
uint16_t it = go - 4; /* 4 Ticks is OK for UNO @ 16MHz with default prescaler*/ /* Mask Interruptions just before setting down the pin */
|
||||
#else
|
||||
uint16_t it = go - max(4, (256 / MS_TIMER_TICK_EVERY_X_CYCLES)); /* 4 Ticks is OK for UNO @ 16MHz */ /* Mask Interruptions just before setting down the pin */
|
||||
#endif
|
||||
// loop until we reach or pass 'go' time: this is a blocking loop (max 2400us) except for non masked ISR (between edges)
|
||||
for (;;)
|
||||
{
|
||||
now = SOFT_RC_PULSE_OUT_TCNT;
|
||||
if ( now < last ) base += 256;
|
||||
last = now;
|
||||
if( !s[i]->ItMasked )
|
||||
{
|
||||
if( base + now > it)
|
||||
{
|
||||
if ( abs(s[i]->pulse0 - s[i-1]->pulse0)<=5)
|
||||
{
|
||||
s[i]->ItMasked=1; /* 2 consecutive Pulses are close each other, so do not unmask interrupts between Pulses */
|
||||
}
|
||||
noInterrupts();
|
||||
s[i]->ItMasked = 1;
|
||||
}
|
||||
// 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/SoftRcPulseOut after them. This could be compensated, but I feel
|
||||
// it is within the margin of error of software SoftRcPulseOuts that could catch
|
||||
// an extra interrupt handler at any time.
|
||||
noInterrupts();
|
||||
for ( i = 0; i < count; i++) digitalWrite( s[i]->pin, 1);
|
||||
interrupts();
|
||||
|
||||
uint8_t start = SOFT_RC_PULSE_OUT_TCNT;
|
||||
uint8_t now = start;
|
||||
uint8_t last = now;
|
||||
|
||||
// Now wait for each pin's time in turn..
|
||||
for ( i = 0; i < count; i++)
|
||||
}
|
||||
if ( base + now > go )
|
||||
{
|
||||
digitalWrite( s[i]->pin, 0);
|
||||
if( (i + 1) < count )
|
||||
{
|
||||
uint16_t go = start + s[i]->pulse0;
|
||||
uint16_t it = go - 4; /* 4 Ticks is OK for UNO @ 16MHz */ /* Mask Interruptions just before setting down the pin */
|
||||
|
||||
// loop until we reach or pass 'go' time
|
||||
for (;;)
|
||||
{
|
||||
now = SOFT_RC_PULSE_OUT_TCNT;
|
||||
if ( now < last) base += 256;
|
||||
last = now;
|
||||
if(!s[i]->ItMasked)
|
||||
{
|
||||
if( base + now > it)
|
||||
{
|
||||
noInterrupts();
|
||||
s[i]->ItMasked=1;
|
||||
}
|
||||
}
|
||||
if ( base + now > go)
|
||||
{
|
||||
digitalWrite( s[i]->pin,0);
|
||||
if((i+1)<count)
|
||||
{
|
||||
if(!s[i+1]->ItMasked)
|
||||
{
|
||||
interrupts();
|
||||
}
|
||||
}else interrupts();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return(RefreshDone);
|
||||
if( !s[i + 1]->ItMasked )
|
||||
{
|
||||
interrupts();
|
||||
}
|
||||
}else interrupts();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return(RefreshDone);
|
||||
}
|
||||
|
@@ -2,14 +2,16 @@
|
||||
#define SoftRcPulseOut_h
|
||||
|
||||
/*
|
||||
Update 01/03/2013: add support for DigiSpark (http://digistump.com): automatic Timer selection (RC Navy: p.loussouarn.free.fr)
|
||||
|
||||
Update 01/03/2013: add support for Digispark (http://digistump.com): automatic Timer selection (RC Navy: p.loussouarn.free.fr)
|
||||
Update 19/08/2014: usage with write_us and read_us fixed and optimized for highest resolution
|
||||
|
||||
English: by RC Navy (2012)
|
||||
=======
|
||||
<SoftRcPulseOut>: a library mainly based on the <SoftwareServo> library, but with a better pulse generation to limit jitter.
|
||||
It supports the same methods as <SoftwareServo>.
|
||||
It also support Pulse Width order given in microseconds. The current Pulse Width can also be read in microseconds.
|
||||
The refresh method can admit an optionnal argument (force). If SoftRcPulseOut::refresh(1) is called, the refresh is forced even if 20 ms are not elapsed.
|
||||
The refresh() method returns 1 if refresh done (can be used for synchro and/or for 20ms timer).
|
||||
http://p.loussouarn.free.fr
|
||||
|
||||
Francais: par RC Navy (2012)
|
||||
@@ -18,6 +20,7 @@
|
||||
Elle supporte les memes methodes que <SoftwareServo>.
|
||||
Elle supporte egalement une consigne de largeur d'impulsion passee en microseconde. La largeur de l'impulsion courante peut egalement etre lue en microseconde.
|
||||
La methode refresh peut admettre un parametre optionnel (force). Si SoftRcPulseOut::resfresh(1) est appelee, le refresh est force meme si 20 ms ne se sont pas ecoulee.
|
||||
La methode refresh() retourne 1 si refresh effectue (peut etre utilise pour synhro et/ou 20ms timer).
|
||||
http://p.loussouarn.free.fr
|
||||
*/
|
||||
|
||||
@@ -32,28 +35,40 @@
|
||||
class SoftRcPulseOut
|
||||
{
|
||||
private:
|
||||
boolean ItMasked;
|
||||
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 SoftRcPulseOut *next;
|
||||
static SoftRcPulseOut* first;
|
||||
boolean ItMasked;
|
||||
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 SoftRcPulseOut *next;
|
||||
static SoftRcPulseOut *first;
|
||||
public:
|
||||
SoftRcPulseOut();
|
||||
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
|
||||
void write_us(int); // specify the angle in microseconds, 500 to 2500
|
||||
uint8_t read(); // return the current angle
|
||||
uint8_t read_us(); // return the current pulse with in microseconds
|
||||
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 uint8_t refresh(bool force = false); // 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
|
||||
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
|
||||
void write_us(uint16_t); // specify the angle in microseconds, 500 to 2500
|
||||
uint8_t read(); // return the current angle
|
||||
uint16_t read_us(); // return the current pulse with in microseconds
|
||||
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 uint8_t refresh(bool force = false);// 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
|
||||
};
|
||||
|
||||
/* Methodes en Francais English native methods */
|
||||
#define attache attach
|
||||
#define detache detach
|
||||
#define ecrit write
|
||||
#define ecrit_us write_us
|
||||
#define lit read
|
||||
#define lit_us read_us
|
||||
#define estAttache attached
|
||||
#define definitImpulsionMinimum setMinimumPulse
|
||||
#define definitImpulsionMaximum setMaximumPulse
|
||||
#define rafraichit refresh
|
||||
|
||||
#endif
|
||||
|
@@ -19,6 +19,8 @@ SoftRcPulseOut myservo; // create servo object to control a servo
|
||||
|
||||
#define REFRESH_PERIOD_MS 20
|
||||
|
||||
#define NOW 1
|
||||
|
||||
int val; // variable to read the value from the analog pin
|
||||
|
||||
void setup()
|
||||
@@ -32,6 +34,6 @@ void loop()
|
||||
val = map(val, 0, 1023, 0, 179); // scale it to use it with the servo (value between 0 and 180)
|
||||
myservo.write(val); // sets the servo position according to the scaled value
|
||||
delay(REFRESH_PERIOD_MS); // waits for the servo to get there
|
||||
SoftRcPulseOut::refresh(); // generates the servo pulse
|
||||
SoftRcPulseOut::refresh(NOW); // generates the servo pulse Now
|
||||
}
|
||||
|
||||
|
@@ -52,7 +52,7 @@ boolean LedState=HIGH;
|
||||
|
||||
void setup()
|
||||
{
|
||||
#if !defined(__AVR_ATtiny24__) && !defined(__AVR_ATtiny44__) && !defined(__AVR_ATtiny84__) && !defined(__AVR_ATtiny25__) && !defined(__AVR_ATtiny45__) && !defined(__AVR_ATtiny85__)
|
||||
#if !defined(__AVR_ATtiny24__) && !defined(__AVR_ATtiny44__) && !defined(__AVR_ATtiny84__) && !defined(__AVR_ATtiny25__) && !defined(__AVR_ATtiny45__) && !defined(__AVR_ATtiny85__) && !defined(__AVR_ATtiny167__)
|
||||
Serial.begin(9600);
|
||||
Serial.print("SoftRcPulseIn library V");Serial.print(SoftRcPulseIn::LibTextVersionRevision());Serial.print(" demo"); /* For arduino UNO which has an hardware UART, display the library version in the console */
|
||||
#endif
|
||||
@@ -74,8 +74,8 @@ static uint16_t Width_us=NEUTRAL_US; /* Static to keep the value at the next loo
|
||||
ServoMotor[INVERTED].write_us((NEUTRAL_US*2)-Width_us); /* Inverted Signal */
|
||||
SoftRcPulseOut::refresh(NOW); /* NOW argument (=1) allows to synchronize outgoing pulses with incoming pulses */
|
||||
RxPulseStartMs=millis(); /* Restart the Chrono for Pulse */
|
||||
#if !defined(__AVR_ATtiny24__) && !defined(__AVR_ATtiny44__) && !defined(__AVR_ATtiny84__) && !defined(__AVR_ATtiny25__) && !defined(__AVR_ATtiny45__) && !defined(__AVR_ATtiny85__)
|
||||
Serial.print("Pulse=");Serial.println(Largeur_us); /* For arduino UNO which has an hardware UART, display the library version in the console */
|
||||
#if !defined(__AVR_ATtiny24__) && !defined(__AVR_ATtiny44__) && !defined(__AVR_ATtiny84__) && !defined(__AVR_ATtiny25__) && !defined(__AVR_ATtiny45__) && !defined(__AVR_ATtiny85__) && !defined(__AVR_ATtiny167__)
|
||||
Serial.print("Pulse=");Serial.println(Width_us); /* For arduino UNO which has an hardware UART, display the library version in the console */
|
||||
#endif
|
||||
}
|
||||
else
|
||||
|
@@ -12,6 +12,8 @@ SoftRcPulseOut myservo; // create servo object to control a servo
|
||||
|
||||
#define REFRESH_PERIOD_MS 20
|
||||
|
||||
#define NOW 1
|
||||
|
||||
int pos = 0; // variable to store the servo position
|
||||
|
||||
void setup()
|
||||
@@ -26,12 +28,12 @@ void loop()
|
||||
{ // in steps of 1 degree
|
||||
myservo.write(pos); // tell servo to go to position in variable 'pos'
|
||||
delay(REFRESH_PERIOD_MS); // waits 20ms for refresh period
|
||||
SoftRcPulseOut::refresh(1); // generates the servo pulse
|
||||
SoftRcPulseOut::refresh(NOW); // generates the servo pulse Now
|
||||
}
|
||||
for(pos = 180; pos>=1; pos-=1) // goes from 180 degrees to 0 degrees
|
||||
{
|
||||
myservo.write(pos); // tell servo to go to position in variable 'pos'
|
||||
delay(REFRESH_PERIOD_MS); // waits 20ms for for refresh period
|
||||
SoftRcPulseOut::refresh(1); // generates the servo pulse
|
||||
SoftRcPulseOut::refresh(NOW); // generates the servo pulse Now
|
||||
}
|
||||
}
|
||||
|
@@ -0,0 +1,37 @@
|
||||
// SweepNoDelay
|
||||
// by RC Navy (http://p.loussouarn.free.fr/arduino/arduino.html>)
|
||||
// This sketch can work with ATtiny and Arduino UNO, MEGA, etc...
|
||||
// This example code is in the public domain.
|
||||
|
||||
#include <SoftRcPulseOut.h>
|
||||
|
||||
SoftRcPulseOut myservo; // create servo object to control a servo
|
||||
// a maximum of eight servo objects can be created
|
||||
#define SERVO_PIN 0
|
||||
|
||||
#define UP_DIRECTION +1
|
||||
#define DOWN_DIRECTION -1
|
||||
|
||||
#define POS_MIN 0
|
||||
#define POS_MAX 180
|
||||
|
||||
int pos = POS_MIN; // variable to store the servo position
|
||||
int step = UP_DIRECTION;
|
||||
|
||||
void setup()
|
||||
{
|
||||
myservo.attach(SERVO_PIN); // attaches the servo on pin defined by SERVO_PIN to the servo object
|
||||
myservo.write(pos);
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
if (SoftRcPulseOut::refresh()) // refresh() returns 1 every 20ms (after pulse update)
|
||||
{
|
||||
// We arrive here every 20ms
|
||||
pos += step;
|
||||
if(pos >= POS_MAX) step = DOWN_DIRECTION; //180 degrees reached -> Change direction
|
||||
if(pos <= POS_MIN) step = UP_DIRECTION; // 0 degrees reached -> Change direction
|
||||
myservo.write(pos);
|
||||
}
|
||||
}
|
@@ -19,6 +19,7 @@ SoftRcPulseOut myservo; // create servo object to control a servo
|
||||
|
||||
#define REFRESH_PERIOD_MS 20
|
||||
|
||||
#define NOW 1
|
||||
|
||||
#define MOY_SUR_1_VALEUR 0
|
||||
#define MOY_SUR_2_VALEURS 1
|
||||
@@ -46,8 +47,8 @@ static int ValMoyennee;
|
||||
val = analogRead(POT_PIN); // reads the value of the potentiometer (value between 0 and 1023)
|
||||
val = map(val, 0, 1023, 0, 179); // scale it to use it with the servo (value between 0 and 180)
|
||||
MOYENNE(ValMoyennee,val,TAUX_DE_MOYENNAGE);//If there is lots of noise: average with TAUX_DE_MOYENNAGE
|
||||
myservo.write(ValMoyennee); // sets the servo position according to the scaled value
|
||||
myservo.write(ValMoyennee); // sets the servo position according to the scaled value
|
||||
delay(REFRESH_PERIOD_MS); // waits for the servo to get there
|
||||
SoftRcPulseOut::refresh(); // generates the servo pulse
|
||||
SoftRcPulseOut::refresh(NOW); // generates the servo pulse
|
||||
}
|
||||
|
||||
|
@@ -6,21 +6,31 @@
|
||||
# Datatypes (KEYWORD1)
|
||||
#######################################
|
||||
|
||||
SoftRcPulseOut KEYWORD1
|
||||
SoftRcPulseOut KEYWORD1
|
||||
|
||||
#######################################
|
||||
# Methods and Functions (KEYWORD2)
|
||||
#######################################
|
||||
attach KEYWORD2
|
||||
detach KEYWORD2
|
||||
write KEYWORD2
|
||||
write_us KEYWORD2
|
||||
read KEYWORD2
|
||||
read_us KEYWORD2
|
||||
attached KEYWORD2
|
||||
setMinimumPulse KEYWORD2
|
||||
setMaximumPulse KEYWORD2
|
||||
refresh KEYWORD2
|
||||
attach KEYWORD2
|
||||
attache KEYWORD2
|
||||
detach KEYWORD2
|
||||
detache KEYWORD2
|
||||
write KEYWORD2
|
||||
ecrit KEYWORD2
|
||||
write_us KEYWORD2
|
||||
ecrit_us KEYWORD2
|
||||
read KEYWORD2
|
||||
lit KEYWORD2
|
||||
read_us KEYWORD2
|
||||
lit_us KEYWORD2
|
||||
attached KEYWORD2
|
||||
estAttache KEYWORD2
|
||||
setMinimumPulse KEYWORD2
|
||||
definitImpulsionMinimum KEYWORD2
|
||||
setMaximumPulse KEYWORD2
|
||||
definitImpulsionMaximum KEYWORD2
|
||||
refresh KEYWORD2
|
||||
rafraichit KEYWORD2
|
||||
|
||||
#######################################
|
||||
# Constants (LITERAL1)
|
||||
|
Reference in New Issue
Block a user