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:
@@ -17,7 +17,7 @@ This sequence uses:
|
||||
IMPORTANT:
|
||||
=========
|
||||
For this sketch, which is using <DigiUSB> library:
|
||||
1) Comment "#define RC_SEQ_WITH_SOFT_RC_PULSE_IN_SUPPORT" in "arduino-1.xx\libraries\RcSeq.h".
|
||||
1) Comment "#define RC_SEQ_WITH_SOFT_RC_PULSE_IN_SUPPORT" AND #define RC_SEQ_CONTROL_SUPPORT in "arduino-1.xx\libraries\RcSeq.h".
|
||||
This will disable the code to manage incoming RC pulses and save some flash memory.
|
||||
RC_SEQ_WITH_SHORT_ACTION_SUPPORT and RC_SEQ_WITH_SOFT_RC_PULSE_OUT_SUPPORT shall be defined
|
||||
2) Replace #define RING_BUFFER_SIZE 128 with #define RING_BUFFER_SIZE 32 in "arduino-1.xx\libraries\DigisparkUSB\DigiUSB.h".
|
||||
@@ -38,17 +38,17 @@ static void ToggleLed(void); /* Declare Short Action: Toggle a LED */
|
||||
#include <RcSeq.h>
|
||||
#include <SoftRcPulseOut.h>
|
||||
|
||||
#define LED_PIN 1
|
||||
#define LED_PIN 1
|
||||
|
||||
/*****************************************************************/
|
||||
/* STEP #2: Enumeration of the servos used in the sequence */
|
||||
/*****************************************************************/
|
||||
enum {ROTATION_SERVO=0, UP_DOWN_SERVO , SERVO_NB};
|
||||
enum {ROTATION_SERVO=0, UP_DOWN_SERVO, SERVO_NB};
|
||||
|
||||
/*****************************************************************/
|
||||
/* STEP #3: Servos Digital Pins assignment */
|
||||
/*****************************************************************/
|
||||
#define UP_DOWN_SERVO_PIN 2
|
||||
#define UP_DOWN_SERVO_PIN 2
|
||||
/* /!\ Do not use Pin 3 (used by USB) /!\ */
|
||||
/* /!\ Do not use Pin 4 (used by USB) /!\ */
|
||||
#define ROTATION_SERVO_PIN 5
|
||||
@@ -56,12 +56,12 @@ enum {ROTATION_SERVO=0, UP_DOWN_SERVO , SERVO_NB};
|
||||
/**************************************************************************************/
|
||||
/* STEP #4: Declaration of the angles of the servos for the different motions (in °) */
|
||||
/**************************************************************************************/
|
||||
#define UP_DOWN_ON_DECK_POS 120 /* Zodiac on the deck */
|
||||
#define UP_DOWN_ON_AIR_POS 180 /* Zodiac in the air */
|
||||
#define UP_DOWN_ON_SEA_POS 0 /* Zodiac at sea level */
|
||||
#define UP_DOWN_ON_DECK_POS 120 /* Zodiac on the deck */
|
||||
#define UP_DOWN_ON_AIR_POS 180 /* Zodiac in the air */
|
||||
#define UP_DOWN_ON_SEA_POS 0 /* Zodiac at sea level */
|
||||
|
||||
#define ROTATION_ABOVE_DECK_POS 90 /* crane at deck side */
|
||||
#define ROTATION_ABOVE_SEA_POS 0 /* crane at sea side */
|
||||
#define ROTATION_ABOVE_DECK_POS 90 /* crane at deck side */
|
||||
#define ROTATION_ABOVE_SEA_POS 0 /* crane at sea side */
|
||||
|
||||
|
||||
/***************************************************************************************************************************************/
|
||||
@@ -80,26 +80,26 @@ Order <--DECK_TO_AIR_DURATION_MS--> <--DECK_TO_SEA_ROTATION_DUR
|
||||
/* STEP #6: With the help of the temporal diagram, declare start up time, the motion duration of servo and optional delay */
|
||||
/**************************************************************************************************************************************************/
|
||||
/* Tune below all the motion duration. Do not forget to add a trailer 'UL' for each value to force them in Unsigned Long type */
|
||||
#define START_UP_DECK_TO_AIR_MS 0UL /* 0 for immediate start up, but you can put a delay here. Ex: 2000UL, will delay the startup of the whole sequence after 2 seconds */
|
||||
#define DECK_TO_AIR_DURATION_MS 3000UL
|
||||
#define START_UP_DECK_TO_AIR_MS 0UL /* 0 for immediate start up, but you can put a delay here. Ex: 2000UL, will delay the startup of the whole sequence after 2 seconds */
|
||||
#define DECK_TO_AIR_DURATION_MS 3000UL
|
||||
|
||||
#define START_UP_DECK_TO_SEA_ROTATION_MS (START_UP_DECK_TO_AIR_MS + DECK_TO_AIR_DURATION_MS)
|
||||
#define DECK_TO_SEA_ROTATION_DURATION_MS 3000UL
|
||||
#define START_UP_DECK_TO_SEA_ROTATION_MS (START_UP_DECK_TO_AIR_MS + DECK_TO_AIR_DURATION_MS)
|
||||
#define DECK_TO_SEA_ROTATION_DURATION_MS 3000UL
|
||||
|
||||
#define START_UP_AIR_TO_SEA_FALLING_MS (START_UP_DECK_TO_SEA_ROTATION_MS + DECK_TO_SEA_ROTATION_DURATION_MS)
|
||||
#define AIR_TO_SEA_FALLING_DURATION_MS 9000UL
|
||||
#define START_UP_AIR_TO_SEA_FALLING_MS (START_UP_DECK_TO_SEA_ROTATION_MS + DECK_TO_SEA_ROTATION_DURATION_MS)
|
||||
#define AIR_TO_SEA_FALLING_DURATION_MS 9000UL
|
||||
|
||||
#define DELAY_BEFORE_RISING_UP_MS 6000UL
|
||||
#define DELAY_BEFORE_RISING_UP_MS 6000UL
|
||||
|
||||
#define START_UP_SEA_TO_AIR_RISING_MS (START_UP_AIR_TO_SEA_FALLING_MS + AIR_TO_SEA_FALLING_DURATION_MS + DELAY_BEFORE_RISING_UP_MS)
|
||||
#define SEA_TO_AIR_RISING_DURATION_MS 9000UL
|
||||
#define START_UP_SEA_TO_AIR_RISING_MS (START_UP_AIR_TO_SEA_FALLING_MS + AIR_TO_SEA_FALLING_DURATION_MS + DELAY_BEFORE_RISING_UP_MS)
|
||||
#define SEA_TO_AIR_RISING_DURATION_MS 9000UL
|
||||
|
||||
#define START_UP_SEA_TO_DECK_ROTATION_MS (START_UP_SEA_TO_AIR_RISING_MS + SEA_TO_AIR_RISING_DURATION_MS)
|
||||
#define SEA_TO_DECK_ROTATION_DURATION_MS 3000UL
|
||||
#define START_UP_SEA_TO_DECK_ROTATION_MS (START_UP_SEA_TO_AIR_RISING_MS + SEA_TO_AIR_RISING_DURATION_MS)
|
||||
#define SEA_TO_DECK_ROTATION_DURATION_MS 3000UL
|
||||
|
||||
|
||||
#define START_UP_AIR_TO_DECK_FALLING_MS (START_UP_SEA_TO_DECK_ROTATION_MS + SEA_TO_DECK_ROTATION_DURATION_MS)
|
||||
#define AIR_TO_DECK_FALLING_DURATION_MS 3000UL
|
||||
#define START_UP_AIR_TO_DECK_FALLING_MS (START_UP_SEA_TO_DECK_ROTATION_MS + SEA_TO_DECK_ROTATION_DURATION_MS)
|
||||
#define AIR_TO_DECK_FALLING_DURATION_MS 3000UL
|
||||
|
||||
/********************************************************************************************************************/
|
||||
/* STEP #7: Declare here the percentage of motion to be performed at half speed for servo start up and stop */
|
||||
@@ -118,7 +118,7 @@ Order <--DECK_TO_AIR_DURATION_MS--> <--DECK_TO_SEA_ROTATION_DUR
|
||||
/* - Percentage of motion performed at half speed for servo start and servo stop (Soft start and Soft stop) */
|
||||
/* Note: START_STOP_PER_CENT not used (MOTION_WITHOUT_SOFT_START_AND_STOP() macro used) */
|
||||
/************************************************************************************************************/
|
||||
SequenceSt_t ZodiacSequence[] PROGMEM = {
|
||||
const SequenceSt_t ZodiacSequence[] PROGMEM = {
|
||||
SHORT_ACTION_TO_PERFORM(ToggleLed, START_UP_DECK_TO_AIR_MS) /* Switch ON the Led at the beginning of the sequence */
|
||||
SHORT_ACTION_TO_PERFORM(ToggleLed, START_UP_AIR_TO_DECK_FALLING_MS+AIR_TO_DECK_FALLING_DURATION_MS) /* Switch OFF the Led at the beginning of the sequence: You are not obliged to put this line at the end of the table */
|
||||
/* 1) The crane lifts the pneumatic Zodiac from the deck to the air and stops */
|
||||
@@ -155,7 +155,7 @@ void setup()
|
||||
/**************************************************************************************************************************/
|
||||
/* STEP #11: declare the sequence command signal (0), the stick level (0), and the sequence to call */
|
||||
/**************************************************************************************************************************/
|
||||
RcSeq_DeclareCommandAndSequence(0, 0, RC_SEQUENCE(ZodiacSequence)); /* 0,0 since there's no RC command */
|
||||
RcSeq_DeclareCommandAndSequence(0, 0, RC_SEQUENCE(ZodiacSequence)); /* 0, 0 since there's no RC command */
|
||||
}
|
||||
|
||||
void loop()
|
||||
@@ -172,12 +172,12 @@ char RxChar;
|
||||
/****************************************************************************************************************/
|
||||
if(DigiUSB.available())
|
||||
{
|
||||
RxChar=DigiUSB.read();
|
||||
if(RxChar=='g') /* Go ! */
|
||||
RxChar = DigiUSB.read();
|
||||
if(RxChar == 'g') /* Go ! */
|
||||
{
|
||||
RcSeq_LaunchSequence(ZodiacSequence);
|
||||
}
|
||||
if(RxChar=='t') /* Toggle LED ! */
|
||||
if(RxChar == 't') /* Toggle LED ! */
|
||||
{
|
||||
RcSeq_LaunchShortAction(ToggleLed); /* You can toggle LED during Servo Motion! */
|
||||
}
|
||||
@@ -187,7 +187,7 @@ char RxChar;
|
||||
|
||||
static void ToggleLed(void)
|
||||
{
|
||||
static boolean Status=LOW;
|
||||
Status=!Status; /* Toggle Status */
|
||||
static boolean Status = LOW;
|
||||
Status = !Status; /* Toggle Status */
|
||||
digitalWrite(LED_PIN, Status);
|
||||
}
|
||||
}
|
||||
|
@@ -81,11 +81,11 @@ enum {RC_CHANNEL, RC_CHANNEL_NB}; /* Here, as there is a single channel, we coul
|
||||
/* Declaration of the custom keyboard": the pulse width of the push buttons do not need to be equidistant */
|
||||
enum {PUSH_BUTTON1, PUSH_BUTTON2, PUSH_BUTTON3, PUSH_BUTTON4, PUSH_BUTTON5, PUSH_BUTTON_NBR};
|
||||
#define TOLERANCE 40 /* Tolerance +/- (in microseconds): CAUTION, no overlap allowed between 2 adjacent active areas . active area width = 2 x TOLERANCE (us) */
|
||||
KeyMap_t CustomKeyboard[] PROGMEM ={ {CENTER_VALUE_US(1100,TOLERANCE)}, /* PUSH_BUTTON1: +/-40 us */
|
||||
{CENTER_VALUE_US(1300,TOLERANCE)}, /* PUSH_BUTTON2: +/-40 us */
|
||||
{CENTER_VALUE_US(1500,TOLERANCE)}, /* PUSH_BUTTON3: +/-40 us */
|
||||
{CENTER_VALUE_US(1700,TOLERANCE)}, /* PUSH_BUTTON4: +/-40 us */
|
||||
{CENTER_VALUE_US(1900,TOLERANCE)}, /* PUSH_BUTTON5: +/-40 us */
|
||||
const KeyMap_t CustomKeyboard[] PROGMEM ={ {CENTER_VALUE_US(1100,TOLERANCE)}, /* PUSH_BUTTON1: +/-40 us */
|
||||
{CENTER_VALUE_US(1300,TOLERANCE)}, /* PUSH_BUTTON2: +/-40 us */
|
||||
{CENTER_VALUE_US(1500,TOLERANCE)}, /* PUSH_BUTTON3: +/-40 us */
|
||||
{CENTER_VALUE_US(1700,TOLERANCE)}, /* PUSH_BUTTON4: +/-40 us */
|
||||
{CENTER_VALUE_US(1900,TOLERANCE)}, /* PUSH_BUTTON5: +/-40 us */
|
||||
};
|
||||
|
||||
//==============================================================================================
|
||||
|
@@ -0,0 +1,307 @@
|
||||
/*
|
||||
This sketch illustrates 2 new features of the <RcSeq> library (since the V2.1 version):
|
||||
1) the "control" capability: it's a function passed as argument to the RcSeq_DeclareCommandAndSequence() method.
|
||||
It is used to check if a sequence can be launched or not, depending of specific condition
|
||||
It is also used to inform the sequence is finished: this can be used to memorize in EEPROM the sequence id.
|
||||
Like that, at the next start-up the position of the servos can be restored according to the last position of the sequence.
|
||||
2) the "timeout" capability:
|
||||
The RcSeq_Timeout() method can be used to check if the command signal remains constant (HIGH or LOW).
|
||||
It's then possible to launch the sequence based on the static state of the command pin rather than a Rc Pulse width.
|
||||
In practice, it's possible to use both manners to launch a sequence as done in the sketch below.
|
||||
|
||||
THE SKETCH:
|
||||
==========
|
||||
In this sketch, the first declared sequence opens the 2 doors with the help of 2 servos (1 per door).
|
||||
The second declared sequence closes the 2 doors with the help of 2 servos (1 per door).
|
||||
The 2 doors cannot open or close simultaneously with the same speed since there is a nosing secured to the right door.
|
||||
This nosing forces to open and close the doors using sequences.
|
||||
|
||||
Opening <- -> Opening
|
||||
. .
|
||||
. .
|
||||
. .
|
||||
. .
|
||||
. .
|
||||
. .
|
||||
. .
|
||||
__ nosing -> .------. __
|
||||
/ \----------------'---. '----------------/ \
|
||||
\__/-------------------''-------------------\__/
|
||||
Left door Right door
|
||||
TOP VIEW
|
||||
|
||||
The opening sequence is like hereafter:
|
||||
======================================
|
||||
1) The servo assigned to the right door starts
|
||||
2) Once rigth door slightly opened, the servo assigned to the left door starts, whilst the servo assigned to the right door resumes its travel
|
||||
3) Once the 2 servos reached 90°, the 2 doors stop; the opening sequence is finished
|
||||
|
||||
The closing sequence is like hereafter:
|
||||
======================================
|
||||
1) The 2 servos assigned to the left and right doors start together but the left servo rotates more quickly than the right servo.
|
||||
2) As a consequence, the left door is closed berfore the right door
|
||||
3) Once the 2 servos reached 90°, the 2 doors stop; the closing sequence is finished
|
||||
|
||||
The sequences of this sketch can be launched either a RC channel either a regular ON/OFF switch:
|
||||
===============================================================================================
|
||||
A) Command from a RC channel:
|
||||
------------------------- _______________
|
||||
V _______________ | __ |
|
||||
| __________ | ARDUINO: |________| / \ Left |
|
||||
| | | | | | \__/ Servo |
|
||||
| | RC |CH | UNO | |_______________|
|
||||
'-+ Receiver |----| MEGA | _______________
|
||||
| | | Digispark | | __ |
|
||||
|__________| | Digispark pro |________| / \ Right |
|
||||
|_______________| | \__/ Servo |
|
||||
|_______________|
|
||||
|
||||
B) Command from a ON/OFF switch:
|
||||
---------------------------- _______________
|
||||
_______________ | __ |
|
||||
| ARDUINO: |________| / \ Left |
|
||||
| | | \__/ Servo |
|
||||
| UNO | |_______________|
|
||||
.----| MEGA | _______________
|
||||
| | Digispark | | __ |
|
||||
ON/OFF Switch \ | Digispark pro |________| / \ Right |
|
||||
| |_______________| | \__/ Servo |
|
||||
-+- |_______________|
|
||||
GND
|
||||
*/
|
||||
|
||||
/*************************************************/
|
||||
/* STEP #1: Include the required libraries */
|
||||
/*************************************************/
|
||||
#include <RcSeq.h>
|
||||
#include <TinyPinChange.h>
|
||||
#include <SoftRcPulseIn.h>
|
||||
#include <SoftRcPulseOut.h>
|
||||
#include <EEPROM.h>
|
||||
|
||||
/*****************************************************************/
|
||||
/* STEP #2: Enumeration of the RC Signals used in the sequence */
|
||||
/*****************************************************************/
|
||||
enum {RC_SIGNAL = 0, SIGNAL_NB}; /* Here, a single RC signal is used */
|
||||
|
||||
/******************************************************************/
|
||||
/* STEP #3: Enumeration of the different position of the RC stick */
|
||||
/******************************************************************/
|
||||
enum {RC_PULSE_LEVEL_MINUS_1 = 0, RC_PULSE_LEVEL_PLUS_1, RC_PULSE_NB};
|
||||
|
||||
/*****************************************************************/
|
||||
/* STEP #4: Enumeration of the servos used in the sequences */
|
||||
/*****************************************************************/
|
||||
enum {DOOR_SERVO_LEFT = 0, DOOR_SERVO_RIGHT, SERVO_NB}; /* In this sketch, 2 servos are declared */
|
||||
|
||||
/***************************************************/
|
||||
/* STEP #5: Digital pin assignment for Command */
|
||||
/***************************************************/
|
||||
#define COMMAND_PIN 2 /* This pin can be connected to a channel of a RC Receiver or to a regular ON/OFF switch (switch wired between pin and Ground) */
|
||||
|
||||
/**************************************************/
|
||||
/* STEP #6: Digital Pins assignment for Servos */
|
||||
/**************************************************/
|
||||
#define DOOR_SERVO_LEFT_PIN 3
|
||||
#define DOOR_SERVO_RIGHT_PIN 4
|
||||
|
||||
/*************************************************************************************/
|
||||
/* STEP #7: Declaration of the angle of the servos for the different motions (in °) */
|
||||
/*************************************************************************************/
|
||||
#define DOOR_SERVO_OPENED_LEFT_POS 135 /* position of the left Servo when left door is opened */
|
||||
#define DOOR_SERVO_CLOSED_LEFT_POS 45 /* position of the left Servo when left door is closed */
|
||||
|
||||
#define DOOR_SERVO_OPENED_RIGHT_POS 45 /* position of the right Servo when right door is opened */
|
||||
#define DOOR_SERVO_CLOSED_RIGHT_POS 135 /* position of the right Servo when right door is closed */
|
||||
|
||||
|
||||
/***************************************************************************************************************************************/
|
||||
/* STEP #8: Do a temporal diagram showing the start up and the duration of each motions of each servo */
|
||||
/***************************************************************************************************************************************/
|
||||
/*
|
||||
1) OPENING MOTION OF THE DOORS
|
||||
===========================
|
||||
All the start up values (time stamp) have as reference the moment of the sequence startup order (t=0).
|
||||
|
||||
1.1 MOTION OF THE LEFT DOOR SERVO FOR OPENING
|
||||
=========================================
|
||||
|
||||
Order <---OPENING_DURATION_LEFT_MS--->
|
||||
|-----------------------------|--------------------------------|-->Time Axis
|
||||
0 OPENING_START_LEFT_MS
|
||||
|
||||
1.2 MOTION OF THE RIGHT DOOR SERVO FOR OPENING
|
||||
==========================================
|
||||
|
||||
Order <--------OPENING_DURATION_RIGHT_MS------->
|
||||
|-------------------|------------------------------------------|-->Time Axis
|
||||
0 OPENING_START_RIGHT_MS
|
||||
|
||||
|
||||
2) CLOSING MOTION OF THE DOORS
|
||||
===========================
|
||||
All the start up values (time stamp) have as reference the moment of the sequence startup order (t=0).
|
||||
|
||||
2.1 MOTION OF THE LEFT DOOR SERVO FOR CLOSING
|
||||
=========================================
|
||||
|
||||
Order <---CLOSING_DURATION_LEFT_MS--->
|
||||
|-------------------|--------------------------------|------------>Time Axis
|
||||
0 CLOSING_START_LEFT_MS
|
||||
|
||||
2.2 MOTION OF THE RIGTH DOOR SERVO FOR CLOSING
|
||||
==========================================
|
||||
|
||||
Order <--------CLOSING_DURATION_RIGHT_MS------->
|
||||
|-------------------|------------------------------------------|-->Time Axis
|
||||
0 CLOSING_START_RIGHT_MS
|
||||
*/
|
||||
|
||||
/**************************************************************************************************************************************************/
|
||||
/* STEP #9: With the help of the temporal diagram, declare start up time, the motion duration of servo and optional delay */
|
||||
/**************************************************************************************************************************************************/
|
||||
/* Tune below all the motion duration. Do not forget to add a trailer 'UL' for each value to force them in Unsigned Long type */
|
||||
#define OPENING_START_LEFT_MS 500UL //This means the left servo motion will be delayed of 500ms AFTER the order
|
||||
#define OPENING_DURATION_LEFT_MS 2500UL //The left door motion ends after 500+2500=3s, as the right door
|
||||
|
||||
#define OPENING_START_RIGHT_MS 0UL //Immediate start
|
||||
#define OPENING_DURATION_RIGHT_MS 3000UL //The right door motion ends after 3s
|
||||
|
||||
#define CLOSING_START_LEFT_MS 0UL //Immediate start
|
||||
#define CLOSING_DURATION_LEFT_MS 3000UL //The left door will be closed BEFORE the right door
|
||||
|
||||
#define CLOSING_START_RIGHT_MS 0UL //Immediate start
|
||||
#define CLOSING_DURATION_RIGHT_MS 4000UL //The right door will be closed AFTER the left door
|
||||
|
||||
/********************************************************************************************************************/
|
||||
/* STEP #10: Declare here the percentage of motion to be performed at half speed for servo start up and stop */
|
||||
/********************************************************************************************************************/
|
||||
#define START_STOP_PER_CENT 5 /* Percentage of motion performed at half-speed for starting and stopping the servos (Soft start et Soft stop) */
|
||||
|
||||
/************************************************************************************************************/
|
||||
/* STEP #11: Use a "const SequenceSt_t" structure table to declare the servo sequence */
|
||||
/* For each table entry, arguments are: */
|
||||
/* - Servo Index */
|
||||
/* - Initial Servo Position in ° */
|
||||
/* - Final Servo Position in ° */
|
||||
/* - Motion Start Time Stamp in ms */
|
||||
/* - Motion duration in ms between initial and final position */
|
||||
/* - Percentage of motion performed at half speed for servo start and servo stop (Soft start and Soft stop) */
|
||||
/************************************************************************************************************/
|
||||
/* Table describing the motions of the 2 servos for opening the 2 doors */
|
||||
const SequenceSt_t OpeningSequence[] PROGMEM = {/* Servo Id , Initial Angle , Final Angle , Delay after order , Motion Duration , Percentage at half speed */
|
||||
/* 1st Servo */ MOTION_WITH_SOFT_START_AND_STOP(DOOR_SERVO_LEFT, DOOR_SERVO_CLOSED_LEFT_POS, DOOR_SERVO_OPENED_LEFT_POS, OPENING_START_LEFT_MS, OPENING_DURATION_LEFT_MS, START_STOP_PER_CENT)
|
||||
/* 2nd Servo */ MOTION_WITH_SOFT_START_AND_STOP(DOOR_SERVO_RIGHT, DOOR_SERVO_CLOSED_RIGHT_POS, DOOR_SERVO_OPENED_RIGHT_POS, OPENING_START_RIGHT_MS, OPENING_DURATION_RIGHT_MS, START_STOP_PER_CENT)
|
||||
};
|
||||
|
||||
/* Table describing the motions of the 2 servos for closing the 2 doors */
|
||||
const SequenceSt_t ClosingSequence[] PROGMEM = {/* Servo Id , Initial Angle , Final Angle , Delai after order , Motion Duration , Percentage at half speed */
|
||||
/* 1st Servo */ MOTION_WITH_SOFT_START_AND_STOP(DOOR_SERVO_LEFT, DOOR_SERVO_OPENED_LEFT_POS, DOOR_SERVO_CLOSED_LEFT_POS, CLOSING_START_LEFT_MS, CLOSING_DURATION_LEFT_MS, START_STOP_PER_CENT)
|
||||
/* 2nd Servo */ MOTION_WITH_SOFT_START_AND_STOP(DOOR_SERVO_RIGHT, DOOR_SERVO_OPENED_RIGHT_POS, DOOR_SERVO_CLOSED_RIGHT_POS, CLOSING_START_RIGHT_MS, CLOSING_DURATION_RIGHT_MS, START_STOP_PER_CENT)
|
||||
};
|
||||
|
||||
enum {COMMAND_OPEN = 0, COMMAND_CLOSE};
|
||||
|
||||
/* GLOBAL VARIABLES */
|
||||
uint8_t LastExecutedSeqIdx;
|
||||
|
||||
void setup()
|
||||
{
|
||||
|
||||
#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(F("RcSeq library V"));Serial.print(RcSeq_LibTextVersionRevision());Serial.println(F(" demo: advanced doors sequences"));
|
||||
#endif
|
||||
|
||||
/***************************************************************************/
|
||||
/* STEP #12: Init <RcSeq> library */
|
||||
/***************************************************************************/
|
||||
RcSeq_Init();
|
||||
|
||||
/****************************************************************************************/
|
||||
/* STEP #13: declare the servo command signals with their digital pin number */
|
||||
/****************************************************************************************/
|
||||
RcSeq_DeclareSignal(RC_SIGNAL, COMMAND_PIN);
|
||||
|
||||
/******************************************************************************************/
|
||||
/* STEP #14: declare a stick assigned to the RC signal having RC_PULSE_NB positions */
|
||||
/******************************************************************************************/
|
||||
RcSeq_DeclareStick(RC_SIGNAL, 1000, 2000, RC_PULSE_NB);
|
||||
|
||||
/****************************************************************************************/
|
||||
/* STEP #15: declare the servo command signals with their digital pin number */
|
||||
/****************************************************************************************/
|
||||
RcSeq_DeclareServo(DOOR_SERVO_LEFT, DOOR_SERVO_LEFT_PIN);
|
||||
RcSeq_DeclareServo(DOOR_SERVO_RIGHT, DOOR_SERVO_RIGHT_PIN);
|
||||
|
||||
/*******************************************************************************************************/
|
||||
/* STEP #16: declare the sequence assigned to specific position of the stick assigned to the RC signal */
|
||||
/*******************************************************************************************************/
|
||||
RcSeq_DeclareCommandAndSequence(RC_SIGNAL, RC_PULSE_LEVEL_MINUS_1, RC_SEQUENCE(OpeningSequence), Control); // Declare a sequence triggered by a RC pulse Level Minus 1 (stick at extreme position during at least 250 ms)
|
||||
RcSeq_DeclareCommandAndSequence(RC_SIGNAL, RC_PULSE_LEVEL_PLUS_1, RC_SEQUENCE(ClosingSequence), Control); // Declare a sequence triggered by a RC pulse Level Plus 1 (stick at extreme position during at least 250 ms)
|
||||
|
||||
/*******************************************************************************************/
|
||||
/* STEP #17: Initialize the position of the servos according to the last finished sequence */
|
||||
/*******************************************************************************************/
|
||||
LastExecutedSeqIdx = EEPROM.read(0);
|
||||
if (LastExecutedSeqIdx == COMMAND_OPEN)
|
||||
{
|
||||
RcSeq_ServoWrite(DOOR_SERVO_LEFT, DOOR_SERVO_OPENED_LEFT_POS);
|
||||
RcSeq_ServoWrite(DOOR_SERVO_RIGHT, DOOR_SERVO_OPENED_RIGHT_POS);
|
||||
}
|
||||
else
|
||||
{
|
||||
RcSeq_ServoWrite(DOOR_SERVO_LEFT, DOOR_SERVO_CLOSED_LEFT_POS);
|
||||
RcSeq_ServoWrite(DOOR_SERVO_RIGHT, DOOR_SERVO_CLOSED_RIGHT_POS);
|
||||
}
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
uint8_t RcSignalPinState;
|
||||
/****************************************************************************************************************/
|
||||
/* STEP #18: call the refresh function inside the loop() to catch RC commands and to manage the servo positions */
|
||||
/****************************************************************************************************************/
|
||||
RcSeq_Refresh();
|
||||
|
||||
/*********************************************************************************************************/
|
||||
/* STEP #19: optionally, allow launching the Sequences ou Actions on Timeout (cmd with a regular switch) */
|
||||
/*********************************************************************************************************/
|
||||
if (RcSeq_SignalTimeout(RC_SIGNAL, 250, &RcSignalPinState))
|
||||
{
|
||||
/* Launch the"OpeningSequence" sequence if a LOW level is present during at least 250ms: this allows testing the sequence of servo without using a RC set, just using a regular switch */
|
||||
if((LastExecutedSeqIdx == COMMAND_CLOSE) && (RcSignalPinState == LOW))
|
||||
{
|
||||
RcSeq_LaunchSequence(OpeningSequence);
|
||||
}
|
||||
/* Launch the"ClosingSequence" sequence if a HIGH level is present during at least 250ms: this allows testing the sequence of servo without using a RC set, just using a regular switch */
|
||||
if((LastExecutedSeqIdx == COMMAND_OPEN) && (RcSignalPinState == HIGH))
|
||||
{
|
||||
RcSeq_LaunchSequence(ClosingSequence);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* The Control() fonction is automatically called by the RcSeq library */
|
||||
uint8_t Control(uint8_t Action, uint8_t SeqIdx)
|
||||
{
|
||||
uint8_t Ret = 0;
|
||||
#if !defined(__AVR_ATtiny24__) && !defined(__AVR_ATtiny44__) && !defined(__AVR_ATtiny84__) && !defined(__AVR_ATtiny25__) && !defined(__AVR_ATtiny45__) && !defined(__AVR_ATtiny85__) && !defined(__AVR_ATtiny167__)
|
||||
Serial.print("Action=");Serial.print(Action);Serial.print(" SeqIdx=");Serial.println(SeqIdx);
|
||||
#endif
|
||||
switch(Action)
|
||||
{
|
||||
case RC_SEQ_START_CONDITION: /* RcSeq asks if the conditions are met to launch the sequence SeqIdx */
|
||||
/* Put here a condition to allow RcSeq launching the sequence SeqIdx (Put Ret=1 if no specific condition) */
|
||||
Ret = (SeqIdx != LastExecutedSeqIdx); /* Allows RcSeq launching the sequence if the sequence to launch is different from the last one */
|
||||
break;
|
||||
|
||||
case RC_SEQ_END_OF_SEQ: /* RcSeq informs the sequence SeqIdx is finished */
|
||||
/* We memorize the last finished sequence id in EEPROM memory. Like that, at next power-up, we will know how to position the servos ( done in the Setup() ) */
|
||||
EEPROM.write(0, SeqIdx);
|
||||
LastExecutedSeqIdx = SeqIdx;
|
||||
break;
|
||||
}
|
||||
return(Ret);
|
||||
}
|
||||
|
@@ -1,7 +1,7 @@
|
||||
#include <RcSeq.h>
|
||||
#include <TinyPinChange.h> /* Ne pas oublier d'inclure la librairie <TinyPinChange> qui est utilisee par la librairie <RcSeq> */
|
||||
#include <SoftRcPulseIn.h> /* Ne pas oublier d'inclure la librairie <SoftRcPulseIn> qui est utilisee par la librairie <RcSeq> */
|
||||
#include <SoftRcPulseOut.h> /* Ne pas oublier d'inclure la librairie <SoftRcPulseOut> qui est utilisee par la librairie <RcSeq> */
|
||||
#include <TinyPinChange.h>
|
||||
#include <SoftRcPulseIn.h>
|
||||
#include <SoftRcPulseOut.h>
|
||||
|
||||
/*
|
||||
IMPORTANT:
|
||||
@@ -25,16 +25,16 @@ enum {RC_VOIE1, RC_VOIE2, RC_VOIE3, NBR_VOIES_RC}; /* Declaration des voies */
|
||||
|
||||
enum {BP1, BP2, NBR_BP}; /* Declaration des Boutons-Poussoirs (On peut aller jusqu'à BP8) */
|
||||
|
||||
enum {POS_MINUS1, POS_PLUS1,NBR_POS}; /* Declaration des positions du Manche on peut aller de POS_MOINS2 à POS_PLUS2 (4 Positions actives Max)*/
|
||||
enum {POS_MINUS1, POS_PLUS1, NBR_POS}; /* Declaration des positions du Manche on peut aller de POS_MOINS2 à POS_PLUS2 (4 Positions actives Max)*/
|
||||
|
||||
|
||||
/* Declaration d'un clavier "Maison": les impulsions des Boutons-Poussoirs n'ont pas besoin d'etre equidistantes */
|
||||
enum {BP_MAISON1, BP_MAISON2, BP_MAISON3, NBR_BP_MAISON};
|
||||
#define TOLERANCE 40 /* Tolerance en + ou en - (en micro-seconde) */
|
||||
KeyMap_t ClavierMaison[] PROGMEM ={ {VALEUR_CENTRALE_US(1100,TOLERANCE)}, /* BP_MAISON1: 1100 +/-40 us */
|
||||
{VALEUR_CENTRALE_US(1300,TOLERANCE)}, /* BP_MAISON2: 1300 +/-40 us */
|
||||
{VALEUR_CENTRALE_US(1700,TOLERANCE)}, /* BP_MAISON3: 1700 +/-40 us */
|
||||
};
|
||||
const KeyMap_t ClavierMaison[] PROGMEM ={ {VALEUR_CENTRALE_US(1100, TOLERANCE)}, /* BP_MAISON1: 1100 +/-40 us */
|
||||
{VALEUR_CENTRALE_US(1300, TOLERANCE)}, /* BP_MAISON2: 1300 +/-40 us */
|
||||
{VALEUR_CENTRALE_US(1700, TOLERANCE)}, /* BP_MAISON3: 1700 +/-40 us */
|
||||
};
|
||||
|
||||
enum {AZIMUT=0, ELEVATION , NBR_SERVO}; /* Delaration de tous les servos, 2 dans cet exemple (On peut déclaer jusqu'à 8 servos) */
|
||||
|
||||
@@ -80,23 +80,23 @@ enum {AZIMUT=0, ELEVATION , NBR_SERVO}; /* Delaration de tous les servos, 2 dans
|
||||
#define DEM_ARRET_POUR_CENT 5 /* Pourcentage du mouvement devant etre effectue a mi-vitesse pour demarrage servo et arret servo (Soft start et Soft stop) */
|
||||
|
||||
/* Declaration de la table de sequence des mouvements des servo et des actions courtes */
|
||||
SequenceSt_t SequenceServoEtActionCourte[] PROGMEM = {
|
||||
ACTION_COURTE_A_EFFECTUER(InverseLed,DEMARRAGE_MONTEE_PONT_HAUT_MS)
|
||||
const SequenceSt_t SequenceServoEtActionCourte[] PROGMEM = {
|
||||
ACTION_COURTE_A_EFFECTUER(InverseLed, DEMARRAGE_MONTEE_PONT_HAUT_MS)
|
||||
/* Montee du Zodiac du pont vers la position haute */
|
||||
MVT_AVEC_DEBUT_ET_FIN_MVT_LENTS(ELEVATION,ELEVATION_POS_PONT,ELEVATION_POS_HAUT,DEMARRAGE_MONTEE_PONT_HAUT_MS,DUREE_MONTEE_PONT_HAUT_MS,DEM_ARRET_POUR_CENT)
|
||||
MVT_AVEC_DEBUT_ET_FIN_MVT_LENTS(ELEVATION, ELEVATION_POS_PONT, ELEVATION_POS_HAUT, DEMARRAGE_MONTEE_PONT_HAUT_MS, DUREE_MONTEE_PONT_HAUT_MS, DEM_ARRET_POUR_CENT)
|
||||
/* Rotation Grue du pont vers la mer */
|
||||
MVT_AVEC_DEBUT_ET_FIN_MVT_LENTS(AZIMUT,AZIMUT_POS_PONT,AZIMUT_POS_MER,DEMARRAGE_ROTATION_PONT_MER_MS,DUREE_ROTATION_PONT_MER_MS,DEM_ARRET_POUR_CENT)
|
||||
MVT_AVEC_DEBUT_ET_FIN_MVT_LENTS(AZIMUT, AZIMUT_POS_PONT, AZIMUT_POS_MER, DEMARRAGE_ROTATION_PONT_MER_MS, DUREE_ROTATION_PONT_MER_MS, DEM_ARRET_POUR_CENT)
|
||||
/* Descente du Zodiac depuis la position haute vers la la mer */
|
||||
MVT_AVEC_DEBUT_ET_FIN_MVT_LENTS(ELEVATION,ELEVATION_POS_HAUT,ELEVATION_POS_MER,DEMARRAGE_DESCENTE_HAUT_MER_MS,DUREE_DESCENTE_HAUT_MER_MS,DEM_ARRET_POUR_CENT)
|
||||
ACTION_COURTE_A_EFFECTUER(InverseLed,DEMARRAGE_DESCENTE_HAUT_MER_MS+DUREE_DESCENTE_HAUT_MER_MS)
|
||||
ACTION_COURTE_A_EFFECTUER(InverseLed,DEMARRAGE_MONTEE_MER_HAUT_MS)
|
||||
MVT_AVEC_DEBUT_ET_FIN_MVT_LENTS(ELEVATION, ELEVATION_POS_HAUT, ELEVATION_POS_MER, DEMARRAGE_DESCENTE_HAUT_MER_MS, DUREE_DESCENTE_HAUT_MER_MS, DEM_ARRET_POUR_CENT)
|
||||
ACTION_COURTE_A_EFFECTUER(InverseLed, DEMARRAGE_DESCENTE_HAUT_MER_MS + DUREE_DESCENTE_HAUT_MER_MS)
|
||||
ACTION_COURTE_A_EFFECTUER(InverseLed, DEMARRAGE_MONTEE_MER_HAUT_MS)
|
||||
/* Montee du Zodiac de la mer vers la position haute */
|
||||
MVT_AVEC_DEBUT_ET_FIN_MVT_LENTS(ELEVATION,ELEVATION_POS_MER,ELEVATION_POS_HAUT,DEMARRAGE_MONTEE_MER_HAUT_MS,DUREE_MONTEE_MER_HAUT_MS,DEM_ARRET_POUR_CENT)
|
||||
MVT_AVEC_DEBUT_ET_FIN_MVT_LENTS(ELEVATION, ELEVATION_POS_MER, ELEVATION_POS_HAUT, DEMARRAGE_MONTEE_MER_HAUT_MS, DUREE_MONTEE_MER_HAUT_MS, DEM_ARRET_POUR_CENT)
|
||||
/* Rotation Grue de la mer vers le pont */
|
||||
MVT_AVEC_DEBUT_ET_FIN_MVT_LENTS(AZIMUT,AZIMUT_POS_MER,AZIMUT_POS_PONT,DEMARRAGE_ROTATION_MER_PONT_MS,DUREE_ROTATION_MER_PONT_MS,DEM_ARRET_POUR_CENT)
|
||||
MVT_AVEC_DEBUT_ET_FIN_MVT_LENTS(AZIMUT, AZIMUT_POS_MER, AZIMUT_POS_PONT, DEMARRAGE_ROTATION_MER_PONT_MS, DUREE_ROTATION_MER_PONT_MS, DEM_ARRET_POUR_CENT)
|
||||
/* Descente du Zodiac de la position haute vers le pont */
|
||||
MVT_AVEC_DEBUT_ET_FIN_MVT_LENTS(ELEVATION,ELEVATION_POS_HAUT,ELEVATION_POS_PONT,DEMARRAGE_DESCENTE_HAUT_PONT_MS,DUREE_DESCENTE_HAUT_PONT_MS,DEM_ARRET_POUR_CENT)
|
||||
ACTION_COURTE_A_EFFECTUER(InverseLed,DEMARRAGE_DESCENTE_HAUT_PONT_MS+DUREE_DESCENTE_HAUT_PONT_MS)
|
||||
MVT_AVEC_DEBUT_ET_FIN_MVT_LENTS(ELEVATION, ELEVATION_POS_HAUT, ELEVATION_POS_PONT, DEMARRAGE_DESCENTE_HAUT_PONT_MS, DUREE_DESCENTE_HAUT_PONT_MS, DEM_ARRET_POUR_CENT)
|
||||
ACTION_COURTE_A_EFFECTUER(InverseLed, DEMARRAGE_DESCENTE_HAUT_PONT_MS + DUREE_DESCENTE_HAUT_PONT_MS)
|
||||
};
|
||||
|
||||
#define LED 13
|
||||
@@ -114,22 +114,22 @@ void setup()
|
||||
RcSeq_DeclareServo(AZIMUT, BROCHE_SIGNAL_SERVO_AZ);
|
||||
|
||||
/* Commande d'une action courte et d'une sequence de servos avec 2 BP du clavier de la VOIE1 */
|
||||
RcSeq_DeclareSignal(RC_VOIE1,BROCHE_SIGNAL_RECEPTEUR_VOIE1);
|
||||
RcSeq_DeclareSignal(RC_VOIE1, BROCHE_SIGNAL_RECEPTEUR_VOIE1);
|
||||
RcSeq_DeclareClavier(RC_VOIE1, 1000, 2000, NBR_BP);
|
||||
RcSeq_DeclareCommandeEtActionCourte(RC_VOIE1, BP1, InverseLed);
|
||||
RcSeq_DeclareCommandeEtSequence(RC_VOIE1, BP2, RC_SEQUENCE(SequenceServoEtActionCourte));
|
||||
RcSeq_DeclareCommandeEtSequence(RC_VOIE1, BP2, RC_SEQUENCE(SequenceServoEtActionCourte), NULL);
|
||||
|
||||
/* Commande d'une action courte et d'une sequence de servos avec le manche de la VOIE2 */
|
||||
RcSeq_DeclareSignal(RC_VOIE2,BROCHE_SIGNAL_RECEPTEUR_VOIE2);
|
||||
RcSeq_DeclareSignal(RC_VOIE2, BROCHE_SIGNAL_RECEPTEUR_VOIE2);
|
||||
RcSeq_DeclareManche(RC_VOIE2, 1000, 2000, NBR_POS);
|
||||
RcSeq_DeclareCommandeEtActionCourte(RC_VOIE2, POS_MINUS1, InverseLed);
|
||||
RcSeq_DeclareCommandeEtSequence(RC_VOIE2, POS_PLUS1, RC_SEQUENCE(SequenceServoEtActionCourte));
|
||||
RcSeq_DeclareCommandeEtSequence(RC_VOIE2, POS_PLUS1, RC_SEQUENCE(SequenceServoEtActionCourte), NULL);
|
||||
|
||||
/* Commande d'une action courte et d'une sequence de servos avec le clavier "maison" de la VOIE3 */
|
||||
RcSeq_DeclareSignal(RC_VOIE3,BROCHE_SIGNAL_RECEPTEUR_VOIE3);
|
||||
RcSeq_DeclareSignal(RC_VOIE3, BROCHE_SIGNAL_RECEPTEUR_VOIE3);
|
||||
RcSeq_DeclareClavierMaison(RC_VOIE3, RC_CLAVIER_MAISON(ClavierMaison));
|
||||
RcSeq_DeclareCommandeEtActionCourte(RC_VOIE3, BP_MAISON1, InverseLed);
|
||||
RcSeq_DeclareCommandeEtSequence(RC_VOIE3, BP_MAISON3, RC_SEQUENCE(SequenceServoEtActionCourte));
|
||||
RcSeq_DeclareCommandeEtSequence(RC_VOIE3, BP_MAISON3, RC_SEQUENCE(SequenceServoEtActionCourte), NULL);
|
||||
|
||||
pinMode(LED, OUTPUT);
|
||||
}
|
||||
@@ -142,13 +142,13 @@ void loop()
|
||||
/* Action associee au BP1 de la VOIE1 ou au manche position basse de la VOIE2 ou au BP_MAISON1 de la VOIE3 */
|
||||
void InverseLed(void)
|
||||
{
|
||||
static uint32_t DebutMs=millis(); /* static, pour conserver l'etat entre 2 appels de la fonction */
|
||||
static boolean Etat=HIGH; /* static, pour conserver l'etat entre 2 appels de la fonction */
|
||||
static uint32_t DebutMs = millis(); /* static, pour conserver l'etat entre 2 appels de la fonction */
|
||||
static boolean Etat = HIGH; /* static, pour conserver l'etat entre 2 appels de la fonction */
|
||||
|
||||
if(millis() - DebutMs >= 500UL) /* Depuis RcSeq V2.0, la tempo inter-commande doit etre geree dans le sketch utilisateur */
|
||||
{
|
||||
DebutMs=millis();
|
||||
DebutMs = millis();
|
||||
digitalWrite(LED, Etat);
|
||||
Etat=!Etat; /* Au prochain appel de InverseLed(), l'etat de la LED sera inverse */
|
||||
Etat = !Etat; /* Au prochain appel de InverseLed(), l'etat de la LED sera inverse */
|
||||
}
|
||||
}
|
||||
|
@@ -32,9 +32,9 @@ Cette sequence utilise:
|
||||
/* ETAPE N°1: Inclure les 4 librairies necessaires */
|
||||
/***************************************************/
|
||||
#include <RcSeq.h>
|
||||
#include <TinyPinChange.h> /* Ne pas oublier d'inclure la librairie <TinyPinChange> qui est utilisee par la librairie <RcSeq> */
|
||||
#include <SoftRcPulseIn.h> /* Ne pas oublier d'inclure la librairie <SoftRcPulseIn> qui est utilisee par la librairie <RcSeq> */
|
||||
#include <SoftRcPulseOut.h> /* Ne pas oublier d'inclure la librairie <SoftRcPulseOut> qui est utilisee par la librairie <RcSeq> */
|
||||
#include <TinyPinChange.h>
|
||||
#include <SoftRcPulseIn.h>
|
||||
#include <SoftRcPulseOut.h>
|
||||
|
||||
/*****************************************************/
|
||||
/* ETAPE N°2: Enumeration des signaux de commande RC */
|
||||
@@ -121,23 +121,23 @@ Ordre <---DUREE_MONTEE_PONT_HAUT_MS--> <--DUREE_ROTATION_PONT_M
|
||||
/* Il est possible d'inclure des actions courtes. Il suffit d'utiliser la macro ACTION_COURTE_A_EFFECTUER() en donnant le nom de la fonction a appeler et le */
|
||||
/* moment ou l'action doit avoir lieu. Dans cet exemple, la LED s'allume pendant que les servos tournent et s'eteint pendant la pause de 6 secondes. */
|
||||
/***************************************************************************************************************************************************************/
|
||||
SequenceSt_t SequencePlus2[] PROGMEM = {
|
||||
ACTION_COURTE_A_EFFECTUER(InverseLed,DEMARRAGE_MONTEE_PONT_HAUT_MS)
|
||||
const SequenceSt_t SequencePlus2[] PROGMEM = {
|
||||
ACTION_COURTE_A_EFFECTUER(InverseLed, DEMARRAGE_MONTEE_PONT_HAUT_MS)
|
||||
/* Montee du Zodiac du pont vers la position haute */
|
||||
MVT_AVEC_DEBUT_ET_FIN_MVT_LENTS(ELEVATION,ELEVATION_POS_PONT,ELEVATION_POS_HAUT,DEMARRAGE_MONTEE_PONT_HAUT_MS,DUREE_MONTEE_PONT_HAUT_MS,DEM_ARRET_POUR_CENT)
|
||||
MVT_AVEC_DEBUT_ET_FIN_MVT_LENTS(ELEVATION, ELEVATION_POS_PONT, ELEVATION_POS_HAUT, DEMARRAGE_MONTEE_PONT_HAUT_MS, DUREE_MONTEE_PONT_HAUT_MS, DEM_ARRET_POUR_CENT)
|
||||
/* Rotation Grue du pont vers la mer */
|
||||
MVT_AVEC_DEBUT_ET_FIN_MVT_LENTS(AZIMUT,AZIMUT_POS_PONT,AZIMUT_POS_MER,DEMARRAGE_ROTATION_PONT_MER_MS,DUREE_ROTATION_PONT_MER_MS,DEM_ARRET_POUR_CENT)
|
||||
MVT_AVEC_DEBUT_ET_FIN_MVT_LENTS(AZIMUT, AZIMUT_POS_PONT, AZIMUT_POS_MER, DEMARRAGE_ROTATION_PONT_MER_MS, DUREE_ROTATION_PONT_MER_MS, DEM_ARRET_POUR_CENT)
|
||||
/* Descente du Zodiac depuis la position haute vers la la mer */
|
||||
MVT_AVEC_DEBUT_ET_FIN_MVT_LENTS(ELEVATION,ELEVATION_POS_HAUT,ELEVATION_POS_MER,DEMARRAGE_DESCENTE_HAUT_MER_MS,DUREE_DESCENTE_HAUT_MER_MS,DEM_ARRET_POUR_CENT)
|
||||
ACTION_COURTE_A_EFFECTUER(InverseLed,DEMARRAGE_DESCENTE_HAUT_MER_MS+DUREE_DESCENTE_HAUT_MER_MS)
|
||||
ACTION_COURTE_A_EFFECTUER(InverseLed,DEMARRAGE_MONTEE_MER_HAUT_MS)
|
||||
MVT_AVEC_DEBUT_ET_FIN_MVT_LENTS(ELEVATION, ELEVATION_POS_HAUT, ELEVATION_POS_MER, DEMARRAGE_DESCENTE_HAUT_MER_MS, DUREE_DESCENTE_HAUT_MER_MS, DEM_ARRET_POUR_CENT)
|
||||
ACTION_COURTE_A_EFFECTUER(InverseLed, DEMARRAGE_DESCENTE_HAUT_MER_MS + DUREE_DESCENTE_HAUT_MER_MS)
|
||||
ACTION_COURTE_A_EFFECTUER(InverseLed, DEMARRAGE_MONTEE_MER_HAUT_MS)
|
||||
/* Montee du Zodiac de la mer vers la position haute */
|
||||
MVT_AVEC_DEBUT_ET_FIN_MVT_LENTS(ELEVATION,ELEVATION_POS_MER,ELEVATION_POS_HAUT,DEMARRAGE_MONTEE_MER_HAUT_MS,DUREE_MONTEE_MER_HAUT_MS,DEM_ARRET_POUR_CENT)
|
||||
MVT_AVEC_DEBUT_ET_FIN_MVT_LENTS(ELEVATION, ELEVATION_POS_MER, ELEVATION_POS_HAUT, DEMARRAGE_MONTEE_MER_HAUT_MS, DUREE_MONTEE_MER_HAUT_MS, DEM_ARRET_POUR_CENT)
|
||||
/* Rotation Grue de la mer vers le pont */
|
||||
MVT_AVEC_DEBUT_ET_FIN_MVT_LENTS(AZIMUT,AZIMUT_POS_MER,AZIMUT_POS_PONT,DEMARRAGE_ROTATION_MER_PONT_MS,DUREE_ROTATION_MER_PONT_MS,DEM_ARRET_POUR_CENT)
|
||||
MVT_AVEC_DEBUT_ET_FIN_MVT_LENTS(AZIMUT, AZIMUT_POS_MER, AZIMUT_POS_PONT, DEMARRAGE_ROTATION_MER_PONT_MS, DUREE_ROTATION_MER_PONT_MS, DEM_ARRET_POUR_CENT)
|
||||
/* Descente du Zodiac de la position haute vers le pont */
|
||||
MVT_AVEC_DEBUT_ET_FIN_MVT_LENTS(ELEVATION,ELEVATION_POS_HAUT,ELEVATION_POS_PONT,DEMARRAGE_DESCENTE_HAUT_PONT_MS,DUREE_DESCENTE_HAUT_PONT_MS,DEM_ARRET_POUR_CENT)
|
||||
ACTION_COURTE_A_EFFECTUER(InverseLed,DEMARRAGE_DESCENTE_HAUT_PONT_MS+DUREE_DESCENTE_HAUT_PONT_MS)
|
||||
MVT_AVEC_DEBUT_ET_FIN_MVT_LENTS(ELEVATION, ELEVATION_POS_HAUT, ELEVATION_POS_PONT, DEMARRAGE_DESCENTE_HAUT_PONT_MS, DUREE_DESCENTE_HAUT_PONT_MS, DEM_ARRET_POUR_CENT)
|
||||
ACTION_COURTE_A_EFFECTUER(InverseLed, DEMARRAGE_DESCENTE_HAUT_PONT_MS + DUREE_DESCENTE_HAUT_PONT_MS)
|
||||
};
|
||||
|
||||
#define LED 13
|
||||
@@ -158,7 +158,7 @@ void setup()
|
||||
/**************************************************************************************/
|
||||
/* ETAPE N°13: declarer le(s) signal(aux) de commande RC avec leur N° de pin digitale */
|
||||
/**************************************************************************************/
|
||||
RcSeq_DeclareSignal(SIGNAL_RC,BROCHE_SIGNAL_RECEPTEUR);
|
||||
RcSeq_DeclareSignal(SIGNAL_RC, BROCHE_SIGNAL_RECEPTEUR);
|
||||
|
||||
/******************************************************************************************/
|
||||
/* ETAPE N°14: que le signal RC est associe a un manche qui a NBR_RC_IMPULSIONS positions */
|
||||
@@ -174,7 +174,7 @@ void setup()
|
||||
/**************************************************************************************************************************/
|
||||
/* ETAPE N°16: declarer le signal de commande de sequence, le niveau du manche, et la sequence ou action courte a appeler */
|
||||
/**************************************************************************************************************************/
|
||||
RcSeq_DeclareCommandeEtSequence(SIGNAL_RC, RC_IMPULSION_NIVEAU_PLUS_2, RC_SEQUENCE(SequencePlus2)); // Voici comment declarer une sequence actionnee par une impulsion Niveau Plus 2 (manche en position extreme pendant au moins 250 ms)
|
||||
RcSeq_DeclareCommandeEtSequence(SIGNAL_RC, RC_IMPULSION_NIVEAU_PLUS_2, RC_SEQUENCE(SequencePlus2), NULL); // Voici comment declarer une sequence actionnee par une impulsion Niveau Plus 2 (manche en position extreme pendant au moins 250 ms)
|
||||
|
||||
pinMode(LED, OUTPUT);
|
||||
RcSeq_DeclareCommandeEtActionCourte(SIGNAL_RC, RC_IMPULSION_NIVEAU_MOINS_1, InverseLed); // Voici comment declarer une action actionnee par une impulsion Niveau Moins 1 (manche en position mi-course pendant au moins 250 ms)
|
||||
|
@@ -30,31 +30,31 @@ enum {RC_VOIE, NBR_VOIES_RC}; /* Ici, comme il n'y a qu'une voie, on aurait pu f
|
||||
/* Declaration d'un clavier "Maison": les impulsions des Boutons-Poussoirs n'ont pas besoin d'etre equidistantes */
|
||||
enum {BP1, BP2, BP3, BP4, BP5, BP6, BP7, BP8, NBR_BP};
|
||||
#define TOLERANCE 40 /* Tolerance en + ou en - (en micro-seconde): ATTENTION, il ne doit pas y avoir recouvrement entre 2 zones actives adjascentes. Zone active = 2 x TOLERANCE (us) */
|
||||
KeyMap_t ClavierMaison[] PROGMEM ={ {VALEUR_CENTRALE_US(1100,TOLERANCE)}, /* BP1: +/-40 us */
|
||||
{VALEUR_CENTRALE_US(1200,TOLERANCE)}, /* BP2: +/-40 us */
|
||||
{VALEUR_CENTRALE_US(1300,TOLERANCE)}, /* BP3: +/-40 us */
|
||||
{VALEUR_CENTRALE_US(1400,TOLERANCE)}, /* BP4: +/-40 us */
|
||||
{VALEUR_CENTRALE_US(1600,TOLERANCE)}, /* BP5: +/-40 us */
|
||||
{VALEUR_CENTRALE_US(1700,TOLERANCE)}, /* BP6: +/-40 us */
|
||||
{VALEUR_CENTRALE_US(1800,TOLERANCE)}, /* BP7: +/-40 us */
|
||||
{VALEUR_CENTRALE_US(1900,TOLERANCE)}, /* BP8: +/-40 us */
|
||||
};
|
||||
const KeyMap_t ClavierMaison[] PROGMEM ={ {VALEUR_CENTRALE_US(1100,TOLERANCE)}, /* BP1: +/-40 us */
|
||||
{VALEUR_CENTRALE_US(1200,TOLERANCE)}, /* BP2: +/-40 us */
|
||||
{VALEUR_CENTRALE_US(1300,TOLERANCE)}, /* BP3: +/-40 us */
|
||||
{VALEUR_CENTRALE_US(1400,TOLERANCE)}, /* BP4: +/-40 us */
|
||||
{VALEUR_CENTRALE_US(1600,TOLERANCE)}, /* BP5: +/-40 us */
|
||||
{VALEUR_CENTRALE_US(1700,TOLERANCE)}, /* BP6: +/-40 us */
|
||||
{VALEUR_CENTRALE_US(1800,TOLERANCE)}, /* BP7: +/-40 us */
|
||||
{VALEUR_CENTRALE_US(1900,TOLERANCE)}, /* BP8: +/-40 us */
|
||||
};
|
||||
|
||||
//==============================================================================================
|
||||
/* Astuce: une macro pour n'ecrire qu'une seule fois la fonction ActionX() */
|
||||
#define DECLARE_ACTION(Idx) \
|
||||
void Action##Idx(void) \
|
||||
{ \
|
||||
static uint32_t DebutMs=millis(); \
|
||||
static boolean Etat=HIGH; \
|
||||
static uint32_t DebutMs = millis(); \
|
||||
static boolean Etat = HIGH; \
|
||||
/* Depuis la version 2.0 de la lib <RcSeq>, pour */ \
|
||||
/* des raisons de reactivite, la tempo inter-commande */ \
|
||||
/* doit etre geree dans le sketch utilisateur. */ \
|
||||
if(millis() - DebutMs >= 500UL) \
|
||||
{ \
|
||||
DebutMs=millis(); \
|
||||
DebutMs = millis(); \
|
||||
digitalWrite(Idx, Etat); \
|
||||
Etat=!Etat; \
|
||||
Etat = !Etat; \
|
||||
} \
|
||||
}
|
||||
|
||||
|
@@ -1,6 +1,6 @@
|
||||
#include "RcSeq.h"
|
||||
/*
|
||||
English: by RC Navy (2012/2013)
|
||||
English: by RC Navy (2012-2015)
|
||||
=======
|
||||
<RcSeq> is an asynchronous library for ATmega328P (UNO), ATtiny84 and ATtiny85 to easily create servo's sequences and/or to execute short actions from RC commands.
|
||||
It can also be used to trig some short "actions" (the duration must be less than 20ms to not disturb the servo commands)
|
||||
@@ -21,7 +21,7 @@
|
||||
CAUTION: the end user shall also use asynchronous programmation method in the loop() function (no blocking functions such as delay() or pulseIn()).
|
||||
http://p.loussouarn.free.fr
|
||||
|
||||
Francais: par RC Navy (2012/2013)
|
||||
Francais: par RC Navy (2012-2015)
|
||||
========
|
||||
<RcSeq> est une librairie asynchrone pour ATmega328P (UNO), ATtiny84 et ATtiny85 pour creer facilement des sequences de servos et/ou executer des actions depuis des commandes RC.
|
||||
Elle peut egalement etre utilisee pour lancer des "actions courtes" (la duree doit etre inferieure a 20ms pour ne pas perturber la commande des servos)
|
||||
@@ -58,7 +58,7 @@
|
||||
| | | \
|
||||
| X O X | --> RC_IMPULSION_NIVEAU_MOINS_1 |
|
||||
| | | |
|
||||
| X O X | --> RC_IMPULSION_NIVEAU_MOINS_2 |
|
||||
| X O X | --> RC_IMPULSION_NIVEAU_MOINS_2 |
|
||||
'---------------------' /
|
||||
| | | | |
|
||||
| | | | | \
|
||||
@@ -76,6 +76,10 @@
|
||||
/*************************************************************************
|
||||
MACROS
|
||||
*************************************************************************/
|
||||
/* For an easy Library Version Management */
|
||||
#define RC_SEQ_LIB_VERSION 2
|
||||
#define RC_SEQ_LIB_REVISION 1
|
||||
|
||||
#define STR(s) #s
|
||||
#define MAKE_TEXT_VER_REV(Ver,Rev) (char*)(STR(Ver)"."STR(Rev))
|
||||
|
||||
@@ -123,12 +127,12 @@ Pos 0 1 2 3 4
|
||||
1000us 2000us (Typical Pulse Width values)
|
||||
|
||||
*/
|
||||
#define ACTIVE_AREA_STEP_NBR 3
|
||||
#define INACTIVE_AREA_STEP_NBR 1
|
||||
#define TOTAL_STEP_NBR(KeyNb,Type) ((Type==RC_CMD_STICK)?((KeyNb)*(ACTIVE_AREA_STEP_NBR+INACTIVE_AREA_STEP_NBR)):(((KeyNb)*(ACTIVE_AREA_STEP_NBR+INACTIVE_AREA_STEP_NBR))-1))
|
||||
#define STEP(MinUs, MaxUs,KeyNb,Type) ((MaxUs-MinUs)/TOTAL_STEP_NBR(KeyNb,Type))
|
||||
#define KEY_MIN_VAL(Idx,Step) ((ACTIVE_AREA_STEP_NBR+INACTIVE_AREA_STEP_NBR)*(Step)*(Idx))
|
||||
#define KEY_MAX_VAL(Idx,Step) (KEY_MIN_VAL(Idx,Step)+(ACTIVE_AREA_STEP_NBR*(Step)))
|
||||
#define ACTIVE_AREA_STEP_NBR 3
|
||||
#define INACTIVE_AREA_STEP_NBR 1
|
||||
#define TOTAL_STEP_NBR(KeyNb, Type) ((Type==RC_CMD_STICK)?((KeyNb)*(ACTIVE_AREA_STEP_NBR+INACTIVE_AREA_STEP_NBR)):(((KeyNb)*(ACTIVE_AREA_STEP_NBR+INACTIVE_AREA_STEP_NBR))-1))
|
||||
#define STEP(MinUs, MaxUs, KeyNb, Type) ((MaxUs-MinUs)/TOTAL_STEP_NBR(KeyNb,Type))
|
||||
#define KEY_MIN_VAL(Idx, Step) ((ACTIVE_AREA_STEP_NBR+INACTIVE_AREA_STEP_NBR)*(Step)*(Idx))
|
||||
#define KEY_MAX_VAL(Idx, Step) (KEY_MIN_VAL(Idx,Step)+(ACTIVE_AREA_STEP_NBR*(Step)))
|
||||
|
||||
typedef struct {
|
||||
int8_t InProgress;
|
||||
@@ -138,6 +142,9 @@ typedef struct {
|
||||
void *TableOrShortAction;
|
||||
uint8_t SequenceLength;
|
||||
uint8_t ShortActionMap;
|
||||
#ifdef RC_SEQ_CONTROL_SUPPORT
|
||||
uint8_t(*Control)(uint8_t Action, uint8_t SeqIdx);
|
||||
#endif
|
||||
}CmdSequenceSt_t;
|
||||
|
||||
#ifdef RC_SEQ_WITH_SOFT_RC_PULSE_IN_SUPPORT
|
||||
@@ -147,14 +154,14 @@ typedef struct {
|
||||
}PosST_t;
|
||||
|
||||
typedef struct {
|
||||
SoftRcPulseIn Pulse;
|
||||
PosST_t Pos;
|
||||
uint8_t Type; /* RC_CMD_STICK or RC_CMD_KEYBOARD or RC_CMD_CUSTOM */
|
||||
uint8_t PosNb;
|
||||
uint16_t PulseMinUs;
|
||||
uint16_t PulseMaxUs;
|
||||
uint16_t StepUs;
|
||||
KeyMap_t *KeyMap;
|
||||
SoftRcPulseIn Pulse;
|
||||
PosST_t Pos;
|
||||
uint8_t Type; /* RC_CMD_STICK or RC_CMD_KEYBOARD or RC_CMD_CUSTOM */
|
||||
uint8_t PosNb;
|
||||
uint16_t PulseMinUs;
|
||||
uint16_t PulseMaxUs;
|
||||
uint16_t StepUs;
|
||||
const KeyMap_t *KeyMap;
|
||||
}RcCmdSt_t;
|
||||
#endif
|
||||
|
||||
@@ -175,47 +182,42 @@ static uint8_t CmdSignalNb;
|
||||
static RcCmdSt_t RcChannel[RC_CMD_MAX_NB];
|
||||
#endif
|
||||
#ifdef RC_SEQ_WITH_STATIC_MEM_ALLOC_SUPPORT
|
||||
#define AsMember .
|
||||
#ifdef RC_SEQ_WITH_SOFT_RC_PULSE_OUT_SUPPORT
|
||||
static ServoSt_t Servo[SERVO_MAX_NB];
|
||||
#endif
|
||||
static CmdSequenceSt_t CmdSequence[SEQUENCE_MAX_NB];
|
||||
#else
|
||||
#define AsMember ->
|
||||
#ifdef RC_SEQ_WITH_SOFT_RC_PULSE_OUT_SUPPORT
|
||||
static ServoSt_t **Servo=NULL;
|
||||
static ServoSt_t *Servo = NULL;
|
||||
#endif
|
||||
static CmdSequenceSt_t **CmdSequence=NULL;
|
||||
static CmdSequenceSt_t *CmdSequence = NULL;
|
||||
#endif
|
||||
/*************************************************************************
|
||||
PRIVATE FUNCTION PROTOTYPES
|
||||
*************************************************************************/
|
||||
static void ExecuteSequence(uint8_t CmdIdx, uint8_t Pos);
|
||||
#ifndef RC_SEQ_WITH_STATIC_MEM_ALLOC_SUPPORT
|
||||
static void LoadSequenceOrShortAction(uint8_t CmdIdx,uint8_t Pos,void *SequenceOrShortAction, uint8_t SequenceLength);
|
||||
#endif
|
||||
static uint8_t ExecuteSequence(uint8_t CmdIdx, uint8_t Pos);
|
||||
#ifdef RC_SEQ_WITH_SOFT_RC_PULSE_IN_SUPPORT
|
||||
static int8_t GetPos(uint8_t ChIdx,uint16_t PulseWidthUs);
|
||||
static int8_t GetPos(uint8_t ChIdx, uint16_t PulseWidthUs);
|
||||
#endif
|
||||
|
||||
//========================================================================================================================
|
||||
void RcSeq_Init(void)
|
||||
{
|
||||
SeqNb=0;
|
||||
ServoNb=0;
|
||||
SeqNb = 0;
|
||||
ServoNb = 0;
|
||||
#ifdef RC_SEQ_WITH_SOFT_RC_PULSE_IN_SUPPORT
|
||||
for(uint8_t ChIdx=0;ChIdx<RC_CMD_MAX_NB;ChIdx++)
|
||||
for(uint8_t ChIdx = 0; ChIdx < RC_CMD_MAX_NB; ChIdx++)
|
||||
{
|
||||
RcChannel[ChIdx].Pos.Idx=NO_POS;
|
||||
RcChannel[ChIdx].Pos.Idx = NO_POS;
|
||||
}
|
||||
#endif
|
||||
#ifdef RC_SEQ_WITH_STATIC_MEM_ALLOC_SUPPORT
|
||||
for(uint8_t SeqIdx=0;SeqIdx<SEQUENCE_MAX_NB;SeqIdx++)
|
||||
for(uint8_t SeqIdx = 0; SeqIdx < SEQUENCE_MAX_NB; SeqIdx++)
|
||||
{
|
||||
CmdSequence[SeqIdx].InProgress=0;
|
||||
CmdSequence[SeqIdx].TableOrShortAction=NULL;
|
||||
CmdSequence[SeqIdx].SequenceLength=0;
|
||||
CmdSequence[SeqIdx].ShortActionMap=0;
|
||||
CmdSequence[SeqIdx].InProgress = 0;
|
||||
CmdSequence[SeqIdx].TableOrShortAction = NULL;
|
||||
CmdSequence[SeqIdx].SequenceLength = 0;
|
||||
CmdSequence[SeqIdx].ShortActionMap = 0;
|
||||
}
|
||||
#endif
|
||||
#ifdef RC_SEQ_WITH_SOFT_RC_PULSE_IN_SUPPORT
|
||||
@@ -242,36 +244,53 @@ char *RcSeq_LibTextVersionRevision(void)
|
||||
void RcSeq_DeclareServo(uint8_t Idx, uint8_t DigitalPin)
|
||||
{
|
||||
#ifdef RC_SEQ_WITH_STATIC_MEM_ALLOC_SUPPORT
|
||||
if(Idx<SERVO_MAX_NB)
|
||||
if(Idx < SERVO_MAX_NB)
|
||||
{
|
||||
Servo[Idx].Motor.attach(DigitalPin);
|
||||
Servo[Idx].SeqLineInProgress=NO_SEQ_LINE;
|
||||
if(ServoNb<(Idx+1)) ServoNb=(Idx+1);
|
||||
Servo[Idx].SeqLineInProgress = NO_SEQ_LINE;
|
||||
if(ServoNb < (Idx + 1)) ServoNb = (Idx + 1);
|
||||
}
|
||||
#else
|
||||
if(Idx<SERVO_MAX_NB)
|
||||
if(Idx < SERVO_MAX_NB)
|
||||
{
|
||||
ServoNb++;
|
||||
if(!Servo) Servo=(ServoSt_t**)malloc(sizeof(ServoSt_t));
|
||||
else Servo=(ServoSt_t**)realloc(Servo, sizeof(ServoSt_t)*ServoNb);
|
||||
Servo[Idx] AsMember Motor.attach(DigitalPin);
|
||||
Servo[Idx] AsMember SeqLineInProgress=NO_SEQ_LINE;
|
||||
if(!Servo) Servo = (ServoSt_t*)malloc(sizeof(ServoSt_t));
|
||||
else Servo = (ServoSt_t*)realloc(Servo, sizeof(ServoSt_t) * ServoNb);
|
||||
Servo[Idx].Motor.attach(DigitalPin);
|
||||
Servo[Idx].SeqLineInProgress = NO_SEQ_LINE;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
//========================================================================================================================
|
||||
void RcSeq_ServoWrite(uint8_t Idx, uint16_t Angle)
|
||||
{
|
||||
if(Idx < SERVO_MAX_NB)
|
||||
{
|
||||
Servo[Idx].Motor.write(Angle);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
//========================================================================================================================
|
||||
#ifdef RC_SEQ_WITH_SOFT_RC_PULSE_IN_SUPPORT
|
||||
void RcSeq_DeclareSignal(uint8_t Idx, uint8_t DigitalPin)
|
||||
{
|
||||
if(Idx<RC_CMD_MAX_NB)
|
||||
if(Idx < RC_CMD_MAX_NB)
|
||||
{
|
||||
RcChannel[Idx].Pulse.attach(DigitalPin);
|
||||
CmdSignalNb++;
|
||||
}
|
||||
}
|
||||
//========================================================================================================================
|
||||
void RcSeq_DeclareKeyboardOrStickOrCustom(uint8_t ChIdx, uint8_t Type, uint16_t PulseMinUs, uint16_t PulseMaxUs, KeyMap_t *KeyMap, uint8_t PosNb)
|
||||
boolean RcSeq_SignalTimeout(uint8_t Idx, uint8_t TimeoutMs, uint8_t *State)
|
||||
{
|
||||
if(Idx < RC_CMD_MAX_NB)
|
||||
{
|
||||
return(RcChannel[Idx].Pulse.timeout(TimeoutMs, State));
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
//========================================================================================================================
|
||||
void RcSeq_DeclareKeyboardOrStickOrCustom(uint8_t ChIdx, uint8_t Type, uint16_t PulseMinUs, uint16_t PulseMaxUs, const KeyMap_t *KeyMap, uint8_t PosNb)
|
||||
{
|
||||
RcChannel[ChIdx].Type = Type;
|
||||
RcChannel[ChIdx].PosNb = PosNb;
|
||||
@@ -281,50 +300,62 @@ void RcSeq_DeclareKeyboardOrStickOrCustom(uint8_t ChIdx, uint8_t Type, uint16_t
|
||||
RcChannel[ChIdx].KeyMap = KeyMap;
|
||||
}
|
||||
//========================================================================================================================
|
||||
void RcSeq_DeclareCustomKeyboard(uint8_t ChIdx, KeyMap_t *KeyMapTbl, uint8_t KeyNb)
|
||||
void RcSeq_DeclareCustomKeyboard(uint8_t ChIdx, const KeyMap_t *KeyMapTbl, uint8_t KeyNb)
|
||||
{
|
||||
RcSeq_DeclareKeyboardOrStickOrCustom(ChIdx, RC_CMD_CUSTOM, 0, 0, KeyMapTbl, KeyNb);
|
||||
}
|
||||
#endif
|
||||
//========================================================================================================================
|
||||
void RcSeq_DeclareCommandAndSequence(uint8_t CmdIdx,uint8_t Pos,SequenceSt_t *Table, uint8_t SequenceLength)
|
||||
#ifdef RC_SEQ_CONTROL_SUPPORT
|
||||
void RcSeq_DeclareCommandAndSequence(uint8_t CmdIdx,uint8_t Pos, const SequenceSt_t *Table, uint8_t SequenceLength, uint8_t(*Control)(uint8_t Action, uint8_t SeqIdx))
|
||||
#else
|
||||
void RcSeq_DeclareCommandAndSequence(uint8_t CmdIdx,uint8_t Pos, const SequenceSt_t *Table, uint8_t SequenceLength)
|
||||
#endif
|
||||
{
|
||||
uint8_t Idx, ServoIdx;
|
||||
uint16_t StartInDegrees;
|
||||
uint32_t StartMinMs[SERVO_MAX_NB];
|
||||
#ifdef RC_SEQ_WITH_STATIC_MEM_ALLOC_SUPPORT
|
||||
for(Idx=0;Idx<SEQUENCE_MAX_NB;Idx++)
|
||||
#ifndef RC_SEQ_WITH_STATIC_MEM_ALLOC_SUPPORT
|
||||
if(!CmdSequence) CmdSequence = (CmdSequenceSt_t*)malloc(sizeof(CmdSequenceSt_t));
|
||||
else CmdSequence = (CmdSequenceSt_t*)realloc(CmdSequence, sizeof(CmdSequenceSt_t) * (SeqNb + 1));
|
||||
Idx = SeqNb;
|
||||
SeqNb++;
|
||||
#else
|
||||
for(Idx = 0; Idx < SEQUENCE_MAX_NB; Idx++)
|
||||
{
|
||||
if(!CmdSequence[Idx].TableOrShortAction)
|
||||
{
|
||||
CmdSequence[Idx].CmdIdx=CmdIdx;
|
||||
CmdSequence[Idx].Pos=Pos;
|
||||
CmdSequence[Idx].TableOrShortAction=(void*)Table;
|
||||
CmdSequence[Idx].SequenceLength=SequenceLength;
|
||||
#endif
|
||||
CmdSequence[Idx].CmdIdx = CmdIdx;
|
||||
CmdSequence[Idx].Pos = Pos;
|
||||
CmdSequence[Idx].TableOrShortAction = (void*)Table;
|
||||
CmdSequence[Idx].SequenceLength = SequenceLength;
|
||||
#ifdef RC_SEQ_CONTROL_SUPPORT
|
||||
CmdSequence[Idx].Control = Control;
|
||||
#endif
|
||||
#ifdef RC_SEQ_WITH_STATIC_MEM_ALLOC_SUPPORT
|
||||
SeqNb++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
#else
|
||||
LoadSequenceOrShortAction(CmdIdx,Pos,(void*)Table, SequenceLength);
|
||||
#endif
|
||||
|
||||
#ifdef RC_SEQ_WITH_SOFT_RC_PULSE_OUT_SUPPORT
|
||||
/* Get initial pulse width for each Servo */
|
||||
for(Idx=0;Idx<SERVO_MAX_NB;Idx++)
|
||||
for(Idx = 0; Idx < SERVO_MAX_NB; Idx++)
|
||||
{
|
||||
StartMinMs[Idx]=0xFFFFFFFF;
|
||||
StartMinMs[Idx] = 0xFFFFFFFF;
|
||||
}
|
||||
for(Idx=0;Idx<SequenceLength;Idx++)
|
||||
for(Idx = 0; Idx < SequenceLength; Idx++)
|
||||
{
|
||||
ServoIdx=(int8_t)PGM_READ_8(Table[Idx].ServoIndex);
|
||||
if(ServoIdx!=255)
|
||||
ServoIdx = (int8_t)PGM_READ_8(Table[Idx].ServoIndex);
|
||||
if(ServoIdx != 255)
|
||||
{
|
||||
if((uint32_t)PGM_READ_32(Table[Idx].StartMotionOffsetMs)<=StartMinMs[ServoIdx])
|
||||
if((uint32_t)PGM_READ_32(Table[Idx].StartMotionOffsetMs) <= StartMinMs[ServoIdx])
|
||||
{
|
||||
StartMinMs[ServoIdx]=(uint32_t)PGM_READ_32(Table[Idx].StartMotionOffsetMs);
|
||||
StartInDegrees=(uint16_t)PGM_READ_8(Table[Idx].StartInDegrees);
|
||||
Servo[ServoIdx] AsMember Motor.write(StartInDegrees);
|
||||
StartMinMs[ServoIdx] = (uint32_t)PGM_READ_32(Table[Idx].StartMotionOffsetMs);
|
||||
StartInDegrees = (uint16_t)PGM_READ_8(Table[Idx].StartInDegrees);
|
||||
Servo[ServoIdx].Motor.write(StartInDegrees);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -332,49 +363,42 @@ uint32_t StartMinMs[SERVO_MAX_NB];
|
||||
}
|
||||
#ifdef RC_SEQ_WITH_SOFT_RC_PULSE_IN_SUPPORT
|
||||
//========================================================================================================================
|
||||
void RcSeq_DeclareCommandAndShortAction(uint8_t CmdIdx,uint8_t Pos,void(*ShortAction)(void))
|
||||
void RcSeq_DeclareCommandAndShortAction(uint8_t CmdIdx, uint8_t Pos, void(*ShortAction)(void))
|
||||
{
|
||||
#ifdef RC_SEQ_WITH_STATIC_MEM_ALLOC_SUPPORT
|
||||
uint8_t Idx;
|
||||
for(Idx=0;Idx<SEQUENCE_MAX_NB;Idx++)
|
||||
#ifndef RC_SEQ_WITH_STATIC_MEM_ALLOC_SUPPORT
|
||||
if(!CmdSequence) CmdSequence = (CmdSequenceSt_t*)malloc(sizeof(CmdSequenceSt_t));
|
||||
else CmdSequence = (CmdSequenceSt_t*)realloc(CmdSequence, sizeof(CmdSequenceSt_t) * (SeqNb + 1));
|
||||
Idx = SeqNb;
|
||||
SeqNb++;
|
||||
#else
|
||||
for(Idx = 0; Idx < SEQUENCE_MAX_NB; Idx++)
|
||||
{
|
||||
if(!CmdSequence[Idx].TableOrShortAction)
|
||||
{
|
||||
CmdSequence[Idx].CmdIdx=CmdIdx;
|
||||
CmdSequence[Idx].Pos=Pos;
|
||||
CmdSequence[Idx].TableOrShortAction=(void*)ShortAction;
|
||||
#endif
|
||||
CmdSequence[Idx].CmdIdx = CmdIdx;
|
||||
CmdSequence[Idx].Pos = Pos;
|
||||
CmdSequence[Idx].TableOrShortAction = (void*)ShortAction;
|
||||
CmdSequence[Idx].SequenceLength = 0;
|
||||
#ifdef RC_SEQ_WITH_STATIC_MEM_ALLOC_SUPPORT
|
||||
SeqNb++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
#else
|
||||
LoadSequenceOrShortAction(CmdIdx,Pos,(void*)ShortAction, 0);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef RC_SEQ_WITH_STATIC_MEM_ALLOC_SUPPORT
|
||||
static void LoadSequenceOrShortAction(uint8_t CmdIdx,uint8_t Pos,void *SequenceOrShortAction, uint8_t SequenceLength)
|
||||
{
|
||||
if(!CmdSequence) CmdSequence=(CmdSequenceSt_t**)malloc(sizeof(CmdSequenceSt_t));
|
||||
else CmdSequence=(CmdSequenceSt_t**)realloc(CmdSequence,sizeof(CmdSequence)+sizeof(CmdSequenceSt_t));
|
||||
CmdSequence[SeqNb] AsMember CmdIdx=CmdIdx;
|
||||
CmdSequence[SeqNb] AsMember Pos=Pos;
|
||||
CmdSequence[SeqNb] AsMember TableOrShortAction=(void*)SequenceOrShortAction;
|
||||
CmdSequence[SeqNb] AsMember SequenceLength=SequenceLength;
|
||||
SeqNb++;
|
||||
}
|
||||
#endif
|
||||
//========================================================================================================================
|
||||
uint8_t RcSeq_LaunchSequence(SequenceSt_t *Table)
|
||||
uint8_t RcSeq_LaunchSequence(const SequenceSt_t *Table)
|
||||
{
|
||||
uint8_t Idx, Ret=0;
|
||||
for(Idx=0;Idx<SEQUENCE_MAX_NB;Idx++)
|
||||
uint8_t Idx, Ret = 0;
|
||||
for(Idx = 0; Idx < SEQUENCE_MAX_NB; Idx++)
|
||||
{
|
||||
if(CmdSequence[Idx] AsMember TableOrShortAction==(void*)Table)
|
||||
if(CmdSequence[Idx].TableOrShortAction == (void*)Table)
|
||||
{
|
||||
ExecuteSequence(CmdSequence[Idx] AsMember CmdIdx,CmdSequence[Idx] AsMember Pos);
|
||||
Ret=1;
|
||||
Ret = ExecuteSequence(CmdSequence[Idx].CmdIdx, CmdSequence[Idx].Pos);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -383,8 +407,8 @@ uint8_t Idx, Ret=0;
|
||||
//========================================================================================================================
|
||||
void RcSeq_Refresh(void)
|
||||
{
|
||||
static uint32_t NowMs=millis();
|
||||
static uint32_t StartChronoInterPulseMs=millis();
|
||||
static uint32_t NowMs = millis();
|
||||
static uint32_t StartChronoInterPulseMs = millis();
|
||||
SequenceSt_t *SequenceTable;
|
||||
void (*ShortAction)(void);
|
||||
int8_t ShortActionCnt;
|
||||
@@ -398,100 +422,104 @@ int8_t CmdPos; /* Shall be signed */
|
||||
uint32_t RcPulseWidthUs;
|
||||
|
||||
/* Asynchronous RC Command acquisition */
|
||||
for(ChIdx=0;ChIdx<CmdSignalNb;ChIdx++)
|
||||
for(ChIdx = 0; ChIdx < CmdSignalNb; ChIdx++)
|
||||
{
|
||||
if(!RcChannel[ChIdx].Pulse.available()) continue; /* Channel not used or no pulse received */
|
||||
RcPulseWidthUs=RcChannel[ChIdx].Pulse.width_us();
|
||||
CmdPos=GetPos(ChIdx,RcPulseWidthUs);
|
||||
if(CmdPos>=0)
|
||||
RcPulseWidthUs = RcChannel[ChIdx].Pulse.width_us();
|
||||
CmdPos = GetPos(ChIdx, RcPulseWidthUs);
|
||||
// Serial.print("W=");Serial.print(RcPulseWidthUs);Serial.print(" P=");Serial.println((int)CmdPos);
|
||||
if(CmdPos >= 0)
|
||||
{
|
||||
if(RcChannel[ChIdx].Pos.Idx!=CmdPos)
|
||||
if(RcChannel[ChIdx].Pos.Idx != CmdPos)
|
||||
{
|
||||
RcChannel[ChIdx].Pos.Idx=CmdPos;
|
||||
RcChannel[ChIdx].Pos.StartChronoMs=millis();
|
||||
RcChannel[ChIdx].Pos.Idx = CmdPos;
|
||||
RcChannel[ChIdx].Pos.StartChronoMs = millis();
|
||||
}
|
||||
else
|
||||
{
|
||||
if((millis()-RcChannel[ChIdx].Pos.StartChronoMs)>=((RcChannel[ChIdx].Type==RC_CMD_STICK)?STICK_PULSE_CHECK_MS:KBD_PULSE_CHECK_MS)) /* Check the Pulse is valid at least for 100 ms or 50 ms */
|
||||
if((millis() - RcChannel[ChIdx].Pos.StartChronoMs) >= ((RcChannel[ChIdx].Type == RC_CMD_STICK)?STICK_PULSE_CHECK_MS:KBD_PULSE_CHECK_MS)) /* Check the Pulse is valid at least for 100 ms or 50 ms */
|
||||
{
|
||||
ExecuteSequence(ChIdx,CmdPos);
|
||||
RcChannel[ChIdx].Pos.Idx=NO_POS;
|
||||
ExecuteSequence(ChIdx, CmdPos);
|
||||
RcChannel[ChIdx].Pos.Idx = NO_POS;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
RcChannel[ChIdx].Pos.Idx=NO_POS;
|
||||
RcChannel[ChIdx].Pos.Idx = NO_POS;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
NowMs=millis();
|
||||
NowMs = millis();
|
||||
if((NowMs - StartChronoInterPulseMs) >= 20UL)
|
||||
{
|
||||
/* We arrive here every 20 ms */
|
||||
/* Asynchronous Servo Sequence management */
|
||||
for(int8_t Idx=0;Idx<SeqNb;Idx++)
|
||||
for(int8_t Idx = 0; Idx < SeqNb; Idx++)
|
||||
{
|
||||
if(!CmdSequence[Idx] AsMember InProgress || !CmdSequence[Idx] AsMember SequenceLength) continue;
|
||||
ShortActionCnt=-1;
|
||||
for(int8_t SeqLine=0;SeqLine<CmdSequence[Idx] AsMember SequenceLength;SeqLine++) /* Read all lines of the sequence table: this allows to run several servos simultaneously (not forcibly one after the other) */
|
||||
if(!CmdSequence[Idx].InProgress || !CmdSequence[Idx].SequenceLength) continue;
|
||||
ShortActionCnt = -1;
|
||||
for(int8_t SeqLine = 0; SeqLine < CmdSequence[Idx].SequenceLength; SeqLine++) /* Read all lines of the sequence table: this allows to run several servos simultaneously (not forcibly one after the other) */
|
||||
{
|
||||
SequenceTable=(SequenceSt_t *)CmdSequence[Idx] AsMember TableOrShortAction;
|
||||
ServoIdx=(int8_t)PGM_READ_8(SequenceTable[SeqLine].ServoIndex);
|
||||
SequenceTable = (SequenceSt_t *)CmdSequence[Idx].TableOrShortAction;
|
||||
ServoIdx = (int8_t)PGM_READ_8(SequenceTable[SeqLine].ServoIndex);
|
||||
#ifdef RC_SEQ_WITH_SHORT_ACTION_SUPPORT
|
||||
if(ServoIdx==255) /* Not a Servo: it's a short Action to perform only if not already done */
|
||||
if(ServoIdx == 255) /* Not a Servo: it's a short Action to perform only if not already done */
|
||||
{
|
||||
ShortActionCnt++;
|
||||
StartOfSeqMs = CmdSequence[Idx] AsMember StartChronoMs + (int32_t)PGM_READ_32(SequenceTable[SeqLine].StartMotionOffsetMs);
|
||||
if( (NowMs>=StartOfSeqMs) && !TST_BIT(CmdSequence[Idx] AsMember ShortActionMap,ShortActionCnt) )
|
||||
StartOfSeqMs = CmdSequence[Idx].StartChronoMs + (int32_t)PGM_READ_32(SequenceTable[SeqLine].StartMotionOffsetMs);
|
||||
if( (NowMs >= StartOfSeqMs) && !TST_BIT(CmdSequence[Idx].ShortActionMap, ShortActionCnt) )
|
||||
{
|
||||
ShortAction=(void(*)(void))PGM_READ_16(SequenceTable[SeqLine].ShortAction);
|
||||
ShortAction = (void(*)(void))PGM_READ_16(SequenceTable[SeqLine].ShortAction);
|
||||
ShortAction();
|
||||
SET_BIT(CmdSequence[Idx] AsMember ShortActionMap,ShortActionCnt); /* Mark short Action as performed */
|
||||
/* If the last line contains an Action AsMember End of Sequence */
|
||||
if(SeqLine==(CmdSequence[Idx] AsMember SequenceLength-1))
|
||||
SET_BIT(CmdSequence[Idx].ShortActionMap, ShortActionCnt); /* Mark short Action as performed */
|
||||
/* If the last line contains an Action: End of Sequence */
|
||||
if(SeqLine == (CmdSequence[Idx].SequenceLength - 1))
|
||||
{
|
||||
CmdSequence[Idx] AsMember InProgress=0;
|
||||
CmdSequence[Idx] AsMember ShortActionMap=0; /* Mark all Short Action as not performed */
|
||||
CmdSequence[Idx].InProgress = 0;
|
||||
CmdSequence[Idx].ShortActionMap = 0; /* Mark all Short Action as not performed */
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
#ifdef RC_SEQ_WITH_SOFT_RC_PULSE_OUT_SUPPORT
|
||||
if(Servo[ServoIdx] AsMember RefreshNb && SeqLine!=Servo[ServoIdx] AsMember SeqLineInProgress)
|
||||
if(Servo[ServoIdx].RefreshNb && SeqLine != Servo[ServoIdx].SeqLineInProgress)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
StartOfSeqMs = CmdSequence[Idx] AsMember StartChronoMs + (int32_t)PGM_READ_32(SequenceTable[SeqLine].StartMotionOffsetMs);
|
||||
StartOfSeqMs = CmdSequence[Idx].StartChronoMs + (int32_t)PGM_READ_32(SequenceTable[SeqLine].StartMotionOffsetMs);
|
||||
MotionDurationMs = (int32_t)PGM_READ_32(SequenceTable[SeqLine].MotionDurationMs);
|
||||
EndOfSeqMs = StartOfSeqMs + MotionDurationMs;
|
||||
if(!Servo[ServoIdx] AsMember RefreshNb && Servo[ServoIdx] AsMember SeqLineInProgress==NO_SEQ_LINE)
|
||||
if(!Servo[ServoIdx].RefreshNb && Servo[ServoIdx].SeqLineInProgress == NO_SEQ_LINE)
|
||||
{
|
||||
if( (NowMs>=StartOfSeqMs) && (NowMs<=EndOfSeqMs) )
|
||||
if( (NowMs >= StartOfSeqMs) && (NowMs <= EndOfSeqMs) )
|
||||
{
|
||||
Servo[ServoIdx] AsMember SeqLineInProgress=SeqLine;
|
||||
StartInDegrees=(uint16_t)PGM_READ_8(SequenceTable[SeqLine].StartInDegrees);
|
||||
Servo[ServoIdx] AsMember RefreshNb=REFRESH_NB(MotionDurationMs);
|
||||
Servo[ServoIdx] AsMember Motor.write(StartInDegrees);
|
||||
Servo[ServoIdx].SeqLineInProgress = SeqLine;
|
||||
StartInDegrees = (uint16_t)PGM_READ_8(SequenceTable[SeqLine].StartInDegrees);
|
||||
Servo[ServoIdx].RefreshNb = REFRESH_NB(MotionDurationMs);
|
||||
Servo[ServoIdx].Motor.write(StartInDegrees);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* A sequence line is in progress: update the next position */
|
||||
if(Servo[ServoIdx] AsMember RefreshNb) Servo[ServoIdx] AsMember RefreshNb--;
|
||||
StartInDegrees=(uint16_t)PGM_READ_8(SequenceTable[SeqLine].StartInDegrees);
|
||||
EndInDegrees=(uint16_t)PGM_READ_8(SequenceTable[SeqLine].EndInDegrees);
|
||||
Pos=(int32_t)EndInDegrees-((int32_t)Servo[ServoIdx] AsMember RefreshNb*STEP_IN_DEGREES_PER_REFRESH((int32_t)StartInDegrees,(int32_t)EndInDegrees,(int32_t)MotionDurationMs)); //For refresh max nb, Pos = StartInDegrees
|
||||
Servo[ServoIdx] AsMember Motor.write(Pos);
|
||||
if( !Servo[ServoIdx] AsMember RefreshNb )
|
||||
if(Servo[ServoIdx].RefreshNb) Servo[ServoIdx].RefreshNb--;
|
||||
StartInDegrees = (uint16_t)PGM_READ_8(SequenceTable[SeqLine].StartInDegrees);
|
||||
EndInDegrees = (uint16_t)PGM_READ_8(SequenceTable[SeqLine].EndInDegrees);
|
||||
Pos = (int32_t)EndInDegrees - ((int32_t)Servo[ServoIdx].RefreshNb * STEP_IN_DEGREES_PER_REFRESH((int32_t)StartInDegrees,(int32_t)EndInDegrees,(int32_t)MotionDurationMs)); //For refresh max nb, Pos = StartInDegrees
|
||||
Servo[ServoIdx].Motor.write(Pos);
|
||||
if( !Servo[ServoIdx].RefreshNb )
|
||||
{
|
||||
Servo[ServoIdx] AsMember SeqLineInProgress=NO_SEQ_LINE;
|
||||
Servo[ServoIdx].SeqLineInProgress = NO_SEQ_LINE;
|
||||
/* Last servo motion and refresh = 0 -> End of Sequence */
|
||||
if(SeqLine==(CmdSequence[Idx] AsMember SequenceLength-1))
|
||||
if(SeqLine == (CmdSequence[Idx].SequenceLength - 1))
|
||||
{
|
||||
CmdSequence[Idx] AsMember InProgress=0;
|
||||
CmdSequence[Idx] AsMember ShortActionMap=0; /* Mark all Short Action as not performed */
|
||||
CmdSequence[Idx].InProgress = 0;
|
||||
CmdSequence[Idx].ShortActionMap = 0; /* Mark all Short Action as not performed */
|
||||
#ifdef RC_SEQ_CONTROL_SUPPORT
|
||||
if(CmdSequence[Idx].Control != NULL) CmdSequence[Idx].Control(RC_SEQ_END_OF_SEQ, Idx);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -501,76 +529,94 @@ uint32_t RcPulseWidthUs;
|
||||
#ifdef RC_SEQ_WITH_SOFT_RC_PULSE_OUT_SUPPORT
|
||||
SoftRcPulseOut::refresh(1); /* Force Refresh */
|
||||
#endif
|
||||
StartChronoInterPulseMs=millis();
|
||||
StartChronoInterPulseMs = millis();
|
||||
}
|
||||
}
|
||||
|
||||
//========================================================================================================================
|
||||
// PRIVATE FUNCTIONS
|
||||
//========================================================================================================================
|
||||
static void ExecuteSequence(uint8_t CmdIdx, uint8_t Pos)
|
||||
static uint8_t ExecuteSequence(uint8_t CmdIdx, uint8_t Pos)
|
||||
{
|
||||
void(*ShortAction)(void);
|
||||
uint8_t Idx;
|
||||
uint8_t Idx, Ret = 0;
|
||||
|
||||
for(Idx=0;Idx<SeqNb;Idx++)
|
||||
for(Idx = 0; Idx < SeqNb; Idx++)
|
||||
{
|
||||
if((CmdSequence[Idx] AsMember CmdIdx==CmdIdx) && (CmdSequence[Idx] AsMember Pos==Pos))
|
||||
if((CmdSequence[Idx].CmdIdx == CmdIdx) && (CmdSequence[Idx].Pos == Pos))
|
||||
{
|
||||
#ifdef RC_SEQ_WITH_SHORT_ACTION_SUPPORT
|
||||
if(CmdSequence[Idx] AsMember TableOrShortAction && !CmdSequence[Idx] AsMember SequenceLength)
|
||||
if(CmdSequence[Idx].TableOrShortAction && !CmdSequence[Idx].SequenceLength)
|
||||
{
|
||||
/* It's a short action */
|
||||
ShortAction=(void(*)(void))CmdSequence[Idx] AsMember TableOrShortAction;
|
||||
ShortAction = (void(*)(void))CmdSequence[Idx].TableOrShortAction;
|
||||
ShortAction();
|
||||
Ret = 1;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
/* It's a Table of Sequence */
|
||||
if(!CmdSequence[Idx] AsMember InProgress)
|
||||
if(!CmdSequence[Idx].InProgress)
|
||||
{
|
||||
CmdSequence[Idx] AsMember InProgress=1;
|
||||
CmdSequence[Idx] AsMember StartChronoMs=millis();
|
||||
#ifdef RC_SEQ_CONTROL_SUPPORT
|
||||
uint8_t Go = 1;
|
||||
if(CmdSequence[Idx].Control != NULL)
|
||||
{
|
||||
Go = CmdSequence[Idx].Control(RC_SEQ_START_CONDITION, Idx);
|
||||
// Serial.print(F("Go for Seq["));Serial.print(Idx);Serial.print(F("] "));Serial.println(Go?F("Yes"):F("No"));
|
||||
}
|
||||
if(Go)
|
||||
{
|
||||
CmdSequence[Idx].InProgress = 1;
|
||||
CmdSequence[Idx].StartChronoMs = millis();
|
||||
Ret = 1;
|
||||
}
|
||||
#else
|
||||
CmdSequence[Idx].InProgress = 1;
|
||||
CmdSequence[Idx].StartChronoMs = millis();
|
||||
Ret = 1;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return(Ret);
|
||||
}
|
||||
//========================================================================================================================
|
||||
#ifdef RC_SEQ_WITH_SOFT_RC_PULSE_IN_SUPPORT
|
||||
static int8_t GetPos(uint8_t ChIdx,uint16_t PulseWidthUs)
|
||||
static int8_t GetPos(uint8_t ChIdx, uint16_t PulseWidthUs)
|
||||
{
|
||||
int8_t Idx, Ret=-1;
|
||||
uint16_t PulseMinUs,PulseMaxUs;
|
||||
int8_t Idx, Ret = -1;
|
||||
uint16_t PulseMinUs, PulseMaxUs;
|
||||
|
||||
for(Idx=0;Idx<RcChannel[ChIdx].PosNb;Idx++)
|
||||
for(Idx = 0; Idx < RcChannel[ChIdx].PosNb; Idx++)
|
||||
{
|
||||
switch(RcChannel[ChIdx].Type)
|
||||
{
|
||||
case RC_CMD_STICK: /* No break: normal */
|
||||
case RC_CMD_MULTI_POS_SW:
|
||||
if( (RcChannel[ChIdx].Type==RC_CMD_MULTI_POS_SW) || ((RcChannel[ChIdx].Type==RC_CMD_STICK) && (Idx<(RcChannel[ChIdx].PosNb/2))) )
|
||||
if( (RcChannel[ChIdx].Type == RC_CMD_MULTI_POS_SW) || ((RcChannel[ChIdx].Type == RC_CMD_STICK) && (Idx < (RcChannel[ChIdx].PosNb / 2))) )
|
||||
{
|
||||
PulseMinUs=RcChannel[ChIdx].PulseMinUs+KEY_MIN_VAL(Idx,RcChannel[ChIdx].StepUs);
|
||||
PulseMaxUs=RcChannel[ChIdx].PulseMinUs+KEY_MAX_VAL(Idx,RcChannel[ChIdx].StepUs);
|
||||
PulseMinUs = RcChannel[ChIdx].PulseMinUs + KEY_MIN_VAL(Idx,RcChannel[ChIdx].StepUs);
|
||||
PulseMaxUs = RcChannel[ChIdx].PulseMinUs + KEY_MAX_VAL(Idx,RcChannel[ChIdx].StepUs);
|
||||
}
|
||||
else
|
||||
{
|
||||
PulseMinUs=RcChannel[ChIdx].PulseMaxUs-KEY_MAX_VAL(RcChannel[ChIdx].PosNb-1-Idx,RcChannel[ChIdx].StepUs);
|
||||
PulseMaxUs=RcChannel[ChIdx].PulseMaxUs-KEY_MIN_VAL(RcChannel[ChIdx].PosNb-1-Idx,RcChannel[ChIdx].StepUs);
|
||||
PulseMinUs = RcChannel[ChIdx].PulseMaxUs - KEY_MAX_VAL(RcChannel[ChIdx].PosNb - 1 - Idx, RcChannel[ChIdx].StepUs);
|
||||
PulseMaxUs = RcChannel[ChIdx].PulseMaxUs - KEY_MIN_VAL(RcChannel[ChIdx].PosNb - 1 - Idx, RcChannel[ChIdx].StepUs);
|
||||
}
|
||||
break;
|
||||
|
||||
case RC_CMD_CUSTOM:
|
||||
PulseMinUs=(uint16_t)PGM_READ_16(RcChannel[ChIdx].KeyMap[Idx].Min);
|
||||
PulseMaxUs=(uint16_t)PGM_READ_16(RcChannel[ChIdx].KeyMap[Idx].Max);
|
||||
PulseMinUs = (uint16_t)PGM_READ_16(RcChannel[ChIdx].KeyMap[Idx].Min);
|
||||
PulseMaxUs = (uint16_t)PGM_READ_16(RcChannel[ChIdx].KeyMap[Idx].Max);
|
||||
break;
|
||||
}
|
||||
if((PulseWidthUs>=PulseMinUs) && (PulseWidthUs<=PulseMaxUs))
|
||||
if((PulseWidthUs >= PulseMinUs) && (PulseWidthUs <= PulseMaxUs))
|
||||
{
|
||||
Ret=Idx;
|
||||
Ret = Idx;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@@ -2,7 +2,7 @@
|
||||
#define RC_SEQ_H
|
||||
|
||||
/*
|
||||
English: by RC Navy (2012/2013)
|
||||
English: by RC Navy (2012-2015)
|
||||
=======
|
||||
<RcSeq> is an asynchronous library for ATmega328P (UNO), ATtiny84 and ATtiny85 to easily create servo's sequences and/or to execute short actions from RC commands.
|
||||
It can also be used to trig some short "actions" (the duration must be less than 20ms to not disturb the servo commands)
|
||||
@@ -23,7 +23,7 @@
|
||||
CAUTION: the end user shall also use asynchronous programmation method in the loop() function (no blocking functions such as delay() or pulseIn()).
|
||||
http://p.loussouarn.free.fr
|
||||
|
||||
Francais: par RC Navy (2012/2013)
|
||||
Francais: par RC Navy (2012-2015)
|
||||
========
|
||||
<RcSeq> est une librairie asynchrone pour ATmega328P (UNO), ATtiny84 et ATtiny85 pour creer facilement des sequences de servos et/ou executer des actions depuis des commandes RC.
|
||||
Elle peut egalement etre utilisee pour lancer des "actions courtes" (la duree doit etre inferieure a 20ms pour ne pas perturber la commande des servos)
|
||||
@@ -48,19 +48,17 @@
|
||||
/* RCSEQ LIBRARY CONFIGURATION */
|
||||
/**********************************************/
|
||||
#define RC_SEQ_WITH_SOFT_RC_PULSE_IN_SUPPORT /* Comment this line if you use <DigiUSB> library in your sketch */
|
||||
//#define RC_SEQ_WITH_SOFT_RC_PULSE_OUT_SUPPORT /* Uncomment this if you use <SoftRcPulseOut> library in your sketch for servos and ESC */
|
||||
#define RC_SEQ_WITH_SOFT_RC_PULSE_OUT_SUPPORT /* Uncomment this if you use <SoftRcPulseOut> library in your sketch for servos and ESC */
|
||||
#define RC_SEQ_WITH_SHORT_ACTION_SUPPORT /* Uncomment this to allows to put call to short action in sequence table */
|
||||
#define RC_SEQ_CONTROL_SUPPORT /* Uncomment this to allow control on sequences: start condition and end of sequence */
|
||||
|
||||
|
||||
|
||||
/**********************************************/
|
||||
/* /!\ Do not touch below /!\ */
|
||||
/**********************************************/
|
||||
/* For an easy Library Version Management */
|
||||
#define RC_SEQ_LIB_VERSION 2
|
||||
#define RC_SEQ_LIB_REVISION 0
|
||||
|
||||
#define RC_SEQ_WITH_STATIC_MEM_ALLOC_SUPPORT /* Do NOT comment this line for DigiSpark, but you can for UNO */
|
||||
#define RC_SEQ_WITH_STATIC_MEM_ALLOC_SUPPORT /* Do NOT comment this line for now: still buggy (to do: fix this) */
|
||||
|
||||
#ifdef RC_SEQ_WITH_SOFT_RC_PULSE_IN_SUPPORT
|
||||
#include <TinyPinChange.h>
|
||||
@@ -86,14 +84,26 @@
|
||||
#include <inttypes.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#ifdef RC_SEQ_WITH_SOFT_RC_PULSE_IN_SUPPORT
|
||||
#define SERVO_MAX_NB 10
|
||||
#define SEQUENCE_MAX_NB 8
|
||||
#define RC_CMD_MAX_NB 4
|
||||
#if defined(RC_SEQ_WITH_SOFT_RC_PULSE_OUT_SUPPORT)
|
||||
#if defined(__AVR_ATtiny85__)
|
||||
#define SERVO_MAX_NB 3 /* 3 is the maximum for DigiSpark if DigiUSB is used in the skecth */
|
||||
#else
|
||||
#if (defined(__AVR_ATtiny84__) || defined(__AVR_ATtiny167__))
|
||||
#define SERVO_MAX_NB 6
|
||||
#else
|
||||
#define SERVO_MAX_NB 10
|
||||
#endif
|
||||
#endif
|
||||
#else
|
||||
#define SERVO_MAX_NB 3 /* 3 is the maximum for DigiSpark if DigiUSB is used in the skecth */
|
||||
#define SEQUENCE_MAX_NB 1 /* 1 is the maximum for DigiSpark if DigiUSB is used in the skecth */
|
||||
#define RC_CMD_MAX_NB 0
|
||||
#define SERVO_MAX_NB 0
|
||||
#endif
|
||||
|
||||
#if (defined(__AVR_ATtiny84__) || defined(__AVR_ATtiny85__) || defined(__AVR_ATtiny167__))
|
||||
#define SEQUENCE_MAX_NB 4 /* 2 is the maximum for DigiSpark if DigiUSB is used in the skecth */
|
||||
#define RC_CMD_MAX_NB 2
|
||||
#else
|
||||
#define SEQUENCE_MAX_NB 10
|
||||
#define RC_CMD_MAX_NB 4
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
@@ -122,7 +132,7 @@ typedef struct {
|
||||
#define MOTION_WITHOUT_SOFT_START_AND_STOP(ServoIndex,StartInDegrees,EndInDegrees,StartMvtOffsetMs,MvtDurationMs) \
|
||||
{ServoIndex, StartInDegrees, EndInDegrees, StartMvtOffsetMs, MvtDurationMs, NULL},
|
||||
|
||||
/* Macro to declare a short action (to use in "Sequence[]" structure table) */
|
||||
/* Macro to declare a short action (to be used in "Sequence[]" structure table) */
|
||||
#define SHORT_ACTION_TO_PERFORM(ShortAction, StartActionOffsetMs) {255, 0, 0, (StartActionOffsetMs), 0L, (ShortAction)},
|
||||
|
||||
enum {RC_CMD_STICK=0, RC_CMD_MULTI_POS_SW, RC_CMD_CUSTOM};
|
||||
@@ -138,20 +148,27 @@ uint8_t RcSeq_LibRevision(void);
|
||||
char *RcSeq_LibTextVersionRevision(void);
|
||||
#ifdef RC_SEQ_WITH_SOFT_RC_PULSE_OUT_SUPPORT
|
||||
void RcSeq_DeclareServo(uint8_t Idx, uint8_t DigitalPin);
|
||||
void RcSeq_ServoWrite(uint8_t Idx, uint16_t Angle);
|
||||
#endif
|
||||
#ifdef RC_SEQ_WITH_SOFT_RC_PULSE_IN_SUPPORT
|
||||
void RcSeq_DeclareSignal(uint8_t Idx, uint8_t DigitalPin);
|
||||
void RcSeq_DeclareKeyboardOrStickOrCustom(uint8_t ChIdx, uint8_t Type, uint16_t PulseMinUs, uint16_t PulseMaxUs, KeyMap_t *KeyMapTbl, uint8_t PosNb);
|
||||
void RcSeq_DeclareCustomKeyboard(uint8_t ChIdx, KeyMap_t *KeyMapTbl, uint8_t PosNb);
|
||||
boolean RcSeq_SignalTimeout(uint8_t Idx, uint8_t TimeoutMs, uint8_t *State);
|
||||
void RcSeq_DeclareKeyboardOrStickOrCustom(uint8_t ChIdx, uint8_t Type, uint16_t PulseMinUs, uint16_t PulseMaxUs, const KeyMap_t *KeyMapTbl, uint8_t PosNb);
|
||||
void RcSeq_DeclareCustomKeyboard(uint8_t ChIdx, const KeyMap_t *KeyMapTbl, uint8_t PosNb);
|
||||
#define RcSeq_DeclareStick(ChIdx, PulseMinUs, PulseMaxUs, PosNb) RcSeq_DeclareKeyboardOrStickOrCustom(ChIdx, RC_CMD_STICK, PulseMinUs, PulseMaxUs, NULL, PosNb)
|
||||
#define RcSeq_DeclareMultiPosSwitch(ChIdx, PulseMinUs, PulseMaxUs, PosNb) RcSeq_DeclareKeyboardOrStickOrCustom(ChIdx, RC_CMD_MULTI_POS_SW, PulseMinUs, PulseMaxUs, NULL, PosNb)
|
||||
#define RcSeq_DeclareKeyboard(ChIdx, PulseMinUs, PulseMaxUs, KeyNb) RcSeq_DeclareKeyboardOrStickOrCustom(ChIdx, RC_CMD_MULTI_POS_SW, PulseMinUs, PulseMaxUs, NULL, KeyNb)
|
||||
#ifdef RC_SEQ_WITH_SHORT_ACTION_SUPPORT
|
||||
void RcSeq_DeclareCommandAndShortAction(uint8_t CmdIdx,uint8_t TypeCmd,void(*ShortAction)(void));
|
||||
void RcSeq_DeclareCommandAndShortAction(uint8_t CmdIdx, uint8_t TypeCmd, void(*ShortAction)(void));
|
||||
#endif
|
||||
#endif
|
||||
void RcSeq_DeclareCommandAndSequence(uint8_t CmdIdx,uint8_t TypeCmd,SequenceSt_t *Table, uint8_t SequenceLength);
|
||||
uint8_t RcSeq_LaunchSequence(SequenceSt_t *Table);
|
||||
#ifdef RC_SEQ_CONTROL_SUPPORT
|
||||
void RcSeq_DeclareCommandAndSequence(uint8_t CmdIdx, uint8_t TypeCmd, const SequenceSt_t *Table, uint8_t SequenceLength, uint8_t(*Control)(uint8_t Action, uint8_t CmdSeqIdx));
|
||||
enum {RC_SEQ_START_CONDITION, RC_SEQ_END_OF_SEQ};
|
||||
#else
|
||||
void RcSeq_DeclareCommandAndSequence(uint8_t CmdIdx, uint8_t TypeCmd, const SequenceSt_t *Table, uint8_t SequenceLength);
|
||||
#endif
|
||||
uint8_t RcSeq_LaunchSequence(const SequenceSt_t *Table);
|
||||
#ifdef RC_SEQ_WITH_SHORT_ACTION_SUPPORT
|
||||
#define RcSeq_LaunchShortAction(ShortAction) if(ShortAction) ShortAction()
|
||||
#endif
|
||||
@@ -162,25 +179,28 @@ void RcSeq_Refresh(void);
|
||||
/*******************************************************/
|
||||
|
||||
/* Macro en Francais de declaration mouvement English native Macro to declare a motion */
|
||||
#define MVT_AVEC_DEBUT_ET_FIN_MVT_LENTS MOTION_WITH_SOFT_START_AND_STOP
|
||||
#define MVT_SANS_DEBUT_ET_FIN_MVT_LENTS MOTION_WITHOUT_SOFT_START_AND_STOP
|
||||
#define ACTION_COURTE_A_EFFECTUER SHORT_ACTION_TO_PERFORM
|
||||
#define MVT_AVEC_DEBUT_ET_FIN_MVT_LENTS MOTION_WITH_SOFT_START_AND_STOP
|
||||
#define MVT_SANS_DEBUT_ET_FIN_MVT_LENTS MOTION_WITHOUT_SOFT_START_AND_STOP
|
||||
#define ACTION_COURTE_A_EFFECTUER SHORT_ACTION_TO_PERFORM
|
||||
#ifdef RC_SEQ_WITH_SOFT_RC_PULSE_IN_SUPPORT
|
||||
#define RC_CLAVIER_MAISON RC_CUSTOM_KEYBOARD
|
||||
#define VALEUR_CENTRALE_US CENTER_VALUE_US
|
||||
#define RC_CLAVIER_MAISON RC_CUSTOM_KEYBOARD
|
||||
#define VALEUR_CENTRALE_US CENTER_VALUE_US
|
||||
#endif
|
||||
#ifdef RC_SEQ_CONTROL_SUPPORT
|
||||
#define RC_SEQ_CONDITION_DE_DEPART RC_SEQ_START_CONDITION
|
||||
#define RC_SEQ_FIN_DE_SEQ RC_SEQ_END_OF_SEQ
|
||||
#endif
|
||||
|
||||
/* Methodes en Francais English native methods */
|
||||
#ifdef RC_SEQ_WITH_SOFT_RC_PULSE_IN_SUPPORT
|
||||
#define RcSeq_DeclareManche RcSeq_DeclareStick
|
||||
#define RcSeq_DeclareClavier RcSeq_DeclareKeyboard
|
||||
#define RcSeq_DeclareClavierMaison RcSeq_DeclareCustomKeyboard
|
||||
#define RcSeq_DeclareInterMultiPos RcSeq_DeclareMultiPosSwitch
|
||||
#define RcSeq_DeclareCommandeEtActionCourte RcSeq_DeclareCommandAndShortAction
|
||||
#define RcSeq_DeclareManche RcSeq_DeclareStick
|
||||
#define RcSeq_DeclareClavier RcSeq_DeclareKeyboard
|
||||
#define RcSeq_DeclareClavierMaison RcSeq_DeclareCustomKeyboard
|
||||
#define RcSeq_DeclareInterMultiPos RcSeq_DeclareMultiPosSwitch
|
||||
#define RcSeq_DeclareCommandeEtActionCourte RcSeq_DeclareCommandAndShortAction
|
||||
#endif
|
||||
#define RcSeq_DeclareCommandeEtSequence RcSeq_DeclareCommandAndSequence
|
||||
#define RcSeq_LanceSequence RcSeq_LaunchSequence
|
||||
#define RcSeq_LanceActionCourte RcSeq_LaunchShortAction
|
||||
#define RcSeq_Rafraichit RcSeq_Refresh
|
||||
#define RcSeq_DeclareCommandeEtSequence RcSeq_DeclareCommandAndSequence
|
||||
#define RcSeq_LanceSequence RcSeq_LaunchSequence
|
||||
#define RcSeq_LanceActionCourte RcSeq_LaunchShortAction
|
||||
#define RcSeq_Rafraichit RcSeq_Refresh
|
||||
|
||||
#endif
|
||||
|
116
hardware/digistump/avr/libraries/DigisparkRcSeq/Readme.md
Normal file
116
hardware/digistump/avr/libraries/DigisparkRcSeq/Readme.md
Normal file
@@ -0,0 +1,116 @@
|
||||
RcSeq library
|
||||
=============
|
||||
|
||||
**RcSeq** is an asynchronous library for ATmega328P (**UNO**), ATmega2560 (**MEGA**), ATtiny84, ATtiny85 (**Digispark**) and ATtiny167 (**Digispark pro**) to easily create **servo's sequences** and/or to execute **short actions** from RC commands, from a digital input, or from a launch function called in the sketch.
|
||||
|
||||
The **A**pplication **P**rogramming **I**nterface (**API**) makes **RcSeq** library very easy to use.
|
||||
|
||||
Some definitions:
|
||||
----------------
|
||||
|
||||
* **Sequence**: is used to sequence one or several servos (sequence is defined in a structure in the user's sketch to be performed when the RC command rises). The Sequence table (structure) may contain some servo motions and some short actions to call at a predefined time. For each servo, start angle, end angle and speed are tunable.
|
||||
|
||||
* **Short Action**: is used to perform a quick action (action is a short function defined in the user's sketch to be called when the RC command rises). The duration must be less than 20ms to not disturb the servo commands.
|
||||
|
||||
Some examples of use cases:
|
||||
--------------------------
|
||||
* **A landing gear retract:**
|
||||
* Lock, door and leg servos sequenced with a single RC channel
|
||||
* from a predefined position of the stick on the transmitter
|
||||
* from the 2 positions "Aux Channel" of the transmitter
|
||||
|
||||
* **Navigation lights for aircraft:**
|
||||
* Anticollision, beacon, landing lights commanded:
|
||||
* from predefined positions of the stick on the transmitter
|
||||
* from push-buttons in place of the stick potentiometer
|
||||
|
||||
|
||||
* **Multi-switch:**
|
||||
* Up to 8 digital pins driven from a single RC channel
|
||||
* using the stick of the transmitter
|
||||
* using 8 push-buttons in place of the stick potentiometer
|
||||
|
||||
* **Zodiac animation:**
|
||||
* A pneumatic Zodiac dropped at sea and lifted back to the deck of a ship. Drop and lift sequences commanded:
|
||||
* from predefined positions of the stick on the transmitter
|
||||
* from a regular ON/OFF switch (for demo on table without RC set)
|
||||
|
||||
* **Animatronics sequences:**
|
||||
|
||||
* leg motion,
|
||||
* mouth motion,
|
||||
* eyes motion,
|
||||
* etc.
|
||||
|
||||
Triggers:
|
||||
--------
|
||||
|
||||
**Sequences** and **short actions** can be trigged by:
|
||||
|
||||
* a RC signal (eg: RC receiver output)
|
||||
|
||||
* from one or several **predefined positions of a stick** of the transmitter
|
||||
|
||||
* from one or several **push-button** (keyboard) replacing a a stick of the transmitter. (**RcSeq** assumes Push-Buttons associated Pulse duration are equidistant).
|
||||
|
||||
* from **Custom Keyboard** replacing a stick of the the transmitter. (The pulse durations can be defined independently for each Push-Button).
|
||||
|
||||
* from **Multi position switch** (2 pos switch, 3 pos switch, or more, eg. rotactor) replacing a stick of the the transmitter.
|
||||
|
||||
* a regular ON/OFF switch (no RC set required).
|
||||
|
||||
* a launch function call in the sketch.
|
||||
|
||||
API/methods:
|
||||
-----------
|
||||
* RcSeq_Init()
|
||||
* RcSeq_DeclareSignal()
|
||||
* RcSeq_DeclareStick()
|
||||
* RcSeq_DeclareKeyboard()
|
||||
* RcSeq_DeclareCustomKeyboard()
|
||||
* RcSeq_DeclareMultiPosSwitch()
|
||||
* RcSeq_SignalTimeout()
|
||||
* RcSeq_DeclareServo()
|
||||
* RcSeq_DeclareCommandAndSequence()
|
||||
* RcSeq_DeclareCommandAndShortAction()
|
||||
* RcSeq_LaunchSequence()
|
||||
* RcSeq_LaunchShortAction()
|
||||
* RcSeq_Refresh()
|
||||
* RcSeq_LibVersion()
|
||||
* RcSeq_LibRevision()
|
||||
* RcSeq_LibTextVersionRevision()
|
||||
|
||||
Macros and constants:
|
||||
--------------------
|
||||
* const SequenceSt_t
|
||||
* const KeyMap_t
|
||||
* RC_SEQUENCE()
|
||||
* RC_CUSTOM_KEYBOARD()
|
||||
* SHORT_ACTION_TO_PERFORM()
|
||||
* MOTION_WITH_SOFT_START_AND_STOP()
|
||||
* MOTION_WITHOUT_SOFT_START_AND_STOP()
|
||||
* CENTER_VALUE_US
|
||||
* RC_SEQ_START_CONDITION
|
||||
* RC_SEQ_END_OF_SEQ
|
||||
|
||||
Design considerations:
|
||||
---------------------
|
||||
|
||||
The **RcSeq** library requires 3 other libraries written by the same author:
|
||||
|
||||
1. **TinyPinChange**: a library to catch asynchronously the input change using Pin Change Interruption capability of the AVR microcontroller.
|
||||
|
||||
2. **SoftRcPulseIn**: a library to catch asynchronously the input pulses using **TinyPinChange** library.
|
||||
|
||||
3. **SoftRcPulseOut**: a library mainly based on the **SoftwareServo** library, but with a better pulse generation to limit jitter and with some other enhancements.
|
||||
|
||||
CAUTION:
|
||||
-------
|
||||
The end user shall also use asynchronous programmation method in the loop() function (no blocking functions such as delay() or pulseIn()).
|
||||
|
||||
Contact
|
||||
-------
|
||||
|
||||
If you have some ideas of enhancement, please contact me by clicking on: [RC Navy](http://p.loussouarn.free.fr/contact.html).
|
||||
|
||||
|
@@ -15,11 +15,13 @@ RcSeq_LibRevision KEYWORD2
|
||||
RcSeq_LibTextVersionRevision KEYWORD2
|
||||
RcSeq_Init KEYWORD2
|
||||
RcSeq_DeclareSignal KEYWORD2
|
||||
RcSeq_SignalTimeout KEYWORD2
|
||||
RcSeq_DeclareKeyboard KEYWORD2
|
||||
RcSeq_DeclareClavier KEYWORD2
|
||||
RcSeq_DeclareStick KEYWORD2
|
||||
RcSeq_DeclareManche KEYWORD2
|
||||
RcSeq_DeclareServo KEYWORD2
|
||||
RcSeq_ServoWrite KEYWORD2
|
||||
RcSeq_DeclareCustomKeyboard KEYWORD2
|
||||
RcSeq_DeclareClavierMaison KEYWORD2
|
||||
RcSeq_DeclareMultiPosSwitch KEYWORD2
|
||||
@@ -51,3 +53,8 @@ RC_CLAVIER_MAISON LITERAL1
|
||||
RC_SEQUENCE LITERAL1
|
||||
CENTER_VALUE_US LITERAL1
|
||||
VALEUR_CENTRALE_US LITERAL1
|
||||
RC_SEQ_START_CONDITION LITERAL1
|
||||
RC_SEQ_CONDITION_DE_DEPART LITERAL1
|
||||
RC_SEQ_END_OF_SEQ LITERAL1
|
||||
RC_SEQ_FIN_DE_SEQ LITERAL1
|
||||
|
||||
|
Reference in New Issue
Block a user