Skip to content

Commit

Permalink
Sandbox Refactor - AgFirmware.ino
Browse files Browse the repository at this point in the history
  • Loading branch information
TGit-Tech committed Aug 7, 2017
1 parent 4c5682e commit 457ce6a
Show file tree
Hide file tree
Showing 17 changed files with 971 additions and 1,456 deletions.
4 changes: 2 additions & 2 deletions PumpController/Firmware/PumpController/PumpController.ino
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
#include <PeerIOSerialControl.h> //See https://github.com/tgit23/PeerIOSerialControl
#include <SoftwareSerial.h>

#define TRANSCEIVER_ID 10 // Unique Transceiver ID for this Device (1-15)
#define TRANSCEIVER_ID 11 // Unique Transceiver ID for this Device (1-15)
#define XBEECONFIG 0 // 1 to enter XBEE Configuration Mode, 0 Normal Operation
#define DEBUG 0 // 1 for DEBUG

Expand All @@ -19,7 +19,7 @@
#define SS_RX_PIN 3 // XBee DOUT
#define PUMP_POWER_PIN 7 // Pump Power Pin ( Blue twisted pair )
#define PUMP_AUX_CONTACT 0 // Pump Power Aux Contact ( Green twisted pair ) 0-to deactivate
#define ULTRASONIC_PRESENT 1 // 1=UltraSonic Level Monitor Attached, 0=No UltraSonic
#define ULTRASONIC_PRESENT 0 // 1=UltraSonic Level Monitor Attached, 0=No UltraSonic
#define ULTRASONIC_TRIG_PIN 4 // UltraSonic Trigger Pin
#define ULTRASONIC_ECHO_PIN 5 // UltraSonic Echo Pin
#define ULTRASONIC_MAX_DIST 400 // Longest Distance to Measure
Expand Down
122 changes: 122 additions & 0 deletions Sandbox/AgFirmware/AgFirmware.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
/******************************************************************************************************************//**
* @file AgFirmware.ino
* @brief Arduino Sketch Firmware for the Devices of the AgIrrigationRemoteControl project
* @see https://github.com/tgit23/AgIrrigationRemoteControl
* @authors
* tgit23 8/2017 Original
**********************************************************************************************************************/
#include <LiquidCrystal.h>
#include "RemoteMenu.h"

//vvvvvvvvvvvvvvvvvv[[[ DEVICES ]]]vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
// Hand-Held Remote Units ( 1-5 )
// Smart-Controller Units with LCD ( 6-10 )
// Dumb-Controller Units without LCD ( 11-15 )
#define HAND_REMOTE 1
#define PUMP_CONTROLLER 6
#define GATE_CONTROLLER 11
#define CHEM_CONTROLLER 12
#define PIVOT_CONTROLLER 8
//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
//------------------------------------------------------------------------------------------
#define THISDEVICE HAND_REMOTE // The device this Firmware is for
#define XBEECONFIG 0 // Set to 1 to configure RF Radio through XCTU
#define RELEASE 20170706 // Release Version used to Build the Units
//------------------------------------------------------------------------------------------

#if THISDEVICE<11
//vvvvvvvvvvvvvvvvvv[[[ USER PIN DEFINITIONS ]]]vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
// PinTypes { INPIN, INPINHIGH, OUTPIN, BUZZPIN, SONICPIN, SETTABLE };
// |---- DEVICE-----|-PIN-||-PinType---|----NAME---|ID|-------------------
//------------------------------------------------------------------------------------------
PinPoint PumpPower ( PUMP_CONTROLLER, 7, SETTABLE, "Power", 'P' );
PinPoint WaterLevel ( PUMP_CONTROLLER, 64, SONICPIN, "Water", 'L' );
PinPoint GateLevel ( GATE_CONTROLLER, 6, SETTABLE, "Gate", 'G' );
PinPoint ChemPump ( CHEM_CONTROLLER, 7, OUTPIN, "Chem", 'C' );
PinPoint PivotOnOff ( PIVOT_CONTROLLER, 7, INPINHIGH, "Pivot", 'P' );

//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

// Hardware Pin Definitions
#if THISDEVICE<6 //----------------- Hand-Held Remote Units -------
LiquidCrystal LCD(8, 9, 4, 5, 6, 7);
PinPoint Battery ( HAND_REMOTE, A1, INPIN, "Battery", 'B' );
#if RELEASE<20170525
PinPoint Buzzer ( HAND_REMOTE, 2, BUZZPIN );
RemoteMenu Menu (12, 11, THISDEVICE, &LCD);
#else
PinPoint Buzzer ( HAND_REMOTE, 11, BUZZPIN );
RemoteMenu Menu (3, 2, THISDEVICE, &LCD);
#endif
#else //----------------- Smart-Controller with LCD -----
LiquidCrystal LCD(12, 13, 8, 9, 10, 11);
RemoteMenu Menu(3, 2, THISDEVICE, &LCD);
#endif

void setup() {
Serial.begin(9600);LCD.begin(16, 2);

//vvvvvvvvvvvvvvvvvv[[[ DEVICE NAMES ]]]vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
// Assign Display Names to the Devices
Menu.DeviceDisplayName(HAND_REMOTE, "Remote");
Menu.DeviceDisplayName(PUMP_CONTROLLER, "Pump");
Menu.DeviceDisplayName(GATE_CONTROLLER, "Gate");
Menu.DeviceDisplayName(CHEM_CONTROLLER, "Chem");
Menu.DeviceDisplayName(PIVOT_CONTROLLER, "Pivot");
//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

//vvvvvvvvvvvvvvvvvv[[[ PIN CONTROLS ]]]vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
//
// ControlTypes { SET_PIN, PID_SET, DIRECTLY, LESS_THAN, GREATER_THAN, EQUAL_TO, NOT_EQUAL_TO };
//----------------------- PIN --------- ControlType-------ID----|StorePin|-
#if THISDEVICE<6
Battery.Controls ( &Buzzer, LESS_THAN, 'b' );
Menu.AddPin(&Battery);
#endif
WaterLevel.Controls ( &GateLevel, PID_SET, 'g' );
PivotOnOff.Controls ( &ChemPump, DIRECTLY, 'e' );

//--------- Add Pins to the Display Menu --------------------
Menu.AddPin(&PumpPower);
Menu.AddPin(&WaterLevel);
Menu.AddPin(&GateLevel);
Menu.AddPin(&ChemPump);
Menu.StartDisplay(&PumpPower);
}

void loop() {
Menu.loop();
}


#else // THISDEVIC is (11-15)
//---------------------------------------------------------------------------------------------------------------------
// DUMB-CONTROLLER without LCD support or any local controls
//---------------------------------------------------------------------------------------------------------------------
SoftwareSerial IOSerial(3,2); // SoftSerial for XBEE ( rxPin, txPin )
PeerIOSerialControl XBee(THISDEVICEID,IOSerial,Serial);

void setup() {
pinMode(3, INPUT); // XBee DOUT Pin
pinMode(2, OUTPUT); // XBee DIN Pin
Serial.begin(9600);
IOSerial.begin(9600); // Start UART Communications with the XBee->Module
}

void loop(){

#if XBEECONFIG!=0
if ( IOSerial.available()>0 ) Serial.write(IOSerial.read()); // Forward Serial to XBEE for XBEE Config
if ( Serial.available()>0 ) IOSerial.write(Serial.read());
#else
XBee.Available(); // Check Communications
#if UTRASONIC_METER_INSTALLED==1 // Read UltraSonic water level if installed
int ulCurrentTime = millis();
if ( ulCurrentTime > ulLastPing + 1000 ) {
XBee.VirtualPin(64, sonar.ping_in() ); // Assign UltraSonic reading to Virt.Pin(64)
ulLastPing = ulCurrentTime;
}
#endif

#endif
#endif
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
* tgit23 1/2017 Original
******************************************************************************/
#include "PeerIOSerialControl.h"

#define ID_MASK 0x0F // Bytes[0] [0000 1111] ArduinoID ( 0-15 )
#define REPLY_BIT 4 // Bytes[0] [0001 0000] Reply-1, Send-0
#define RW_BIT 5 // Bytes[0] [0010 0000] Read-1, Write-0
Expand Down Expand Up @@ -82,9 +83,9 @@ void PeerIOSerialControl::Timeout(int milliseconds) {
int PeerIOSerialControl::Timeout() {
return BlockingTimeoutMS;
}
void PeerIOSerialControl::VirtualPin(int Pin, int Value, PinStatus _PinStatus = IsOff) {
void PeerIOSerialControl::VirtualPin(int Pin, int Value, PinStatus _PinStatus = OKAY) {
if ( Pin > 63 && Pin < 128 ) {
iVirtualPin[Pin-64] = Value = ((Value << 0) & 0x0FFF) + ((_PinStatus << 12) & 0x3000);
iVirtualPin[Pin-64] = ((Value << 0) & 0x0FFF) + ((_PinStatus << 12) & 0x3000);
}
}
int PeerIOSerialControl::VirtualPin(int Pin) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
#define READ 1
#define WRITE 0
#define VPIN_STATUS_ON
typedef enum PinStatus { IsOff = 0, IsOn = 1, IsWait = 2, IsErr = 3 };
typedef enum PinStatus { ISOFF = 0, ISON = 1, WAIT = 2, ERR = 3, OKAY = 4 };

/**********************************************************************************************//**
* @class PeerIOSerialControl
Expand Down Expand Up @@ -275,7 +275,7 @@ class PeerIOSerialControl {
* XBee.VirtualPin(70, 15200);
* @endcode
**************************************************************************************/
void VirtualPin(int Pin, int Value, PinStatus _PinStatus = IsOff);
void VirtualPin(int Pin, int Value, PinStatus _PinStatus = OKAY);

/***********************************************************************************//**
* @brief Gets the Value for one of the Analog Virtual Pins (i.e. 64-127)
Expand Down
212 changes: 212 additions & 0 deletions Sandbox/AgFirmware/PinPoint.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,212 @@
/******************************************************************************************************************//**
* @file PinPoint.cpp
* @brief Class definition for PinPoint used for I/O Control of a Pin on a Device
* @authors
* tgit23 8/2017 Original
**********************************************************************************************************************/
#include "PinPoint.h"
#include "UserControl.h"

PeerIOSerialControl *PinPoint::XBee = NULL;
uint8_t PinPoint::ThisDeviceID = 0;
unsigned int PinPoint::LastEpromOffset = 0;

/******************************************************************************************************************//**
* @brief Constructor
* @remarks
* - Raw values are still used behind the scene's only the displayed value is modified
* @code
* exmaple code
* @endcode
**********************************************************************************************************************/
PinPoint::PinPoint(uint8_t _Device, uint8_t _Pin, ePinType _PinType, char *_Name = NULL, char _ID = NULL ) {
Device = _Device; Pin = _Pin; PinType = _PinType; Name = _Name; ID = _ID;
if ( Pin <= A0 ) IsOnOff = true;
if ( PinType == SETTABLE ) FirstControl = new UserControl( this, SET_PIN, this, ID );
switch ( PinType ) {
case INPIN: pinMode(Pin,INPUT);break;
case INPINHIGH: pinMode(Pin,INPUT_PULLUP);break;
case OUTPIN: pinMode(Pin,OUTPUT);break;
case BUZZPIN: pinMode(Pin,OUTPUT);break;
case SONICPIN: break;
case SETTABLE: pinMode(Pin,OUTPUT);break;
}
}

/******************************************************************************************************************//**
* @brief Use a user-defined function in the main sketch to modify the raw value read from the arduino
* @remarks
* - Raw values are still used behind the scene's only the displayed value is modified
* @code
* APin.ReadValue();
* while ( APin.Status() == WAIT ) { // Loop Till Value is Retreived }
* GottenValue = APin.GetValue();
* @endcode
**********************************************************************************************************************/
void PinPoint::ReadValue(bool _ForceBlocking = false) {
DB(("PinPoint::ReadValue(Blocking="));DB((_ForceBlocking));DBL((")"));

mStatus = ERR; mPacketID = -1;
if ( Device > 16 || Pin > 127 ) return; // Value Check

if ( Device == ThisDeviceID ) { //--- Local Pin Read ---
DB(("LOCAL Get: Device="));DB((Device));DB((" Pin="));DBL((Pin));
if ( Pin >= A0 ) { mValue = analogRead(Pin); }
else { mValue = digitalRead(Pin); }
if ( mValue != -1 ) mStatus = OKAY;
}
else if ( _ForceBlocking ) {
DB(("REMOTE Get: Device="));DB((Device));DB((" Pin="));DBL((Pin));
if ( Device != XBee->TargetArduinoID() ) XBee->TargetArduinoID( Device ); //Set TransceiverID
if ( Pin >= A0 ) { mValue = XBee->analogReadB(Pin); }
else { mValue = XBee->digitalReadB(Pin); }
if ( mValue != -1 ) mStatus = OKAY;
}
else { //--- Remote Pin Read ---
DB(("REMOTE Get: Device="));DB((Device));DB((" Pin="));DBL((Pin));
if ( Device != XBee->TargetArduinoID() ) XBee->TargetArduinoID( Device ); //Set TransceiverID
mWaitStart = millis();
if ( Pin >= A0 ) { mPacketID = XBee->analogReadNB(Pin); }
else { mPacketID = XBee->digitalReadNB(Pin); }
mStatus = WAIT;
}
}

/******************************************************************************************************************//**
* @brief Checks XBee communications and returns 'true' if the pin Status has changed
* @remarks
* @code
* exmaple code
* @endcode
**********************************************************************************************************************/
bool PinPoint::UpdateAvailable() {
XBee->Available();
if ( mStatus == WAIT ) {
if ( mPacketID != -1 ) {
int Ret = XBee->GetReply(mPacketID);
if ( Ret != -1 ) {
mValue = Ret;
mStatus = OKAY;
return true;
}
}
if ( millis() - mWaitStart > XBee->Timeout() ) {
mPacketID = -1;
mStatus = ERR;
return true;
}
}
return false;
}

/******************************************************************************************************************//**
* @brief Use a user-defined function in the main sketch to modify the raw value read from the arduino
* @remarks
* - Raw values are still used behind the scene's only the displayed value is modified
* @code
* exmaple code
* @endcode
**********************************************************************************************************************/
PinStatus PinPoint::GetStatus() {
return mStatus;
}

/******************************************************************************************************************//**
* @brief Use a user-defined function in the main sketch to modify the raw value read from the arduino
* @remarks
* - Raw values are still used behind the scene's only the displayed value is modified
* @code
* exmaple code
* @endcode
**********************************************************************************************************************/
int PinPoint::GetRawValue() {
return mValue;
}

/******************************************************************************************************************//**
* @brief Use a user-defined function in the main sketch to modify the raw value read from the arduino
* @remarks
* - Raw values are still used behind the scene's only the displayed value is modified
* @code
* exmaple code
* @endcode
**********************************************************************************************************************/
int PinPoint::GetModifiedValue() {
if ( ValueModifierCallback == NULL ) return mValue;
return (*ValueModifierCallback)(mValue);
}

int PinPoint::ModifyValue(int _Value) {
if ( ValueModifierCallback == NULL ) return _Value;
return (*ValueModifierCallback)(_Value);
}
/******************************************************************************************************************//**
* @brief Use a user-defined function in the main sketch to modify the raw value read from the arduino
* @remarks
* - Raw values are still used behind the scene's only the displayed value is modified
* @code
* exmaple code
* @endcode
**********************************************************************************************************************/
void PinPoint::SetTo(unsigned int _Value, PinStatus _Status = OKAY) {
DB(("PinPoint::SetTo("));DB((Device));DBC;DB((Pin));DBC;DB((_Value));DBL((")"));

if ( Device > 16 || Pin > 127 ) return; // Value Check

// Drive Buzzer
if ( PinType == BUZZPIN ) {
if (_Value < 1) { noTone(Pin); }
else { tone(Pin, _Value); }
}

// Drive Local Pin
else if ( Device == ThisDeviceID ) { // Drive a LOCAL Pin
if ( Pin > 63 ) { XBee->VirtualPin(Pin, _Value, _Status); } // Drive a Virtual Pin
else {
if ( Pin >= A0 ) { analogWrite(Pin, _Value); }
else { digitalWrite(Pin, _Value); }
}
}

// Drive Remote Pin
else {
if ( XBee == NULL ) return;
if ( Device != XBee->TargetArduinoID() ) XBee->TargetArduinoID( Device );
if ( Pin >= A0 ) { XBee->analogWriteB(Pin, _Value); } // Set the Remote Arduino Analog Pin
else { XBee->digitalWriteB(Pin, _Value); } // Set the Remote Arduino Digital Pin
}
}

/******************************************************************************************************************//**
* @brief Use a user-defined function in the main sketch to modify the raw value read from the arduino
* @remarks
* - Raw values are still used behind the scene's only the displayed value is modified
* @code
* exmaple code
* @endcode
**********************************************************************************************************************/
void PinPoint::AttachValueModifier(int (*_ValueModifierCallback)(int)) {
ValueModifierCallback = _ValueModifierCallback;
}

/******************************************************************************************************************//**
* @brief Adds a 'UserControl' to the Controls Link-List
* @remarks
* @code
* exmaple code
* @endcode
**********************************************************************************************************************/
void PinPoint::Controls(PinPoint* _OutPin, eControlType _ControlType, char _ID, PinPoint* _StorePin = NULL) {
if ( FirstControl == NULL ) {
FirstControl = new UserControl( this, _ControlType, _OutPin, _ID, _StorePin );
LastEpromOffset = FirstControl->SetEpromOffset(LastEpromOffset);
} else {
UserControl *thisControl = FirstControl;
while ( thisControl->Next != NULL ) { thisControl = thisControl->Next; }
thisControl->Next = new UserControl( this, _ControlType, _OutPin, _ID, _StorePin );
LastEpromOffset = thisControl->Next->SetEpromOffset(LastEpromOffset);
thisControl->Next->Prev = thisControl;
}
}


Loading

0 comments on commit 457ce6a

Please sign in to comment.