Arduino...

This is for all discussions related to IT and technology. Hardware, software, programming, it all goes here.
User avatar
Lurigo
Posts: 99
Joined: Tue Jan 01, 2013 4:33 pm
Gender: Male
Sexual preference: Straight
Species: Silver Fox
Region: Northwest and North Cape
Location: Potchefstroom
Contact:

Re: Arduino...

#31

Post by Lurigo »

*uses necromancy*

Arduino!!
I recently got one of my own as well. An UNO R3 to be exact.
I haven't done much with it so far, but I have some experience with MCUs at least. I work with TI MSP430s a lot, also got an EasyPIC5 board and worked with a SiLabs 8051 last year.

The Arduino is a pretty nifty lil board. I quite like the analogue inputs, really useful for taking readings and whatnot. I got a Nokia 5110 LCD I want to connect to the Arduino to display stuff. What that stuff will be, I dunno yet. Want to maybe try making a game for it. Simple two-button control and whatnot.

But yeah, quite interested to hear what y'all did with yours so far. Adagio's projects look awesome!
User avatar
Adagio
Warm Hearted
Posts: 3589
Joined: Tue Feb 07, 2012 7:06 am
Gender: Male
Sexual preference: Other
Species: Snow Leopard
Region: Gauteng
Location: Pretoria, Silverton
Contact:

Re: Arduino...

#32

Post by Adagio »

So! I might as well share my latest project!
It's on hold for now, till I finish writing...
I mentioned it on the WAYDRN thread back when I started...

I'm working on a Quadcopter!
BACKSTORY:
For my birthday a few years back, I bought a quadcopter frame, it came with a useless controller, that didn't work at all...

So, after being bored in the semester break, I started making THIS:
Crappy picture... Sorry
Crappy picture... Sorry
I'm still working on the code... In a little over my head... I could make it work straight from the remote, but it'll probably crash...
Gyro, Accelerometer, Compass, Alti
Gyro, Accelerometer, Compass, Alti
Rhus I'm using this... It is a tiny little all in one board from Pololu.
Unfortunately it uses two of the pin's I need for using the interupts... Thus, I can only use 4 channels of the remote's PPM signals... I would have used the 5'th for altitude hold, but I found a way around that!
Arduino and Reciever
Arduino and Reciever
Arduino and Reciever...

And here is the code!(Not finished yet) I still need to figure out an control algorithm and do some calculations...
As I said... I'm in a little over my head... Programming isn't my strong suite...

Code: Select all

  /////////////////////////////////////
 //THIS IS THE TAB FOR THE MAIN CODE//
/////////////////////////////////////

#include <Wire.h>         //Library for Accelerometer board communications
#include <LPS.h>         //Library for Altimiter
#include <L3G.h>        //Library for 3Axis Gyro
#include <LSM303.h>    //Library for Magneto Meter
#include <Servo.h>    //
                     //
LPS ps;             //Declare Pressure Sensor as 'ps'
L3G gyro;          //Declare Gyro as 'gyro'
LSM303 compass;   //declare Magneto Meter as 'compass'
Servo mot1;      //Motor 1
Servo mot2;     //Motor 2
Servo mot3;    //Motor 3
Servo mot4;   //Motor 4


  /////////////
 //Variables//
/////////////

/*
from http://gammon.com.au/interrupts
"
Variables shared between ISR functions and normal functions should be declared "volatile". 
This tells the compiler that such variables might change at any time, 
and thus the compiler must reload the variable whenever you reference it, 
rather than relying upon a copy it might have in a processor register.
"
*/

volatile int sig0;             //to use the AttatchInterupt signal correctly It is important to use Volatile Variables
volatile int sig1;            //
volatile int sig2;           //
volatile int sig3;          //
volatile int sig4;         //
volatile int sig5;        //
volatile int stsig0;     //The micros(); function keeps counting indefinately.
volatile int stsig1;    //so we use these to record the "stop" time.
volatile int stsig2;   //
volatile int stsig3;  //
volatile int stsig4; //
volatile int stsig5;//

int gx, gy, gz;

float pressure;
float altitude;
float takeoff;
float height;
float dheight;
float temperature;
float heading;

  ///////////////////
 //SETUP PROCEDURE//
///////////////////

void setup()
{
  pinMode(2,INPUT);//Input for Interrupts.
  pinMode(3,INPUT);
//  pinMode(21,INPUT);//unfortunately I2C(Wire) requires intterupt pins 20/21 to function properly
  pinMode(20,INPUT);
  pinMode(18,INPUT);
  pinMode(19,INPUT);
  
  Serial.begin(9600);
  Wire.begin();
  
    if (!ps.init())//CHECK IF PRESSURE SENSOR IS FUNCTIONING PROPERLY
  {
    Serial.println("Failed to autodetect pressure sensor!");
    while (1);
  }
  
    if (!gyro.init())//CHECK IF GYRO IS FUNCTIONING PROPPERLY
  {
    Serial.println("Failed to autodetect gyro type!");
    while (1);
  }
  
  
    /////////////////////////////////////
   //HELPER FUNCTIONS FOR GYRO LIBRARY//
  /////////////////////////////////////
  
  ps.enableDefault();
  compass.init();
  compass.enableDefault();
  compass.m_min = (LSM303::vector<int16_t>){-32767, -32767, -32767};
  compass.m_max = (LSM303::vector<int16_t>){+32767, +32767, +32767};
  gyro.enableDefault();

  mot1.attach(4);
  mot2.attach(5);
  mot3.attach(6);
  mot4.attach(7);
  
  attachInterrupt(0,hPPM0,RISING);        //ATTACH THE INTERRUPTS
  attachInterrupt(1,hPPM1,RISING);       //SEE DATA COLLECTION TAB
//  attachInterrupt(2,hPPM2,RISING);    //FOR MORE INFORMATION 
//  attachInterrupt(3,hPPM3,RISING);   //ON THE INTERRUPT PINS
  attachInterrupt(4,hPPM4,RISING);    //USEFULL STIES ON INTERRUPT'S: http://gammon.com.au/interrupts
  attachInterrupt(5,hPPM5,RISING);   //USEFULL STIES ON INTERRUPT'S:  https://www.arduino.cc/en/Reference/AttachInterrupt
  
  salti();
  takeoff = altitude;
  
  
}                                    


  /////////////
 //MAIN LOOP//
/////////////

void loop()
{

  int x, y;
  sgyro();        //call function for Gyro(see Sensors Tab)
  salti();       //call function for Altimeter
  scompass();   //call function for Magnetometer

  sdebug();


}

Code: Select all

  //////////////////////////////////////
 //THIS TAB IS FOR DOING CALCULATIONS//
//////////////////////////////////////

int calcdeg(int val)  //THE PPM SIGNALS FROM THE RECIEVER RETURNS A VALUE FROM 1000ms TO ~1800ms
{
  int res;          //DECTARE A TEMPORARY VARRIABLE
  res = val-1000;  //SUBTRACT 1000(TO GIVE VALUE BETWEEN 0 AND 800)
  res = res/4.16; //DEVIDE BY 4.16(TO GET USABLE DEGREE'S SINCE THE ESC's USE SERVO PULSES TO WORK, THIS'LL BE THE EASYEST)

  if(res>180)   //CHECK INTEGRITY
  {            //
    res=180;  //
  }          //
  if(res<0) //
  {
    res=0;
  }
  
  return(res);//RETURN THE VALUE
}

Code: Select all

  ///////////////////////////////
 //THIS TAB IS TO COLLECT DATA//
///////////////////////////////

/*

Reciever pinout:
Ch 1: Right stick, X-Axis
Ch 2: Right stick, Y-Axis
Ch 3: Left stick, Throttle
Ch 4: Left stick, X-Axis
Ch 5: Switch 1

From Oscilloscope:
LOW: 18ms
HIGH: 1/1.75ms
Period 20ms

sig0 = roll
sig1 = pitch
sig2 = throttle
sig3 = yaw

AttachInterrupt:
int0    int1    int2    int3    int4    int5
2       3       21      20      19      18

Syntax:
attachInterrupt(int, ISR, mode)

Parameters:

interrupt: 	the number of the interrupt (int)

ISR: 	the ISR to call when the interrupt occurs; this function must take no parameters and return nothing. This function is sometimes referred to as an interrupt service routine.

mode: 	

defines when the interrupt should be triggered. Four contstants are predefined as valid values:

    LOW to trigger the interrupt whenever the pin is low,
    CHANGE to trigger the interrupt whenever the pin changes value
    RISING to trigger when the pin goes from low to high,
    FALLING for when the pin goes from high to low. 

Compass heading output:
Degree between 0-360

Baromiter:
p: millibar:
a: M
t: Degree C




*/

Code: Select all

  ////////////////////////////////////////
 //This tab is for the flight controlls//
////////////////////////////////////////

void thr(int power)
{
  
  mot1.write(power);
  mot2.write(power);
  mot3.write(power);
  mot4.write(power);
  
}

void movement(){
 int roll, pitch, yaw;
 
 roll  =   calcdeg(sig0);
 pitch =   calcdeg(sig1);
 yaw   =   calcdeg(sig2);
 
}

void holdalt(){
  int power;
  salti();
  height = altitude-takeoff;
  
  if(dheight < height){
   power++;  
    
  }else if(dheight > height){
   power--;
    
  }
  
  thr(power);
  
}

Code: Select all

      ///////////////////////////////////
     //THIS TAB IS FOR MAIN PROCEDURES//
    ///////////////////////////////////
   //         AND FUNCTIONS         //
  ///////////////////////////////////
 // ~INTERRUPT SERVICE ROUTINE'S~ //
///////////////////////////////////

/*
I spent hour's trying to decode this part of the code. since I got it from johndavid400 on instructables. http://www.instructables.com/id/Arduino-RC-Lawnmower/
So I'll attempt to explain the procedure to the best of my knowledge...

first. Interrupts are important for this. Interrupts catch signals and "Interrupts" the main code untill the finished their job.
Thus, the interrupt's wait for a signal on the designated pins(See Data_Collection for their pin numbers), once they recive their triggers
either RISING or FALLING(Meaning either RISNG: going from LOW to HIGH, or FALLING: From HIGH to LOW) they trigger a procedure.
In my code, it's hPPM[interrupt number].
The returnMillis(); function doesn't work in Interrupt's, so you need to use micros();
The micros(); function returns the (and this is important) [u]TIME ELAPSED SINCE THE ARDUINO RECIEVED POWER[/u]
THAT is why we need to attach an Interrupt for the FALLING edge trigger ASWELL INSIDE the procedure for the RISING edge trigger.
*/

  /////////////////////////////////
 //RISING EDGE TRIGGER INTERRUPT//
/////////////////////////////////

void hPPM0()//INTERRUPT 0
{
  stsig0 = micros();                  //GET MICROSECONDS
  detachInterrupt(0);                //DETATCH(TO ATTACH FALLING EDGE ON SAME PIN)
  attachInterrupt(0,lPPM0,FALLING); //ATTACH FALLING EDGE TRIGGER
}

void hPPM1()//INTERRUPT 1
{
  stsig1 = micros();
  detachInterrupt(1);
  attachInterrupt(1,lPPM1,FALLING);
}

void hPPM2()//INTERRUPT 2
{
  stsig2 = micros();
  detachInterrupt(2);
  attachInterrupt(2,lPPM2,FALLING);
}

void hPPM3()//INTERRUPT 3
{
  stsig3 = micros();
  detachInterrupt(3);
  attachInterrupt(3,lPPM3,FALLING);
}

void hPPM4()//INTERRUPT 4
{
  stsig4 = micros();
  detachInterrupt(4);
  attachInterrupt(4,lPPM4,FALLING);
}

void hPPM5()//INTERRUPT 5
{
  stsig5 = micros();
  detachInterrupt(5);
  attachInterrupt(5,lPPM5,FALLING);
}

  //////////////////////////////////
 //FALLING EDGE TRIGGER INTERRUPT//
//////////////////////////////////


void lPPM0()//INTERRUPT 0
{
  sig0 = micros()-stsig0;            //ASSIGN TO VARIABLE sig0 THE DIFFRENCE BETWEEN THE CURRENT VALUE OF micros() AND THE STARTING VALUE(stsig0)
  detachInterrupt(0);               //DETACH IT AGAIN SE WE CAN...
  attachInterrupt(0,hPPM0,RISING); //REATTACH THE RISING TRIGGER.
}

void lPPM1()
{
  sig1 = micros()-stsig1;
  detachInterrupt(1);
  attachInterrupt(1,hPPM1,RISING);
}

void lPPM2()
{
  sig2 = micros()-stsig2;
  detachInterrupt(2);
  attachInterrupt(2,hPPM2,RISING);
}

void lPPM3()
{
  sig3 = micros()-stsig3;
  detachInterrupt(3);
  attachInterrupt(3,hPPM3,RISING);
}

void lPPM4()
{
  sig4 = micros()-stsig4;
  detachInterrupt(4);
  attachInterrupt(4,hPPM4,RISING);
}

void lPPM5()
{
  sig5 = micros()-stsig5;
  detachInterrupt(5);
  attachInterrupt(5,hPPM5,RISING);
}


void sdebug(){
      ////////////////////////////
     //FOR DEBUGGING PURPOUSES //
    ////////////////////////////
   //CAN BE REMOVED FOR+SPEED//
  ////////////////////////////
 //    SERIAL OUTPUT'S     //
////////////////////////////


/*
  Serial.print("Motor 1:  ");
  Serial.print(mot[0]);
  Serial.print("\t");
  Serial.print("Motor 2:  ");
  Serial.print(mot[1]);
  Serial.print("\t");
  Serial.print("Motor 3:  ");
  Serial.print(mot[2]);
  Serial.print("\t");
  Serial.print("Motor 4:  ");
  Serial.print(mot[3]);
*/
///*
  Serial.print("Raw data:  ");
  Serial.print(sig0);
  Serial.print("\t");
  Serial.print(sig1);
  Serial.print("\t");
  Serial.print(sig4);
  Serial.print("\t");
  Serial.print(sig5);
//*/
  Serial.print("\tGyro:");
  Serial.print("\t");
  Serial.print("X:");
  Serial.print(gx);
  Serial.print("\t");
  Serial.print("Y:");
  Serial.print(gy);
  Serial.print("\t");
  Serial.print("Z:");
  Serial.print(gz);
  
  Serial.print("\tBaro:");
  Serial.print("\t");
  Serial.print(altitude);
  Serial.print("m");
  Serial.print("\t");
  
  Serial.print("Compass");
  Serial.print("\t");
  Serial.print(heading);
   
  Serial.println("");
 
}

Code: Select all

    /////////////////////////////////////
   //    THIS TAB IS FOR PROCEDURES   //
  ////////////////////////////////////
 //   ASSOCIATED WITH THE SENSORS  //
////////////////////////////////////
void salti()
{
  pressure =     ps.readPressureMillibars();
  altitude =     ps.pressureToAltitudeMeters(pressure);
  temperature =  ps.readTemperatureC();
}

void scompass()
{
  compass.read();
  heading = compass.heading();
}

void sgyro()
{
  gyro.read();
  gx = (gyro.g.x)/100;
  gy = (gyro.g.y)/100;
  gz = (gyro.g.z)/100;
}
I made everything modular, So I can easily add a GPS shield later, or an XBEE reciever...


But I still have a lot of work ahead of me...
Leeward
Recalcitrant Ruminant
Posts: 7036
Joined: Wed Mar 19, 2014 10:23 pm

Re: Arduino...

#33

Post by Leeward »

Looking pretty good so far. I'm not much good with C, but I can help with algorithm design.
User avatar
Sev
Superbike Snow Leopard
Posts: 6596
Joined: Thu Mar 06, 2014 9:27 pm
Gender: Male
Sexual preference: Gay
Species: Snow Leopard
Region: Western Cape
Location: A Twisty Road

Re: Arduino...

#34

Post by Sev »

You really do love your comments.
User avatar
Adagio
Warm Hearted
Posts: 3589
Joined: Tue Feb 07, 2012 7:06 am
Gender: Male
Sexual preference: Other
Species: Snow Leopard
Region: Gauteng
Location: Pretoria, Silverton
Contact:

Re: Arduino...

#35

Post by Adagio »

Sev wrote:You really do love your comments.
Why yes! Yes I do! Hahaha!
Went a little overboard didn't I?

I'm planning on posting it on Instructables, and had to go through so many people's code and try to decipher it... So I made sure that it can be understood... I mean, what's the point if you can't learn something?
Leeward wrote:Looking pretty good so far. I'm not much good with C, but I can help with algorithm design.
Thanks! I'll keep that in mind!
I'll continue with it when I finish writing...
Randall
Posts: 1616
Joined: Wed Nov 18, 2015 9:15 am
Species: Funambulus palmarum (Squirrel)
Region: Gauteng

Re: Arduino...

#36

Post by Randall »

Hmmm... this is easy stuff
User avatar
Adagio
Warm Hearted
Posts: 3589
Joined: Tue Feb 07, 2012 7:06 am
Gender: Male
Sexual preference: Other
Species: Snow Leopard
Region: Gauteng
Location: Pretoria, Silverton
Contact:

Re: Arduino...

#37

Post by Adagio »

Sonic2k wrote:Hmmm... this is easy stuff
HAHAHAHAHA! Dude! I was self tough in C and Arduino Code when I started this... And we haven't done C yet in Micro controllers...

And you have a LOT of experience!

I'll get there! Believe me!
Randall
Posts: 1616
Joined: Wed Nov 18, 2015 9:15 am
Species: Funambulus palmarum (Squirrel)
Region: Gauteng

Re: Arduino...

#38

Post by Randall »

So then, just ask for a tutorial/help/whatever.
I used to do this for a living.
User avatar
Adagio
Warm Hearted
Posts: 3589
Joined: Tue Feb 07, 2012 7:06 am
Gender: Male
Sexual preference: Other
Species: Snow Leopard
Region: Gauteng
Location: Pretoria, Silverton
Contact:

Re: Arduino...

#39

Post by Adagio »

Sonic2k wrote:So then, just ask for a tutorial/help/whatever.
I used to do this for a living.
Will do dude!
If I have time, I'll work on this project when I finish my exams...
Post Reply