first commit

This commit is contained in:
2021-05-11 20:43:42 +03:00
commit 9f3ffaba30
381 changed files with 69596 additions and 0 deletions

View File

@@ -0,0 +1,306 @@
/*******************************************************************************************************
Programs for Arduino - Copyright of the author Stuart Robinson - 16/12/19
This program is supplied as is, it is up to the user of the program to decide if the program is
suitable for the intended purpose and free from errors.
*******************************************************************************************************/
/*******************************************************************************************************
Program Operation - This program is a remote control transmitter. When one of four switches are made
(shorted to ground) a packet is transmitted with single byte indicating the state of Switch0 as bit 0,
Switch1 as bit 1 and Switch2 as bit 2. To prevent false triggering at the receiver the packet contains a
32 bit number called the TXIdentity which in this example is set to 1234554321. The receiver will only
act on, change the state of the outputs, if the identity set in the receiver matches that of the
transmitter. The chance of a false trigger is fairly remote.
Between switch presses the LoRa device and Atmel microcontroller are put to sleep. A switch press wakes
up the processor from sleep, the switches are read and a packet sent. On a 'bare bones' Arduino setup
the transmitter has a sleep current of approx 2.2uA, so it's ideal for a battery powered remote control
with a potential range of many kilometres.
The pin definitions, LoRa frequency and LoRa modem settings are in the Settings.h file. These settings
are not necessarily optimised for long range.
Serial monitor baud rate is set at 9600.
*******************************************************************************************************/
#include <SPI.h>
#include <SX127XLT.h>
#include "Settings.h"
#include <ProgramLT_Definitions.h>
#include <avr/wdt.h> //watchdog timer library, integral to Arduino IDE
#include <avr/sleep.h> //watchdog timer library, integral to Arduino IDE
#include "PinChangeInterrupt.h" //get the library here; https://github.com/NicoHood/PinChangeInterrupt
SX127XLT LT;
uint32_t TXpacketCount;
uint8_t TXPacketL;
volatile bool switch0flag = false;
volatile bool switch1flag = false;
volatile bool switch2flag = false;
volatile bool switch3flag = false;
void loop()
{
uint8_t switches;
digitalWrite(LED1, LOW); //turn off indicator LED
Serial.print(F("Sleeping zzzz"));
Serial.flush(); //make sure all serial output has gone
LT.setSleep(CONFIGURATION_RETENTION); //sleep LoRa device, keeping register settings in sleep.
sleep_permanent(); //sleep Atmel processor permanently for switch wakeup only
digitalWrite(LED1, HIGH);
Serial.println(F(" - Awake !!")); //the processor has woken up
switches = readSwitches(); //read the state of the switches
TXpacketCount++;
Serial.print(TXpacketCount); //print the numbers of sends
Serial.print(F(" Sending > "));
Serial.print(switches, BIN);
if (sendSwitchPacket(switches))
{
Serial.println(F(" SentOK"));
}
else
{
Serial.print(F("Send Error - IRQreg,"));
Serial.print(LT.readIrqStatus(), HEX);
}
Serial.println();
delay(500);
}
uint8_t sendSwitchPacket(uint8_t switches)
{
//The SX12XX buffer is filled with variables of a known type and in a known sequence. Make sure the
//receiver uses the same variable types and sequence to read variables out of the receive buffer.
uint8_t len;
LT.startWriteSXBuffer(0); //start the write packet to buffer process
LT.writeUint8(RControl1); //this byte identifies the type of packet
LT.writeUint32(TXIdentity); //this 32bit integer defines the Identity of the transmiter
LT.writeUint8(switches); //this byte contains the 8 switch values to be sent
len = LT.endWriteSXBuffer(); //close the packet, get the length of data to be sent
//now transmit the packet, 10 second timeout, and wait for it to complete sending
TXPacketL = LT.transmitSXBuffer(0, len, 10000, TXpower, WAIT_TX);
return TXPacketL; //TXPacketL will be 0 if there was an error sending
}
void sleep_permanent()
{
attachInterrupts();
ADCSRA = 0; //disable ADC
set_sleep_mode (SLEEP_MODE_PWR_DOWN);
noInterrupts (); //timed sequence follows
sleep_enable();
// turn off brown-out enable in software
MCUCR = bit (BODS) | bit (BODSE); //turn on brown-out enable select
MCUCR = bit (BODS); //this must be done within 4 clock cycles of above
interrupts (); //guarantees next instruction executed
sleep_cpu (); //sleep within 3 clock cycles of above
/* wake up here */
sleep_disable();
detachInterrupts();
}
void attachInterrupts()
{
if (SWITCH0 >= 0)
{
attachPCINT(digitalPinToPCINT(SWITCH0), wake0, FALLING);
switch0flag = false;
}
if (SWITCH1 >= 0)
{
attachPCINT(digitalPinToPCINT(SWITCH1), wake1, FALLING);
switch1flag = false;
}
if (SWITCH2 >= 0)
{
attachPCINT(digitalPinToPCINT(SWITCH2), wake2, FALLING);
switch2flag = false;
}
if (SWITCH3 >= 0)
{
attachPCINT(digitalPinToPCINT(SWITCH3), wake3, FALLING);
switch3flag = false;
}
}
void detachInterrupts()
{
if (SWITCH0 >= 0)
{
detachPCINT(digitalPinToPCINT(SWITCH0));
}
if (SWITCH1 >= 0)
{
detachPCINT(digitalPinToPCINT(SWITCH1));
}
if (SWITCH2 >= 0)
{
detachPCINT(digitalPinToPCINT(SWITCH2));
}
if (SWITCH3 >= 0)
{
detachPCINT(digitalPinToPCINT(SWITCH3));
}
}
void wake0()
{
switch0flag = true;
}
void wake1()
{
switch1flag = true;
}
void wake2()
{
switch2flag = true;
}
void wake3()
{
switch3flag = true;
}
uint8_t readSwitches()
{
uint8_t switchByte = 0xFF; //start assuming all switches off
if (switch0flag)
{
bitClear(switchByte, 0); //if the flag is set clear the bit
Serial.println(F("SWITCH0 pressed"));
}
if (switch1flag)
{
bitClear(switchByte, 1); //if the flag is set clear the bit
Serial.println(F("SWITCH1 pressed"));
}
if (switch2flag)
{
bitClear(switchByte, 2); //if the flag is set clear the bit
Serial.println(F("SWITCH2 pressed"));
}
if (switch3flag)
{
bitClear(switchByte, 3); //if the flag is set clear the bit
Serial.println(F("SWITCH3 pressed"));
}
return switchByte;
}
void led_Flash(uint16_t flashes, uint16_t delaymS)
{
uint16_t index;
for (index = 1; index <= flashes; index++)
{
digitalWrite(LED1, HIGH);
delay(delaymS);
digitalWrite(LED1, LOW);
delay(delaymS);
}
}
void setupSwitches()
{
if (SWITCH0 >= 0)
{
pinMode(SWITCH0, INPUT_PULLUP);
}
if (SWITCH1 >= 0)
{
pinMode(SWITCH1, INPUT_PULLUP);
}
if (SWITCH2 >= 0)
{
pinMode(SWITCH2, INPUT_PULLUP);
}
if (SWITCH3 >= 0)
{
pinMode(SWITCH3, INPUT_PULLUP);
}
}
void setup()
{
pinMode(LED1, OUTPUT);
led_Flash(2, 125);
setupSwitches();
Serial.begin(9600);
SPI.begin();
if (LT.begin(NSS, NRESET, DIO0, DIO1, DIO2, LORA_DEVICE))
{
led_Flash(2, 125);
}
else
{
Serial.println(F("Device error"));
while (1)
{
led_Flash(50, 50); //long fast speed flash indicates LoRa device error
}
}
LT.setupLoRa(Frequency, Offset, SpreadingFactor, Bandwidth, CodeRate, Optimisation);
Serial.println(F("Transmitter ready"));
Serial.println();
}

View File

@@ -0,0 +1,47 @@
/*******************************************************************************************************
Programs for Arduino - Copyright of the author Stuart Robinson - 16/12/19
This program is supplied as is, it is up to the user of the program to decide if the program is
suitable for the intended purpose and free from errors.
*******************************************************************************************************/
//******* Setup hardware pin definitions here ! ***************
//These are the pin definitions for one of my own boards, the Easy Pro Mini,
//be sure to change the definitiosn to match your own setup. Some pins such as DIO1,
//DIO2, may not be in used by this sketch so they do not need to be connected and
//should be set to -1.
const int8_t NSS = 10; //select on LoRa device
const int8_t NRESET = 9; //reset on LoRa device
const int8_t DIO0 = 3; //DIO0 on LoRa device, used for RX and TX done
const int8_t DIO1 = -1; //DIO1 on LoRa device, normally not used so set to -1
const int8_t DIO2 = -1; //DIO2 on LoRa device, normally not used so set to -1
const int8_t LED1 = 8; //On board LED, logic high is on
#define LORA_DEVICE DEVICE_SX1278 //this is the device we are using
const int8_t SWITCH0 = 2;
const int8_t SWITCH1 = 4;
const int8_t SWITCH2 = A3;
const int8_t SWITCH3 = A2;
const uint32_t TXIdentity = 1234554321; //define an identity number, the receiver must use the same number
//range is 0 to 4294967296
//******* Setup LoRa Test Parameters Here ! ***************
//LoRa Modem Parameters
const uint32_t Frequency = 434000000; //frequency of transmissions
const uint32_t Offset = 0; //offset frequency for calibration purposes
const uint8_t Bandwidth = LORA_BW_125; //LoRa bandwidth
const uint8_t SpreadingFactor = LORA_SF7; //LoRa spreading factor
const uint8_t CodeRate = LORA_CR_4_5; //LoRa coding rate
const uint8_t Optimisation = LDRO_AUTO; //low data rate optimisation setting
const int8_t TXpower = 10; //LoRa transmit power in dBm

View File

@@ -0,0 +1,297 @@
/*******************************************************************************************************
Programs for Arduino - Copyright of the author Stuart Robinson - 31/12/19
This program is supplied as is, it is up to the user of the program to decide if the program is
suitable for the intended purpose and free from errors.
*******************************************************************************************************/
/*******************************************************************************************************
Program Operation - This program is a remote control receiver. When a packet is received an 8 bit byte
(SwitchByte) is read and the four outputs (defined in Settings.h) are toggled according to the bits
set in this byte. If the Switch1 byte has bit 0 cleared, then OUTPUT0 is toggled. If the Switch1 byte
has bit 1 cleared, then OUTPUT1 is toggled. If the Switch1 byte has bit 2 cleared, then OUTPUT2 is toggled.
To prevent false triggering at the receiver the packet contains also contains a 32 bit number called the
TXIdentity which in this example is set to 1234554321. The receiver will only act on, change the state
of the outputs, if the identity set in the receiver matches that of the transmitter. The chance of a
false trigger is fairly remote.
The pin definitions, LoRa frequency and LoRa modem settings are in the Settings.h file.
Serial monitor baud rate is set at 9600.
*******************************************************************************************************/
#define programversion "V1.0"
#include <SPI.h>
#include <SX127XLT.h>
#include "Settings.h"
#include <ProgramLT_Definitions.h>
SX127XLT LT;
uint32_t RXpacketCount;
uint16_t errors;
uint8_t RXPacketL; //length of received packet
uint8_t RXPacketType; //type of received packet
int16_t PacketRSSI; //RSSI of received packet
int8_t PacketSNR; //signal to noise ratio of received packet
uint8_t SwitchByte = 0xFF; //this is the transmitted switch values, bit 0 = Switch0 etc
void loop()
{
RXPacketL = LT.receiveSXBuffer(0, 0, WAIT_RX); //returns 0 if packet error of some sort, no timeout
digitalWrite(LED1, HIGH); //something has happened
PacketRSSI = LT.readPacketRSSI(); //read the signal strength of the received packet
PacketSNR = LT.readPacketSNR(); //read the signal to noise ratio of the received packet
if (RXPacketL == 0)
{
packet_is_Error();
}
else
{
packet_is_OK();
}
digitalWrite(LED1, LOW);
Serial.println();
}
uint8_t packet_is_OK()
{
//packet has been received, now read from the SX12xx Buffer using the same variable type and
//order as the transmit side used.
uint32_t TXIdentity;
RXpacketCount++;
Serial.print(RXpacketCount);
Serial.print(F(" Packet Received"));
LT.startReadSXBuffer(0); //start buffer read at location 0
RXPacketType = LT.readUint8(); //read in the packet type
TXIdentity = LT.readUint32(); //read in the identity of transmitter
SwitchByte = LT.readUint8(); //read in the Switch values
RXPacketL = LT.endReadSXBuffer(); //finish buffer read
printpacketDetails();
if (RXPacketType != RControl1)
{
Serial.print(F(" Wrong packet type"));
led_Flash(5, 25); //short fast speed flash indicates wrong packet type
return 0;
}
if (TXIdentity != RXIdentity)
{
Serial.print(F(" Transmitter "));
Serial.print(TXIdentity);
Serial.print(F(" not recognised"));
led_Flash(5, 25); //short fast speed flash indicates transmitter not recognised
return 0;
}
if (LT.readRXPacketL() != 6)
{
Serial.print(F(" Wrong Packet Length"));
led_Flash(5, 25); //short fast speed flash indicates transmitter not recognised
return 0;
}
//if we get to here, then the packet is valid so switch outputs accordingly
if (BUZZER >= 0)
{
digitalWrite(BUZZER, HIGH);
}
Serial.print(F(",SwitchByte Received "));
Serial.print(SwitchByte, BIN); //print switch values in binary, if a bit is 0, that switch is active
actionOutputs(SwitchByte);
if (BUZZER >= 0)
{
digitalWrite(BUZZER, LOW);
}
return RXPacketL;
}
void packet_is_Error()
{
uint16_t IRQStatus;
IRQStatus = LT.readIrqStatus();
if (IRQStatus & IRQ_RX_TIMEOUT)
{
Serial.print(F("RXTimeout"));
}
else
{
errors++;
Serial.print(F("PacketError"));
printpacketDetails();
Serial.print(F("IRQreg,"));
Serial.print(IRQStatus, HEX);
}
}
void printpacketDetails()
{
Serial.print(F(" RSSI,"));
Serial.print(PacketRSSI);
Serial.print(F("dBm,SNR,"));
Serial.print(PacketSNR);
Serial.print(F("dB,Length,"));
Serial.print(LT.readRXPacketL());
}
void led_Flash(uint16_t flashes, uint16_t delaymS)
{
uint16_t index;
for (index = 1; index <= flashes; index++)
{
digitalWrite(LED1, HIGH);
delay(delaymS);
digitalWrite(LED1, LOW);
delay(delaymS);
}
}
void actionOutputs(uint8_t switches)
{
//read the recreived switch byte and toggle outputs as required
if (!bitRead(switches, 0))
{
//toggle Output state
digitalWrite(OUTPUT0, !digitalRead(OUTPUT0)); //toggle Output state
}
if (!bitRead(switches, 1))
{
digitalWrite(OUTPUT1, !digitalRead(OUTPUT1)); //toggle Output state
}
if (!bitRead(switches, 2))
{
digitalWrite(OUTPUT2, !digitalRead(OUTPUT2)); //toggle Output state
}
if (!bitRead(switches, 3))
{
digitalWrite(OUTPUT3, !digitalRead(OUTPUT3)); //toggle Output state
}
}
void setupOutputs()
{
//configure the output pins, if a pin is defiend in 'Settings.h' as -1, its not configured, so stays as input
if (OUTPUT0 >= 0)
{
pinMode(OUTPUT0, OUTPUT);
}
if (OUTPUT1 >= 0)
{
pinMode(OUTPUT1, OUTPUT);
}
if (OUTPUT2 >= 0)
{
pinMode(OUTPUT2, OUTPUT);
}
if (OUTPUT3 >= 0)
{
pinMode(OUTPUT3, OUTPUT);
}
if (BUZZER >= 0)
{
pinMode(BUZZER, OUTPUT);
}
}
void outputCheck(uint8_t number, uint32_t ondelaymS, uint32_t offdelaymS)
{
uint8_t index;
Serial.println(F("Toggling outputs"));
for (index = 1; index <= number; index++)
{
digitalWrite(OUTPUT0, HIGH);
delay(ondelaymS);
digitalWrite(OUTPUT0, LOW);
delay(offdelaymS);
digitalWrite(OUTPUT1, HIGH);
delay(ondelaymS);
digitalWrite(OUTPUT1, LOW);
delay(offdelaymS);
digitalWrite(OUTPUT2, HIGH);
delay(ondelaymS);
digitalWrite(OUTPUT2, LOW);
delay(offdelaymS);
digitalWrite(OUTPUT3, HIGH);
delay(offdelaymS);
digitalWrite(OUTPUT3, LOW);
delay(offdelaymS);
digitalWrite(BUZZER, HIGH);
delay(offdelaymS);
digitalWrite(BUZZER, LOW);
delay(offdelaymS);
}
}
void setup()
{
pinMode(LED1, OUTPUT);
led_Flash(2, 125);
Serial.begin(9600);
setupOutputs();
outputCheck(3, 500, 100);
SPI.begin();
if (LT.begin(NSS, NRESET, DIO0, DIO1, DIO2, LORA_DEVICE))
{
led_Flash(2, 125);
}
else
{
Serial.println(F("Device error"));
while (1)
{
led_Flash(50, 50); //long fast speed flash indicates device error
}
}
LT.setupLoRa(Frequency, Offset, SpreadingFactor, Bandwidth, CodeRate, Optimisation);
Serial.println(F("Receiver ready"));
}

View File

@@ -0,0 +1,44 @@
/*******************************************************************************************************
Programs for Arduino - Copyright of the author Stuart Robinson - 31/12/19
This program is supplied as is, it is up to the user of the program to decide if the program is
suitable for the intended purpose and free from errors.
*******************************************************************************************************/
//******* Setup hardware pin definitions here ! ***************
//These are the pin definitions for one of my own boards, the Easy Pro Mini,
//be sure to change the definitiosn to match your own setup. Some pins such as DIO1,
//DIO2, may not be in used by this sketch so they do not need to be connected and
//should be set to -1.
const int8_t NSS = 10; //select on LoRa device
const int8_t NRESET = 9; //reset on LoRa device
const int8_t DIO0 = 3; //DIO0 on LoRa device, used for RX and TX done
const int8_t DIO1 = -1; //DIO1 on LoRa device, normally not used so set to -1
const int8_t DIO2 = -1; //DIO2 on LoRa device, normally not used so set to -1
const int8_t LED1 = 8; //On board LED, logic high is on
const int8_t BUZZER = A5; //buzzer if fitted, set to -1 if not
#define LORA_DEVICE DEVICE_SX1278 //this is the device we are using
const int8_t OUTPUT0 = 2;
const int8_t OUTPUT1 = 4;
const int8_t OUTPUT2 = A3;
const int8_t OUTPUT3 = A2;
const uint32_t RXIdentity = 1234554321; //define an identity number, the receiver must use the same number
//range is 0 to 4294967296
//******* Setup LoRa Test Parameters Here ! ***************
//LoRa Modem Parameters
const uint32_t Frequency = 434000000; //frequency of transmissions
const uint32_t Offset = 0; //offset frequency for calibration purposes
const uint8_t Bandwidth = LORA_BW_125; //LoRa bandwidth
const uint8_t SpreadingFactor = LORA_SF7; //LoRa spreading factor
const uint8_t CodeRate = LORA_CR_4_5; //LoRa coding rate
const uint8_t Optimisation = LDRO_AUTO; //low data rate optimisation setting

View File

@@ -0,0 +1,229 @@
/*******************************************************************************************************
Programs for Arduino - Copyright of the author Stuart Robinson - 30/12/19
This program is supplied as is, it is up to the user of the program to decide if the program is
suitable for the intended purpose and free from errors.
*******************************************************************************************************/
/*******************************************************************************************************
Program Operation - This is a remote control transmitter that uses a LoRa link to transmit the positions
from a simple joystick to a remote receiver. The receiver uses the sent joystick positions to adjust the
positions of servos. The postions of the joysticks potentiometers on the transmitter are read with the
analogueRead() function.
If the joystick has a switch, often made by pressing on the joystick, then this can be used to remote
control an output on the receiver. The switch is read by an interrupt, the interrupt routine sets a flag
byte which is read in loop().
The program is intended as a proof of concept demonstration of how to remote control servos, the program
is not designed as a practical remote control device for RC model cars for instance.
It would be straight forward to make the transmitter program send packets continuously, but in most places
in the world that would break a normal limitation of 10% duty cycle for unlicensed use. Therefore the
program was designed to only transmit at a 10% duty cycle. Thus the fastest (lowest air time) packets are
used, spreading factor 6 at a bandwidth of 500khz. This results in an air time for the 5 byte control
packet of around 4mS, so there are around 25 sent per second.
To have the transmitter program print out the values read from the joystick, comment in the line;
//#define DEBUG
Which is just above the loop() function. With the DEBUG enabled the transmission rate, the rate at which
the control packets are transmitted will be slowed down.
To reduce the risk of the receiver picking up LoRa packets from other sources, the packet sent contains a
'TXidentity' number, valid values are 0 - 65535. The receiver must be setup with the matching identity
number or the received packets will be ignored.
The pin definitions, LoRa frequency and LoRa modem settings are in the Settings.h file. These settings
are not necessarily optimised for long range.
Serial monitor baud rate is set at 115200.
*******************************************************************************************************/
#include <SPI.h>
#include <SX127XLT.h>
#include "Settings.h"
#include <ProgramLT_Definitions.h>
SX127XLT LT;
#include "PinChangeInterrupt.h" //get the library here; https://github.com/NicoHood/PinChangeInterrupt
uint32_t TXpacketCount;
uint8_t TXPacketL;
uint8_t joystickX1value; //variable to read the value from the analog pin
uint8_t joystickY1value; //variable to read the value from the analog pin
volatile bool switch1flag = false;
//#define DEBUG //comment in thie line (remove the two // at the beggining) for debug output
void loop()
{
uint8_t switchByte = 0xFF;
joystickX1value = (uint8_t) (analogRead(joystickX1) / 4) ; //read the joystick X1 pot, turn 0-1023 into 0 to 255
joystickY1value = (uint8_t) (analogRead(joystickY1) / 4); //read the joystick Y1 pot
if (switch1flag)
{
bitClear(switchByte, 1); //if the switch is down clear the bit
digitalWrite(LED1, HIGH); //turn on LED as switch indicator
switch1flag = false;
}
if (!sendJoystickPacket(joystickX1value, joystickY1value, switchByte))
{
Serial.print(F("Send Error - IRQreg,"));
Serial.print(LT.readIrqStatus(), HEX);
}
}
uint8_t sendJoystickPacket(uint16_t X1value, uint16_t Y1value, uint8_t switches)
{
//The SX12XX buffer is filled with variables of a known type and in a known sequence. Make sure the
//receiver uses the same variable types and sequence to read variables out of the receive buffer.
//uint8_t len;
uint32_t packetStartmS, packettimemS;
LT.startWriteSXBuffer(0); //start the write packet to buffer process
LT.writeUint8(RControl1); //this is the packet type
LT.writeUint8(TXIdentity); //this value represents the transmitter number
LT.writeUint8(X1value); //this byte contains joystick pot AD X1 value to be sent
LT.writeUint8(Y1value); //this byte contains joystick pot AD Y1 value to be sent
LT.writeUint8(switches); //switches value
LT.endWriteSXBuffer(); //close the packet, thee are 5 bytes to send
//now transmit the packet, 10 second timeout, and wait for it to complete sending
packetStartmS = millis();
TXPacketL = LT.transmitSXBuffer(0, PacketLength, 10000, TXpower, WAIT_TX);
packettimemS = millis() - packetStartmS;
#ifdef DEBUG
Serial.print(TXIdentity);
Serial.print(F(",X1,"));
Serial.print(joystickX1value);
Serial.print(F(",Y1,"));
Serial.print(joystickY1value);
Serial.print(F(","));
Serial.print(switches, BIN);
Serial.print(F(","));
Serial.print(packettimemS);
Serial.print(F("mS"));
Serial.println();
#endif
digitalWrite(LED1, LOW); //LED off, may have been on due to switch press
delay(packettimemS * 9); //delay for 9 times packet transmit time to ensure 10% duty cycle
return TXPacketL; //TXPacketL will be 0 if there was an error sending
}
void led_Flash(uint16_t flashes, uint16_t delaymS)
{
uint16_t index;
for (index = 1; index <= flashes; index++)
{
digitalWrite(LED1, HIGH);
delay(delaymS);
digitalWrite(LED1, LOW);
delay(delaymS);
}
}
void attachInterrupts()
{
if (SWITCH1 >= 0)
{
attachPCINT(digitalPinToPCINT(SWITCH1), wake1, FALLING);
switch1flag = false;
}
}
void detachInterrupts()
{
if (SWITCH1 >= 0)
{
detachPCINT(digitalPinToPCINT(SWITCH1));
}
}
void wake1()
{
switch1flag = true;
}
void setupSwitches()
{
if (SWITCH1 >= 0)
{
pinMode(SWITCH1, INPUT_PULLUP);
}
}
void setupLoRa()
{
//this setup is used so as the implicit packet type,LORA_PACKET_FIXED_LENGTH, is used
LT.setMode(MODE_STDBY_RC); //got to standby mode to configure device
LT.setPacketType(PACKET_TYPE_LORA); //set for LoRa transmissions
LT.setRfFrequency(Frequency, Offset); //set the operating frequency
LT.calibrateImage(0); //run calibration after setting frequency
LT.setModulationParams(SpreadingFactor, Bandwidth, CodeRate, LDRO_AUTO); //set LoRa modem parameters
LT.setBufferBaseAddress(0x00, 0x00); //where in the SX buffer packets start, TX and RX
LT.setPacketParams(8, LORA_PACKET_FIXED_LENGTH, PacketLength, LORA_CRC_ON, LORA_IQ_NORMAL); //set packet parameters
LT.setSyncWord(LORA_MAC_PRIVATE_SYNCWORD); //syncword, LORA_MAC_PRIVATE_SYNCWORD = 0x12, or LORA_MAC_PUBLIC_SYNCWORD = 0x34
LT.setHighSensitivity(); //set for highest sensitivity at expense of slightly higher LNA current
//This is the typical IRQ parameters set, actually excecuted in the transmit function
LT.setDioIrqParams(IRQ_RADIO_ALL, IRQ_TX_DONE, 0, 0); //set for IRQ on TX done
}
void setup()
{
pinMode(LED1, OUTPUT);
led_Flash(2, 125);
setupSwitches();
Serial.begin(115200);
SPI.begin();
if (LT.begin(NSS, NRESET, DIO0, DIO1, DIO2, LORA_DEVICE))
{
led_Flash(2, 125);
}
else
{
Serial.println(F("Device error"));
while (1)
{
led_Flash(50, 50);
}
}
//this function call sets up the device for LoRa using the settings from the Settings.h file
setupLoRa();
attachInterrupts();
Serial.println();
LT.printModemSettings(); //reads and prints the configured LoRa settings, useful check
Serial.println();
LT.printOperatingSettings(); //reads and prints the configured operating settings, useful check
Serial.println();
Serial.println(F("35_Remote_Control_Servo_Transmitter ready"));
Serial.println();
}

View File

@@ -0,0 +1,47 @@
/*******************************************************************************************************
Programs for Arduino - Copyright of the author Stuart Robinson - 16/12/19
This program is supplied as is, it is up to the user of the program to decide if the program is
suitable for the intended purpose and free from errors.
*******************************************************************************************************/
//******* Setup hardware pin definitions here ! ***************
//These are the pin definitions for one of my own boards, the Easy Pro Mini,
//be sure to change the definitiosn to match your own setup. Some pins such as DIO1,
//DIO2, may not be in used by this sketch so they do not need to be connected and
//should be set to -1.
const int8_t NSS = 10; //select on LoRa device
const int8_t NRESET = 9; //reset on LoRa device
const int8_t DIO0 = 3; //DIO0 on LoRa device, used for RX and TX done
const int8_t DIO1 = -1; //DIO1 on LoRa device, normally not used so set to -1
const int8_t DIO2 = -1; //DIO2 on LoRa device, normally not used so set to -1
const int8_t LED1 = 8; //On board LED, logic high is on
#define LORA_DEVICE DEVICE_SX1278 //this is the device we are using
const int8_t joystickX1 = A2; //analog pin for the joystick 1 X pot
const int8_t joystickY1 = A3; //analog pin for the joystick 1 Y pot
const int8_t SWITCH1 = 2; //switch on joystick, set to -1 if not used
const uint32_t TXIdentity = 123 ; //define a transmitter number, the receiver must use the same number
//range is 0 to 255
//******* Setup LoRa Test Parameters Here ! ***************
//LoRa Modem Parameters
const uint32_t Frequency = 434000000; //frequency of transmissions
const uint32_t Offset = 0; //offset frequency for calibration purposes
const uint8_t Bandwidth = LORA_BW_500; //LoRa bandwidth
const uint8_t SpreadingFactor = LORA_SF6; //LoRa spreading factor
const uint8_t CodeRate = LORA_CR_4_5; //LoRa coding rate
const uint8_t Optimisation = LDRO_AUTO; //low data rate optimisation setting
const uint8_t PacketLength = 5; //packet length is fixed
const int8_t TXpower = 10; //LoRa transmit power in dBm

View File

@@ -0,0 +1,275 @@
/*******************************************************************************************************
Programs for Arduino - Copyright of the author Stuart Robinson - 30/12/19
This program is supplied as is, it is up to the user of the program to decide if the program is
suitable for the intended purpose and free from errors.
*******************************************************************************************************/
/*******************************************************************************************************
Program Operation - This is a remote control receiver that uses a LoRa link to control the positions of
servos sent from a remote transmitter.
If the ttransmitter joystick has a switch, often made by pressing on the joystick, then this can be used
to remote control an output on the receiver.
The program is intended as a proof of concept demonstration of how to remote control servos, the program
is not designed as a practical remote control device for RC model cars for instance.
It would be straight forward to make the transmitter program send packets continuously, but in most places
in the world that would break a normal limitation of 10% duty cycle for unlicensed use. Therefore the
program was designed to only transmit at a 10% duty cycle. Thus the fastest (lowest air time) packets are
used, spreading factor 6 at a bandwidth of 500khz. This results in an air time for the 5 byte control
packet of around 4mS, so there are around 25 sent per second.
To have the receiver program print out the joystick values (0-255) read from the received packet, comment
in the line;
//#define DEBUG
Which is just above the loop() function. With the DEBUG enabled then there is a possibility that some
transmitted packets will be missed. With the DEBUG line enabled to servos should also sweep to and fro 3
times at program start-up.
To reduce the risk of the receiver picking up LoRa packets from other sources, the packet sent contains a
'TXidentity' number, valid values are 0 - 255. The receiver must be setup with the matching RXIdentity
number in Settings.h or the received packets will be ignored.
The pin definitions, LoRa frequency and LoRa modem settings are in the Settings.h file. These settings
are not necessarily optimised for long range.
Serial monitor baud rate is set at 115200.
*******************************************************************************************************/
#define programversion "V1.0"
#include <SPI.h>
#include <SX127XLT.h>
#include "Settings.h"
#include <ProgramLT_Definitions.h>
SX127XLT LT;
#include <Servo.h>
Servo ServoX1; //create the servo object
Servo ServoY1; //create the servo object
uint8_t joystickX1value; //variable to read the value from the analog pin
uint8_t joystickY1value; //variable to read the value from the analog pin
uint8_t RXPacketL; //length of received packet
uint8_t RXPacketType; //type of received packet
//#define DEBUG
void loop()
{
RXPacketL = LT.receiveSXBuffer(0, 0, WAIT_RX); //returns 0 if packet error of some sort
while (!digitalRead(DIO0)); //wait for DIO0 to go high
if ( LT.readIrqStatus() == (IRQ_RX_DONE + IRQ_HEADER_VALID))
{
packet_is_OK();
}
else
{
packet_is_Error();
}
}
uint8_t packet_is_OK()
{
//packet has been received, now read from the SX12xx Buffer using the same variable type and
//order as the transmit side used.
uint8_t TXIdentity;
uint16_t pulseX1, pulseY1;
uint8_t switchByte = 0xFF; //this is the transmitted switch values, bit 0 = Switch0 etc
LT.startReadSXBuffer(0); //start buffer read at location 0
RXPacketType = LT.readUint8(); //read in the packet type
TXIdentity = LT.readUint8(); //read in the transmitter number
joystickX1value = LT.readUint8(); //this byte contains joystick pot AD X1 value sent
joystickY1value = LT.readUint8(); //this byte contains joystick pot AD Y1 value sent
switchByte = LT.readUint8(); //read in the Switch values
RXPacketL = LT.endReadSXBuffer(); //end buffer read
#ifdef DEBUG
Serial.print(TXIdentity);
Serial.print(F(",X1,"));
Serial.print(joystickX1value);
Serial.print(F(",Y1,"));
Serial.print(joystickY1value);
Serial.print(F(","));
Serial.print(switchByte, BIN);
Serial.println();
#endif
if (RXPacketType != RControl1)
{
Serial.print(F("Packet type "));
Serial.println(RXPacketType);
led_Flash(5, 25); //short fast speed flash indicates wrong packet type
return 0;
}
if (TXIdentity != RXIdentity)
{
Serial.print(F("TX"));
Serial.print(TXIdentity);
Serial.println(F("?"));
return 0;
}
//actionServos
pulseX1 = map(joystickX1value, 0, 255, 1000, 2000); //scale the numbers from the joystick
ServoX1.writeMicroseconds(pulseX1);
pulseY1 = map(joystickY1value, 0, 255, 1000, 2000); //scale the numbers from the joystick
ServoY1.writeMicroseconds(pulseY1); //move the servo to position
//actionOutputs
if (!bitRead(switchByte, 1))
{
digitalWrite(OUTPUT1, !digitalRead(OUTPUT1)); //Toggle Output state
}
return RXPacketL;
}
void packet_is_Error()
{
uint16_t IRQStatus;
int16_t PacketRSSI;
IRQStatus = LT.readIrqStatus();
if (IRQStatus & IRQ_RX_TIMEOUT)
{
Serial.print(F("RXTimeout"));
}
else
{
PacketRSSI = LT.readPacketRSSI(); //read the signal strength of the received packet
Serial.print(F("Err,"));
Serial.print(PacketRSSI);
Serial.print(F("dBm"));
}
Serial.println();
}
void setupOutputs()
{
//configure the output pins, if a pin is defiend in 'Settings.h' as -1, its not configured, so stays as input
if (OUTPUT1 >= 0)
{
pinMode(OUTPUT1, OUTPUT);
}
}
void led_Flash(uint16_t flashes, uint16_t delaymS)
{
uint16_t index;
for (index = 1; index <= flashes; index++)
{
digitalWrite(LED1, HIGH);
delay(delaymS);
digitalWrite(LED1, LOW);
delay(delaymS);
}
}
void sweepTest(uint8_t num)
{
uint16_t index1, index2;
for (index1 = 1; index1 <= num; index1++)
{
for (index2 = 900; index2 <= 2100; index2++)
{
ServoX1.writeMicroseconds(index2);
ServoY1.writeMicroseconds(index2);
}
delay(1000);
for (index2 = 2100; index2 >= 900; index2--)
{
ServoX1.writeMicroseconds(index2);
ServoY1.writeMicroseconds(index2);
}
delay(1000);
}
}
void setupLoRa()
{
//this setup is used so as the implicit packet type,LORA_PACKET_FIXED_LENGTH, is used
LT.setMode(MODE_STDBY_RC); //got to standby mode to configure device
LT.setPacketType(PACKET_TYPE_LORA); //set for LoRa transmissions
LT.setRfFrequency(Frequency, Offset); //set the operating frequency
LT.calibrateImage(0); //run calibration after setting frequency
LT.setModulationParams(SpreadingFactor, Bandwidth, CodeRate, LDRO_AUTO); //set LoRa modem parameters
LT.setBufferBaseAddress(0x00, 0x00); //where in the SX buffer packets start, TX and RX
LT.setPacketParams(8, LORA_PACKET_FIXED_LENGTH, PacketLength, LORA_CRC_ON, LORA_IQ_NORMAL); //set packet parameters
LT.setSyncWord(LORA_MAC_PRIVATE_SYNCWORD); //syncword, LORA_MAC_PRIVATE_SYNCWORD = 0x12, or LORA_MAC_PUBLIC_SYNCWORD = 0x34
LT.setHighSensitivity(); //set for highest sensitivity at expense of slightly higher LNA current
//This is the typical IRQ parameters set, actually excecuted in the transmit function
LT.setDioIrqParams(IRQ_RADIO_ALL, IRQ_TX_DONE, 0, 0); //set for IRQ on TX done
}
void setup()
{
pinMode(LED1, OUTPUT);
led_Flash(2, 125);
setupOutputs();
Serial.begin(115200);
ServoX1.attach(pinservoX1); //connect pin pinservoX1 to ServoX1 object
ServoY1.attach(pinservoY1); //connect pin pinservoY1 to ServoY1 object
#ifdef DEBUG
Serial.println(F("Servo sweep test"));
sweepTest(3);
#endif
SPI.begin();
if (LT.begin(NSS, NRESET, DIO0, DIO1, DIO2, LORA_DEVICE))
{
led_Flash(2, 125);
}
else
{
Serial.println(F("Device error"));
while (1)
{
led_Flash(50, 50); //long fast speed flash indicates device error
}
}
//this function call sets up the device for LoRa using the settings from the Settings.h file
setupLoRa();
Serial.println();
LT.printModemSettings(); //reads and prints the configured LoRa settings, useful check
Serial.println();
LT.printOperatingSettings(); //reads and prints the configured operating settings, useful check
Serial.println();
Serial.println(F("36_Remote_Control_Servo_Receiver ready"));
Serial.println();
}

View File

@@ -0,0 +1,43 @@
/*******************************************************************************************************
Programs for Arduino - Copyright of the author Stuart Robinson - 02/12/19
This program is supplied as is, it is up to the user of the program to decide if the program is
suitable for the intended purpose and free from errors.
*******************************************************************************************************/
//******* Setup hardware pin definitions here ! ***************
//These are the pin definitions for one of my own boards, the Easy Pro Mini,
//be sure to change the definitiosn to match your own setup. Some pins such as DIO1,
//DIO2, may not be in used by this sketch so they do not need to be connected and
//should be set to -1.
const int8_t NSS = 10; //select on LoRa device
const int8_t NRESET = 9; //reset on LoRa device
const int8_t DIO0 = 3; //DIO0 on LoRa device, used for RX and TX done
const int8_t DIO1 = -1; //DIO1 on LoRa device, normally not used so set to -1
const int8_t DIO2 = -1; //DIO2 on LoRa device, normally not used so set to -1
const int8_t LED1 = 8; //On board LED, logic high is on
#define LORA_DEVICE DEVICE_SX1278 //this is the device we are using
const int8_t pinservoX1 = 2; //pin for controlling servo X1
const int8_t pinservoY1 = 4; //pin for controlling servo Y1
const int8_t OUTPUT1 = 8; //this output toggles when joystick switch is pressed on receiver
const uint16_t RXIdentity = 123; //define a receiver number, the transmitter must use the same number
//range is 0 to 255
//******* Setup LoRa Test Parameters Here ! ***************
//LoRa Modem Parameters
const uint32_t Frequency = 434000000; //frequency of transmissions
const uint32_t Offset = 0; //offset frequency for calibration purposes
const uint8_t Bandwidth = LORA_BW_500; //LoRa bandwidth
const uint8_t SpreadingFactor = LORA_SF6; //LoRa spreading factor
const uint8_t CodeRate = LORA_CR_4_5; //LoRa coding rate
const uint8_t Optimisation = LDRO_AUTO; //low data rate optimisation setting
const uint8_t PacketLength = 5; //packet length is fixed

View File

@@ -0,0 +1,127 @@
/*******************************************************************************************************
Programs for Arduino - Copyright of the author Stuart Robinson - 19/09/20
This program is supplied as is, it is up to the user of the program to decide if the program is
suitable for the intended purpose and free from errors.
*******************************************************************************************************/
/*******************************************************************************************************
Program Operation - This is a LoRa transmitter that transmits a buffer containing text to control a
remote device by sending 'LEDOn' to turn the LED on and 'LEDOff' to turn the LED off.
Sample Serial Monitor output;
86_Buffer_Transmit_Controller Starting
LoRa Device found
Transmitter ready
Send Packet> LEDOn
Send Packet> LEDOff
Serial monitor baud rate is set at 9600
*******************************************************************************************************/
#include <SPI.h> //the lora device is SPI based so load the SPI library
#include <SX127XLT.h> //include the appropriate library
SX127XLT LT; //create a library class instance called LT
#define NSS 10 //select pin on LoRa device
#define NRESET 9 //reset pin on LoRa device
#define DIO0 3 //DIO0 pin on LoRa device, used for sensing RX and TX done
#define LED1 8 //pin for LED
#define LORA_DEVICE DEVICE_SX1278 //we need to define the device we are using
#define TXpower 10 //LoRa transmit power in dBm
#define TXtimeout 10000 //transmit timeout in mS
uint8_t TXPacketL;
uint8_t onpacket[] = "LEDOn"; //send this to turn LED on
uint8_t offpacket[] = "LEDOff"; //send this to turn LED off
#include <SPI.h>
#include <LoRa.h>
void loop()
{
//************************************
//LED on
//************************************
Serial.print(F("Send Packet> ("));
Serial.print(sizeof(onpacket));
Serial.print(F("chars) "));
LT.printASCIIPacket(onpacket, sizeof(onpacket)); //print the buffer (the sent packet) as ASCII
digitalWrite(LED1, HIGH);
LT.transmit(onpacket, sizeof(onpacket), TXtimeout, TXpower, WAIT_TX); //will return packet length sent if OK, otherwise 0 if transmit error
Serial.println();
delay(5000); //have a delay between packets
//************************************
//LED off
//************************************
Serial.print(F("Send Packet> ("));
Serial.print(sizeof(offpacket));
Serial.print(F("chars) "));
LT.printASCIIPacket(offpacket, sizeof(offpacket)); //print the buffer (the sent packet) as ASCII
digitalWrite(LED1, LOW);
LT.transmit(offpacket, sizeof(offpacket), TXtimeout, TXpower, WAIT_TX); //will return packet length sent if OK, otherwise 0 if transmit error
Serial.println();
delay(5000); //have a delay between packets
}
void led_Flash(uint16_t flashes, uint16_t delaymS)
{
uint16_t index;
for (index = 1; index <= flashes; index++)
{
digitalWrite(LED1, HIGH);
delay(delaymS);
digitalWrite(LED1, LOW);
delay(delaymS);
}
}
void setup()
{
pinMode(LED1, OUTPUT); //setup pin as output for indicator LED
led_Flash(2, 125);
Serial.begin(9600);
Serial.println();
Serial.println(F("86_Buffer_Transmit_Controller Starting"));
SPI.begin();
if (LT.begin(NSS, NRESET, DIO0, LORA_DEVICE))
{
Serial.println(F("LoRa Device found"));
led_Flash(2, 125);
delay(1000);
}
else
{
Serial.println(F("No device responding"));
while (1)
{
led_Flash(50, 50); //long fast speed LED flash indicates device error
}
}
LT.setupLoRa(434000000, 0, LORA_SF7, LORA_BW_125, LORA_CR_4_5, LDRO_AUTO); //configure frequency and LoRa settings
Serial.print(F("Transmitter ready"));
Serial.println();
}

View File

@@ -0,0 +1,176 @@
/*******************************************************************************************************
Programs for Arduino - Copyright of the author Stuart Robinson - 19/09/20
This program is supplied as is, it is up to the user of the program to decide if the program is
suitable for the intended purpose and free from errors.
*******************************************************************************************************/
/*******************************************************************************************************
Program Operation - This is a LoRa receiver that listens for packets that are text based commands used
when received to turn a LED on or off. When 'LEDOn' is received the LED is turned on and its turned off
when 'LEDOff' is received.
Sample Serial Monitor output;
87_Buffer_Receive_Controller Starting
LoRa Device found
Receiver ready
2s Received packet > LEDOn,RSSI,-65dBm,SNR,6dB,Length,5 Turn LED on
3s Received packet > LEDOff,RSSI,-62dBm,SNR,5dB,Length,6 Turn LED off
Serial monitor baud rate is set at 9600
*******************************************************************************************************/
#include <SPI.h> //the lora device is SPI based so load the SPI library
#include <SX127XLT.h> //include the appropriate library
SX127XLT LT; //create a library class instance called LT
#define NSS 10 //select pin on LoRa device
#define NRESET 9 //reset pin on LoRa device
#define DIO0 3 //DIO0 pin on LoRa device, used for RX and TX done
#define LED1 8 //pin for LED
#define LORA_DEVICE DEVICE_SX1278 //we need to define the device we are using
#define RXtimeout 60000 //receive timeout in mS
char RXBUFFER[16]; //create the buffer that received packets are copied into
uint8_t RXPacketL; //stores length of packet received
int16_t PacketRSSI; //stores RSSI of received packet
int8_t PacketSNR; //stores signal to noise ratio (SNR) of received packet
char onpacket[] = "LEDOn"; //send this to turn LED on
char offpacket[] = "LEDOff"; //send this to turn LED off
void loop()
{
RXPacketL = LT.receive( (uint8_t*) RXBUFFER, sizeof(RXBUFFER), RXtimeout, WAIT_RX); //wait for a packet to arrive with timeout
PacketRSSI = LT.readPacketRSSI(); //read the received packets RSSI value
PacketSNR = LT.readPacketSNR(); //read the received packets SNR value
if (RXPacketL == 0) //if the LT.receive() function detects an error RXpacketL is 0
{
packet_is_Error();
}
else
{
packet_is_OK();
if (strncmp((char*) RXBUFFER, onpacket, strlen(onpacket)) == 0)
{
Serial.print(F(" Turn LED on"));
digitalWrite(LED1, HIGH);
}
if ( strncmp( (char*) RXBUFFER, offpacket, strlen(offpacket)) == 0)
{
Serial.print(F(" Turn LED off"));
digitalWrite(LED1, LOW);
}
}
Serial.println();
}
void led_Flash(uint16_t flashes, uint16_t delaymS)
{
uint16_t index;
for (index = 1; index <= flashes; index++)
{
digitalWrite(LED1, HIGH);
delay(delaymS);
digitalWrite(LED1, LOW);
delay(delaymS);
}
}
void printElapsedTime()
{
float seconds;
seconds = millis() / 1000;
Serial.print(seconds, 0);
Serial.print(F("s"));
}
void packet_is_OK()
{
printElapsedTime(); //print elapsed time to Serial Monitor
Serial.print(F(" Received packet > "));
LT.printASCIIPacket((uint8_t*)RXBUFFER, RXPacketL); //print the packet as ASCII characters
Serial.print(F(",RSSI,"));
Serial.print(PacketRSSI);
Serial.print(F("dBm,SNR,"));
Serial.print(PacketSNR);
Serial.print(F("dB,Length,"));
Serial.print(RXPacketL);
}
void packet_is_Error()
{
uint16_t IRQStatus;
IRQStatus = LT.readIrqStatus(); //read the LoRa device IRQ status register
printElapsedTime(); //print elapsed time to Serial Monitor
Serial.print(F(" Packet error > "));
if (IRQStatus & IRQ_RX_TIMEOUT) //check for an RX timeout
{
Serial.print(F(" RXTimeout"));
}
else
{
Serial.print(F(" RSSI,"));
Serial.print(PacketRSSI);
Serial.print(F("dBm,SNR,"));
Serial.print(PacketSNR);
Serial.print(F("dB,Length,"));
Serial.print(LT.readRXPacketL()); //get the real packet length
Serial.print(F(",IRQreg,"));
Serial.print(IRQStatus, HEX);
LT.printIrqStatus(); //print the names of the IRQ registers set
}
}
void setup()
{
pinMode(LED1, OUTPUT); //setup pin as output for indicator LED
led_Flash(2, 125);
Serial.begin(9600);
Serial.println();
Serial.println(F("87_Buffer_Receive_Controller Starting"));
Serial.println();
SPI.begin();
if (LT.begin(NSS, NRESET, DIO0, LORA_DEVICE))
{
Serial.println(F("LoRa Device found"));
led_Flash(2, 125);
delay(1000);
}
else
{
Serial.println(F("No device responding"));
while (1)
{
led_Flash(50, 50); //long fast speed LED flash indicates device error
}
}
LT.setupLoRa(434000000, 0, LORA_SF7, LORA_BW_125, LORA_CR_4_5, LDRO_AUTO); //configure frequency and LoRa settings
Serial.println(F("Receiver ready"));
}