Grunderna i förvandlar ditt Remote Controll fordon till ett autonomt System (Drone) genom att använda en Arduino (5 / 7 steg)
Steg 5: Den kod del 2
Du kan använda vilken sensor du och så många du vill, så länge de kan gränssnittet för arduino som du använder.
För att visa denna idé, jag har skrivit lite kod som tar behandlingen företrädare för avstånd från en skarp analog infraröd sensor som är monterad på en sida av helikoptern och om läsningen innebär att helikoptern närmar sig ett hinder då det kommer att avleda bort till motsatt sida. Annars kommer kontroll att förbli helt på våra händer.
Jag har lämnat spjäll koden i trots att det inte används om du använder en 3: e signal linje; kan du spara tid att lägga till koden igen :) inte jag trevligt!
Här är den modifierade koden och kom ihåg att läsa kommentarer att göra det klart för oss vad koden gör:
#include < RCArduinoFastLib.h >
//
Kapten Dysons Mod till the Origional Test struktur av Rcarduinos exempelkod
för "RCArduinoFastLib"-biblioteket
Denna kod läser en avstånd sensorn innan du fattar beslut om att flytta bort eller inte.
//
MultiChannels
rcarduino.blogspot.com
En enkel metod för att läsa tre RC kanaler med hjälp av pin ändra avbryter
Se relaterade inlägg-
http://rcarduino.blogspot.co.uk/2012/01/How-to-Read-RC-receiver-with.html
http://rcarduino.blogspot.co.uk/2012/03/need-more-interrupts-to-Read-more.html
http://rcarduino.blogspot.co.uk/2012/01/can-i-Control-more-than-x-Servos-with.html
rcarduino.blogspot.com
inkluderar pinchangeint biblioteket - se länkarna i avsnittet närliggande information ovan för Detaljer
#include < PinChangeInt.h >
Tilldela din kanal i pins
#define THROTTLE_IN_PIN 5
#define STEERING_IN_PIN 6
#define AUX_IN_PIN 7
Tilldela din kanal ut pins
#define THROTTLE_OUT_PIN 8
#define STEERING_OUT_PIN 9
#define AUX_OUT_PIN 10
Tilldela servo index
#define SERVO_THROTTLE 0
#define SERVO_STEERING 1
#define 2
#define SERVO_FRAME_SPACE 3
Dessa bitflaggor som anges i bUpdateFlagsShared att ange vilka kanaler har nya signaler
#define THROTTLE_FLAG 1
#define STEERING_FLAG 2
#define AUX_FLAG 4
innehar uppdatering flaggorna ovan definierade
flyktiga uint8_t bUpdateFlagsShared;
delade variabler uppdateras av ISR och läsa av loop.
I slinga vi omedelbart ta lokala kopior så att ISR kan hålla ägandet av den
delade de. Att få tillgång till dessa i slinga vi först inaktivera avbrott med noInterrupts
Vi tar en kopia att använda i loop och turn avbrott igen så snabbt som möjligt
Detta säkerställer att vi alltid ska kunna ta emot nya signaler
flyktiga uint16_t unThrottleInShared;
flyktiga uint16_t unSteeringInShared;
flyktiga uint16_t unAuxInShared;
Dessa används för att registrera stigande kanten av en puls i de calcInput funktionerna
De behöver inte vara flyktiga som de används bara i ISR. Om vi ville
för att hänvisa till dessa i loop och ISR skulle då de behöva förklaras flyktiga
uint16_t unThrottleInStart;
uint16_t unSteeringInStart;
uint16_t unAuxInStart;
uint16_t unLastAuxIn = 0;
uint32_t ulVariance = 0;
uint32_t ulGetNextSampleMillis = 0;
uint16_t unMaxDifference = 0;
Tilldela en omkopplarinställning att läsa sensordata
int sensorPin = A0;
void setup()
{
Serial.BEGIN(115200);
Serial.println("multiChannels");
koppla servo objekt, dessa kommer att generera rätt
pulser för att köra elektroniska hastighetsregulatorer, servon eller andra enheter
utformad för att samverka direkt med RC mottagare
CRCArduinoFastServos::attach(SERVO_THROTTLE,THROTTLE_OUT_PIN);
CRCArduinoFastServos::attach(SERVO_STEERING,STEERING_OUT_PIN);
CRCArduinoFastServos::attach(SERVO_AUX,AUX_OUT_PIN);
låter som en standard frekvens på 50 Hz genom att ange en ram utrymme av 10 * 2000 = 3 servon + 7 gånger 2000
CRCArduinoFastServos::setFrameSpaceA(SERVO_FRAME_SPACE,7*2000);
CRCArduinoFastServos::begin();
med hjälp av PinChangeInt biblioteket, bifoga avbrotten används för att läsa kanalerna
PCintPort::attachInterrupt (THROTTLE_IN_PIN, calcThrottle, förändring);
PCintPort::attachInterrupt (STEERING_IN_PIN, calcSteering, förändring);
PCintPort::attachInterrupt (AUX_IN_PIN, calcAux, förändring);
}
void loop()
{
skapa lokala variabler för att lagra lokala kopior av kanal ingångarna
Detta förklaras som statiska så att deras värden bevaras mellan samtal till ögla.
statisk uint16_t unThrottleIn;
statisk uint16_t unSteeringIn;
statisk uint16_t unAuxIn;
lokal kopia av uppdatering flaggor
statisk uint8_t bUpdateFlags;
Kolla delade uppdatering flaggor för att se om några kanaler har en ny signal
IF(bUpdateFlagsShared)
{
noInterrupts(); Inaktivera avbrott snabbt medan vi vidta lokala kopior av de delade variablerna
ta en lokal kopia av vilka kanaler har uppdaterats så att vi kan använda detta i resten av loopen
bUpdateFlags = bUpdateFlagsShared;
i aktuell kod fylls gemensamma värden alltid
så vi kunde kopiera dem utan provning flaggor
men i framtiden kan detta förändras, så kan
Kopiera endast när flaggorna berättar vi kan.
IF(bUpdateFlags & THROTTLE_FLAG)
{
unThrottleIn = unThrottleInShared;
}
IF(bUpdateFlags & STEERING_FLAG)
{
unSteeringIn = unSteeringInShared;
}
IF(bUpdateFlags & AUX_FLAG)
{
unAuxIn = unAuxInShared;
}
Rensa delade kopian av uppdaterad flaggor som vi redan har tagit uppdateringarna
Vi har fortfarande en lokal kopia om vi behöver använda det i bUpdateFlags
bUpdateFlagsShared = 0;
interrupts(); Vi har lokala kopior av insatsvaror, så nu kan vi vända avbryter tillbaka på
så snart som avbryter är tillbaka på, kan vi inte längre använda delade kopiorna, avbrottet
Service rutiner äger dessa och kan uppdatera dem när som helst. Under uppdateringen, den
delade kopior kan innehålla skräppost. Lyckligtvis har vi vår lokala kopior att arbeta med :-)
}
göra någon bearbetning härifrån och framåt
Använd endast den lokala värden unAuxIn, unThrottleIn och unSteeringIn
Denna Sensor setup upptäcker prescence i ett objekt till helecopters höger
Om objektet är att stänga då båten kommer att avleda vänster, från faran
Du kan lägga till så många om loopar till denna kod som du gillar med olika sensorer
men Kopiera inte denna kod exakt och förväntar sig att arbeta, det beror på
Detaljer i din servon och anvisningarna du vill ha dem att resa i,
denna kod är specifika för min bygga, ändra den för din :)
Läs sensorn
int val = analogRead(sensorPin);
placera ett villkor mot denna behandling
om (val > 150)
{
agera utifrån villkoret
unSteeringIn = unSteeringIn + 430,
Tillämpa de nya förändrade värdena
IF(bUpdateFlags & THROTTLE_FLAG)
{
CRCArduinoFastServos::writeMicroseconds(SERVO_THROTTLE,unThrottleIn);
}
IF(bUpdateFlags & STEERING_FLAG)
{
CRCArduinoFastServos::writeMicroseconds(SERVO_STEERING,unSteeringIn);
}
IF(bUpdateFlags & AUX_FLAG)
{
CRCArduinoFastServos::writeMicroseconds(SERVO_AUX,unAuxIn);
}
}
Om vi har ingen anledning att ändra servo positioner kan vi passera signalen genom
som vi gjorde i test skissen med inga ändringar.
annat
{
IF(bUpdateFlags & THROTTLE_FLAG)
{
CRCArduinoFastServos::writeMicroseconds(SERVO_THROTTLE,unThrottleIn);
}
IF(bUpdateFlags & STEERING_FLAG)
{
CRCArduinoFastServos::writeMicroseconds(SERVO_STEERING,unSteeringIn);
}
IF(bUpdateFlags & AUX_FLAG)
{
CRCArduinoFastServos::writeMicroseconds(SERVO_AUX,unAuxIn);
}
}
bUpdateFlags = 0;
}
enkla avbrottstjänstens rutin
void calcThrottle()
{
IF(PCintPort::pinState)
{
unThrottleInStart = TCNT1;
}
annat
{
unThrottleInShared = (TCNT1 - unThrottleInStart) >> 1;
bUpdateFlagsShared | = THROTTLE_FLAG;
}
}
void calcSteering()
{
IF(PCintPort::pinState)
{
unSteeringInStart = TCNT1;
}
annat
{
unSteeringInShared = (TCNT1 - unSteeringInStart) >> 1;
bUpdateFlagsShared | = STEERING_FLAG;
}
}
void calcAux()
{
IF(PCintPort::pinState)
{
unAuxInStart = TCNT1;
}
annat
{
unAuxInShared = (TCNT1 - unAuxInStart) >> 1;
bUpdateFlagsShared | = AUX_FLAG; }
}
Nu kom ihåg detta är bara ett enkelt exempel, vänligen vara lika uppfinningsrik som du vill och lägga till så många sensorer som du vill, några idéer skulle vara en accelerometer eller en PING sensor för avkänning längre sträckor, eller gå ännu längre och lägga till en GPS med ett nuvarande läge kontra målet läge jämförelse sedan få din enhet att gå till en viss geografisk plats.