AirsoftMechanics.com
September 10, 2010, 07:44:13 PM *
Welcome, Guest. Please login or register.
Did you miss your activation email?

Login with username, password and session length
News: Welcome to the NEW AirsoftMechanics.com Discussion Forums!
 
   Home   Help Login Register  
Pages: 1 ... 7 8 [9] 10 11
  Print  
Author Topic: Lion Software (Read 5104 times)
Gandolf
High Voltage Guru
Global Moderator
Colonel
*

Reputation Power: 98
Reputation: Gandolf has an aura about them.Gandolf has an aura about them.Gandolf has an aura about them.Gandolf has an aura about them.Gandolf has an aura about them.Gandolf has an aura about them.Gandolf has an aura about them.Gandolf has an aura about them.Gandolf has an aura about them.Gandolf has an aura about them.
[view reputation]

Offline Offline

Posts: 1593



WWW
« Reply #120 on: June 26, 2010, 10:45:50 PM »

Quote
im also thinking on the motor state machine. states should be stop, running and brake. the jump conditions use clock, precocking time and known motor running time, last state, new state requests (from mainloop) and trigger already debounced. outputs are OCR0A, TCCR0A, TCCR0B (for controlling motor and brake). i haven't decided where to put the control of the motor in terms of continuous work or single shot/burst, i could use a hand here. the thing i've decided more about is the request service:

I am thinking this...

The motor state machine should be pretty simple.  

There are three states:
  Off  - Both FETs are turned off
  On - The drive FET is turned on under control of the PWM
  Brake - The brake FET is tuned on under PWM control  (note that there is no PWM on it at this time)
  Crossover - A forced dead time between a FET is turned off and the other being turned on.  (would that be a 4th state?)  There is no delay if the same FET is turned off and then on.

The complications are:
  At no time can the braking and main FET be allowed to be on at the same time.  That will destroy the unit!
  There needs to be a crossover time between tuning off one FET and turning on the other.  Right now that time is 1mS (3.8uS transition (worst case) plus 1000uS cool down for 450 amps for 1000uS).
  The motor and probably the brake speed should be continuously variable while the motor is running.
  Very quickly after the motor is turned on (1mS) we need to check the current to see if it is just running into a dead short (Vdrain > 0.905V).

Things like precocking, short detection, burst times etc. need to be much higher functions since they can be vary complex and those methods change all the time.

So the inputs are:
  Motor (on, off, or break)
  Motor (PWM)
  Brake (PWM)

Quote
the ADC 1us was time expected to spend on ADC ISR code, not that ADC would be that fast. anyhow I see your point, maybe we should run slower, so we are able to read properly.

I should do a test to see just how fast the ADC can be run and where the accuracy falls off.  That is a bit scary though since that can vary from chip type and things like that new "A" on all the part numbers.

Once the ADC is started the rest of the program can go onward no mater how long the ADC takes.  The ADC tells us when it is done with its status bit.  In my case, I just sat there and waited for it but that was really a waste.
« Last Edit: June 26, 2010, 11:37:19 PM by Gandolf » Logged
sik_gerar
Corporal
****

Reputation Power: 6
Reputation: sik_gerar has no influence.
[view reputation]

Offline Offline

Posts: 74


codemonkey


« Reply #121 on: June 27, 2010, 03:37:11 AM »

quick drawing of what you just said:





as you can see this has no intelligence at all, it does just low level timmings and pin settings. also note that error control is not here. this is done in the 4rd cycle, error control is done in 3rd cycle, and we can check motor state to know what to check (first time ADC drain will be read ~250us-500us after fet is set, and actions will be taken ~750us after fet is set)
Logged
kiwi_mat
Corporal
****

Reputation Power: 6
Reputation: kiwi_mat has no influence.
[view reputation]

Offline Offline

Posts: 84



WWW
« Reply #122 on: July 01, 2010, 05:57:03 PM »

I was having a nosey at the code for the lion, from the svn repo.. I know it has not been updated for a couple of weeks, But something was bugging me, it was the use of binary values to set IO which is not very "readable" ie, I had no idea what was being set..

Values for the bit fields are defined in the appropriate ioxxxx.h..
eg, for ADMUX the bits is defined with
Code:
#define ADMUX _SFR_MEM8(0x7C)
#define MUX0 0
#define MUX1 1
#define MUX2 2
#define MUX3 3
#define MUX4 4
#define ADLAR 5
#define REFS0 6
#define REFS1 7

thus instead of
Code:
ADMUX |= 0b00000110;
the following is more usefull to someone picking up the code and reading it..
Code:
ADMUX |= (1 << MUX1) | (1 << MUX2);

I have gone through a couple of functions for an example, also re-formatted to ANSI standard (with a couple of mods)..
Code:
volatile long GetVoltage(unsigned char Sensor, unsigned char ADCRange)
{

  ADCSRA = (1 << ADPS0) | (1 << ADPS1) | (1 << ADPS2) | (1 << ADEN); //0b10000111 ; //  Setup A/D 156.25kHz clock
  unsigned long divider=0;// we set up a divider value depending on the range. default depends on the range
  // note that the values are the range in mV, 20000mV=20V
  //
  // ADCRange 0 ADCRange 1 ADCRange 2
  // trigger/drain 20000 10240 4400
  // else 5000 2560 1100
  //
  switch(ADCRange)  //select range
  {
    case 0:
      ADMUX = (1 << REFS0);
      divider=5000;
      break; //0-5V or 0-20V range
    case 1:
      ADMUX = (1 << REFS0) | (1 << REFS1); //0b11000000;
      divider=2560;
      break; //0-2.56V or 0-10.24V range
    case 2:
      ADMUX = (1 << REFS1); //0b10000000;
      divider=1100;
      break; //0-1.1V or 0-4.4V range
  }
  switch(Sensor) //select input source
  {
    case TRIGGER:
      ADMUX |= (1 << MUX0) | (1 << MUX1);// 0b00000011;
      divider=divider*4;
      break;
    case DRAIN:
      ADMUX |= (1 << MUX1); //0b00000010;
      divider=divider*4;
      break;
    case GROUND:
      ADMUX |= (1 << MUX0) | (1 << MUX1) | (1 << MUX2) | (1 << MUX3) | (1 << MUX4); // check mux4 on cpu 0b00011111;
      break;
    case AUX0:
      ADMUX |= (1 << MUX2);//0b00000100;
      break;
    case AUX1:
      ADMUX |= (1 << MUX0) | (1 << MUX2);//0b00000101;
      break;
    case AUX2:
      ADMUX |= (1 << MUX1) | (1 << MUX2);//0b00000110;
      break;
  }
  _delay_loop_1(10);//give 384ns to start the conversion TOTEST
// _delay_us(5);//give some time to the ADC to cool up
  ADCSRA |= (1 << ADSC) ;//0b01000000 ;   //  Start A/D conversion (bit 6 is set)
  // Start A/D conversion
  while (ADCSRA & (1 << ADSC))
  {
    ;    //  Test if done or wait
  }

  if(Sensor==TRIGGER) //Correct for 5K protection Resistor
  {
    return ((ADCW*divider*5)/(1023*4));
  }
  else
  {
    return ((ADCW*divider)/1023);
  }
}

//------------------------------------------------------------

void MotorPWM(char PWMduty)
{

  /* Controlling OC0A which is pin 43 PB3 to the motor drive */
  if((PWMduty != 0) && (Data.Motor.Status == mSTOP))
  {
    Data.Motor.StartTime = Data.Time.RealClock;
  }
  if((PWMduty == 0) && (Data.Motor.Status == mRUNABLE))
  {
    Data.Motor.StopTime = Data.Time.RealClock;
  }
  Brake(DISABLED);
  _delay_us(50);  //Turn off brake //TOCHECK: _delay_ms(50);
  if(PWMduty != 0)
  {
    TCCR0A = (1 << WGM00) | (1 << WGM01) | ( 1 << COM0A1); // 0b10000011;    //  Start Motor
    Data.Motor.Status = mRUNABLE;
  }
  else
  {
    TCCR0A = (1 << WGM00) | (1 << WGM01); // 0b00000011;    // Stop Motor
    Data.Motor.Status = mSTOP;
  }
  OCR0A = (char)PWMduty;  //  This is the PWM comparator test value
  TCCR0B = (1 << CS01) | (1 << FOC0A);//0b10000010;  //  9.765625kHz clock
}

//------------------------------------------------------------

void Vibrate(unsigned long Time, unsigned long Frequency, unsigned long Volume)
{

  unsigned long StartTime = 0;

  // Time in mS, Frequency = 1 to 1000 Hz, Volume = 0 to 100 %

  Brake(DISABLED);
  MotorPWM(mSTOP);
  if(Frequency > 1000)
  {
    Frequency = 1000;
  } //TOCHECK: if(Frequency > 1000) {Frequency = 10000;}
  if(Volume > 100)
  {
    Volume = 100;
  }
  StartTime = Data.Time.RealClock;
  while (Data.Time.RealClock <= StartTime + Time)
  {
    PORTB |= (1 << PORTB3) | (1 << PORTB4);// 0b00011000;  //Turn on motor
    _delay_us(Volume * 4);//TOCHECK: _delay_ms(Volume * 4);
    PORTB &= (1 << PORTB0) | (1 << PORTB1) | (1 << PORTB2) | (1 << PORTB4) |
             (1 << PORTB5) | (1 << PORTB6) | (1 << PORTB7);//   0b11110111;  //Turn off motor
    _delay_us(1000000 / (Frequency + 1));//TOCHECK: _delay_ms(1000000 / (Frequency + 1));
  }
}

//------------------------------------------------------------

void StartClock(void)
{

//  1mS real time clock setup on 16 bit timer 1
  TCCR1A = 0b00000000;
  TCCR1B = (1<<WGM12)|(1<<CS10);
  OCR1A  = 20000U;  //  20MHz clock / 20000 = 1mS
  TIMSK1 |=(1<<OCIE1A);
  Data.Time.RealClock = RESET;  //  Be sure time starts at zero
}

I have been writing my own AVR code for an "airsoft simulated bomb" and also my gun control, so getting to know the ins and outs of the libraries..

BTW, I have found code::blocks a much better IDE than the AVR one (plus it works under linux and has avr support Smiley ), give it a go.. www.codeblocks.org

Smiley
Logged

Visit Christchurch - Play @ Sport Airsoft.
www.sportairsoft.co.nz
sik_gerar
Corporal
****

Reputation Power: 6
Reputation: sik_gerar has no influence.
[view reputation]

Offline Offline

Posts: 74


codemonkey


« Reply #123 on: July 02, 2010, 12:17:48 AM »

good job!

it has not been updated, thats true, i've been working on my local copy, i can upload some changes right now, but i have been working really on the v1 instead of the old one.

i won't be home this weekend, i'm leaving now for the beach, so i cant check what you did, but it seems really handy. i will add it to the repository for good use. i like it very much, i still couldnt see where in .hs is the definition of all the ports, or why they are numbered instead of called by name, im quite used to "PORTAbits.RA1" things from PIC stuff..

I will check the IDE you say when i come back. if it is as good as you say, we should use it shouldnt we? checking its features..
Quote
Code folding for C++ and XML files.
Tabbed interface
Code completion
Smart indent
One-key swap between .h and .c/.cpp files
To-do list management with different users

I really like that!
Logged
sik_gerar
Corporal
****

Reputation Power: 6
Reputation: sik_gerar has no influence.
[view reputation]

Offline Offline

Posts: 74


codemonkey


« Reply #124 on: July 06, 2010, 09:45:40 AM »

yesterday i started testing codeblocks. it seems im really used to crappy interfaces, 'cause i like more the old one..

i am currently overloaded at work, so im spending very little time on this. don't think im resigning tho Wink
Logged
Gandolf
High Voltage Guru
Global Moderator
Colonel
*

Reputation Power: 98
Reputation: Gandolf has an aura about them.Gandolf has an aura about them.Gandolf has an aura about them.Gandolf has an aura about them.Gandolf has an aura about them.Gandolf has an aura about them.Gandolf has an aura about them.Gandolf has an aura about them.Gandolf has an aura about them.Gandolf has an aura about them.
[view reputation]

Offline Offline

Posts: 1593



WWW
« Reply #125 on: July 06, 2010, 12:12:03 PM »

Quote
But something was bugging me, it was the use of binary values to set IO which is not very "readable" ie, I had no idea what was being set..
LOL.  That is my fault for never being able to figure out what:

ADCSRA = (1 << ADPS0) | (1 << ADPS1) | (1 << ADPS2) | (1 << ADEN)

Actually meant and was doing.  Is 1 << ADPS0 the equivalent of ADPS0 = 1 but at the bit level?  and those "|" confused me too....  But I could figure out the binary  Cheesy

Of course, feel free to do everything the best and proper way.  If needed I can read more than the first 97 pages of the C book  Huh?  It is wonderful having people that really know how to program in C here now.  I really don't know C.  The highest level language I ever have formal classes in was FORTRAN.   Roll Eyes   Cheesy

Quote
yesterday i started testing codeblocks. it seems I'm really used to crappy interfaces, 'cause i like more the old one..
I often just use gedit.  It has C and C++ formating all built in even if it is the lowest level Linux text editor.  It makes very nice color printouts too.  But when I do something serious I just reboot into windoughs and run Studio 4.  But to each their own Wink

Quote
i am currently overloaded at work, so im spending very little time on this. don't think im resigning tho Wink
Cool!  Smiley  This project is only two years old and there are no deadlines  Cheesy  Unlike real work, we all do this for the fun  Grin
Logged
sik_gerar
Corporal
****

Reputation Power: 6
Reputation: sik_gerar has no influence.
[view reputation]

Offline Offline

Posts: 74


codemonkey


« Reply #126 on: July 06, 2010, 12:27:30 PM »

i use gedit to explain my sister (12yoer) how to write C code, but she gets bored quite fast. i usually run windows for other stuff, like games, orCAD, MPlab... so having avr studio is not a big deal for me.

as for bit masks.. well the best thing is 2 hours thinking and 3 lines of comments Cheesy that does the job for me. of course there is sometimes easier ways to describe the equation..
Logged
kiwi_mat
Corporal
****

Reputation Power: 6
Reputation: kiwi_mat has no influence.
[view reputation]

Offline Offline

Posts: 84



WWW
« Reply #127 on: July 06, 2010, 02:26:02 PM »

It takes time to learn, I started with C/C++ about 20 years ago, still learning it too.. One of my bugbears is picking up a project and finding it un-readable, but it takes time to learn how to write like that too..

I have been looking through the lion code, and have now developed my own AVR code for the pololu board to control the gun (with the reflectance sensor), and its working well.

I have used the code you had for vibrate and programming with a couple of tidies, i would have had trouble figuring out how to vibrate the motor as you have done..

I have figured out how to sleep the avr, the pololu board goes down to approx 5.5 mah (probably mostly the power LED) and wakes on external interrupt (trigger switch), its a nice low power state, cant remember if I saw a sleep state in the lion code..

I will be posting up on my website information about my control project sometime in the next few days (given time)..



Logged

Visit Christchurch - Play @ Sport Airsoft.
www.sportairsoft.co.nz
sik_gerar
Corporal
****

Reputation Power: 6
Reputation: sik_gerar has no influence.
[view reputation]

Offline Offline

Posts: 74


codemonkey


« Reply #128 on: July 06, 2010, 02:52:48 PM »

It takes time to learn, I started with C/C++ about 20 years ago, still learning it too.. One of my bugbears is picking up a project and finding it un-readable, but it takes time to learn how to write like that too..

I have been looking through the lion code, and have now developed my own AVR code for the pololu board to control the gun (with the reflectance sensor), and its working well.

I have used the code you had for vibrate and programming with a couple of tidies, i would have had trouble figuring out how to vibrate the motor as you have done..

I have figured out how to sleep the avr, the pololu board goes down to approx 5.5 mah (probably mostly the power LED) and wakes on external interrupt (trigger switch), its a nice low power state, cant remember if I saw a sleep state in the lion code..

I will be posting up on my website information about my control project sometime in the next few days (given time)..

Lion already has some code to power it down while iddling. we will also have it on the next version, but also reducing consumption by powering down parts we are not currently using (ports, usart...).
vibration will have to somehow change, but the idea will remain (frequency, length and duty cycle control).

do you think you could modify the sensor to be used in the Lion as an addon board? how do you use it, ADC readings?, usart?

looking forward to new information!
Logged
kiwi_mat
Corporal
****

Reputation Power: 6
Reputation: kiwi_mat has no influence.
[view reputation]

Offline Offline

Posts: 84



WWW
« Reply #129 on: July 06, 2010, 04:36:25 PM »

Quote
do you think you could modify the sensor to be used in the Lion as an addon board? how do you use it, ADC readings?, usart?


It would be simple to use on the Lion, it uses a Digital Input (there is a analog version) and the library it comes with gives values based on a range , in my case 1000 = dark, < 500 (value i have chosen) = reflect.. I power it off a digital output so its only switched on when i want to read from it..

Have a nosey at the following thread I have posted on our club forum, threre is a couple of pics,

My current code is packaged up - get it here for a look http://dl.dropbox.com/u/4995159/SharedStuff/AEGControlQTRV0.1.zip it includes the pololu library which I have used- its got some good stuff in it for i/o and devices..


« Last Edit: July 06, 2010, 05:01:27 PM by kiwi_mat » Logged

Visit Christchurch - Play @ Sport Airsoft.
www.sportairsoft.co.nz
sik_gerar
Corporal
****

Reputation Power: 6
Reputation: sik_gerar has no influence.
[view reputation]

Offline Offline

Posts: 74


codemonkey


« Reply #130 on: July 07, 2010, 09:42:30 AM »

i will have a look at your web again, as i always say any help is welcome. good to know we can use the board as an addon, that will make it a good extra for the board.

[offtopic]
today has been a good prolific day, JTLYK this is what i'm currently working at:




i know they are doing the same, its a demo software we wrote to test our prototypes under very restricted and controlled conditions. we are working on the second prototype, which is the reason I lack so much time for this project.
if you know spanish, you might like this one as well.. (one of my teachers).


[/offtopic]
Logged
kiwi_mat
Corporal
****

Reputation Power: 6
Reputation: kiwi_mat has no influence.
[view reputation]

Offline Offline

Posts: 84



WWW
« Reply #131 on: July 09, 2010, 01:50:56 AM »

some code snippet - i have redone the programming sequence as I found it a bit rough..

You will need.
Code:
#include <avr/pgmspace.h>

and at the moment i have serial debug output, so I define the strings as such..
Code:
const PROGMEM char c_ProgrammingMode[]   = "Programming Mode = 0 = no, 1 = yes\r\n";
const PROGMEM char c_Programming[]       = "Programming Mode = %d %d\r\n";

const PROGMEM char c_ProgramComplete[]   = "Program Complete\r\n";
const PROGMEM char c_MagSwitch[]         = "Mag Switch? 1 = on, 2 = off\r\n";
const PROGMEM char c_MagSwitchCount[]    = "Mag Switch = %d %d\r\n";

const PROGMEM char c_MotorSpeed[]        = "Motor Speed?  1 = 100%%, 2 = 90%%, 3 = 80%%,...  10 = 10%%\r\n";
const PROGMEM char c_MotorSpeedCount[]   = "Motor Speed = %d %d\r\n";

const PROGMEM char c_SniperDelay[]       = "Sniper Delay?  1 = None, 2 = 1 Sec, 3 = 2 Sec,... 11 = 10 Sec\r\n";
const PROGMEM char c_SniperDelayCount[]  = "Sniper Delay = %d %d\r\n";

const PROGMEM char c_BrakingOff[]       = "Brake? 1 = On, 2 = Off\r\n";
const PROGMEM char c_BrakingOffCount[]  = "Brake = %d %d\r\n";

const PROGMEM char c_DebugTriggerCount[] = "Count = %d\r\n";

const PROGMEM char c_DebugTriggerSelect[] = "Trigger Select = %d %d %d\r\n";

enum eIncDec {mINCREMENT,mDECREMENT};
I also did the enum above as I am using C++, it can be changed, if you want to leave out the debug strings, that bit can be removed.

Now, the first bit, is to define the program, using an array of structures, BTW, i use the progmem here to free up ram (and its static)..
Code:
struct ProgramItem
{
  eIncDec incdec;          // increment value or decrement
  uint8_t countstart;      // start counter vaule
  uint8_t maxcount;        // max counter value
  uint8_t defaultcount;    // default value -if no trigger press
  const char *serialDebugQ; // debug question, remove if not using serial debug
  const char *serialDebugR; // debug answer, remove if not using serial debug.
};

#define ProgramItemsCount 5
const PROGMEM ProgramItem ProgramItems[ProgramItemsCount] =
{
  {mINCREMENT,0, 1,0, c_ProgrammingMode,c_Programming},
  {mINCREMENT,0, 2,1, c_MagSwitch      ,c_MagSwitchCount},
  {mINCREMENT,0,11,1, c_MotorSpeed     ,c_MotorSpeedCount},
  {mINCREMENT,0,11,1, c_SniperDelay    ,c_SniperDelayCount},
  {mINCREMENT,0, 2,1, c_BrakingOff     ,c_BrakingOffCount},
};

you might see that there is no ID or vibrate count, i take that from the index in the array, then the programming function is reduced to..
Code:
void Programming::Program()
{

  uint8_t Count = 0;

  Motor::Vibrate(1000, 30, 50);

  for(uint8_t i = 0; i < ProgramItemsCount; i++)
  {
    Serial::printf_P((char*)pgm_read_word(&ProgramItems[i].serialDebugQ));

    VibrateSignal(i+1);

    Count = GetTriggerSelect(
                             pgm_read_byte(&ProgramItems[i].countstart),
                             pgm_read_byte(&ProgramItems[i].incdec),
                             pgm_read_byte(&ProgramItems[i].maxcount)
                            );
    if(Count == 0)
      Count = pgm_read_byte(&ProgramItems[i].defaultcount);

    uint8_t newValue;
    bool act = Action(i,Count,newValue);
    Serial::printf_P((char*)pgm_read_word(&ProgramItems[i].serialDebugR),Count,newValue);
    if(!act)
      return;
  }

  Serial::printf_P(c_ProgramComplete);
}
[code]
To set the menu value, the above calls Action, which has a simple case statement to set the menu values.

bool Programming::Action(uint8_t item, uint8_t value, uint8_t newValue)
{
  switch(item)
  {
    case 0:
      if(value == 0)
        return false;
      break;
    case 1:
      mMagSwitchEnabled = value == 1;
      newValue = value;
      break;
    case 2:
      mMotorSpeed = ((255 * (11 - value)) / 10);
      newValue = mMotorSpeed;
      break;
    case 3:
      mSniperDelay = (value - 1) * 1000;
      newValue = mSniperDelay;
      break;
    case 4:
      mBrakeEnabled = value == 1;
      newValue = value;
      break;
  }
  return true;
}
[/code]

This makes adding new items fairly simple, just add a line into "ProgramItems" and an additional case into "Action".

Smiley

I am a happy boy when coding things.. or shooting people..  Grin

Logged

Visit Christchurch - Play @ Sport Airsoft.
www.sportairsoft.co.nz
sik_gerar
Corporal
****

Reputation Power: 6
Reputation: sik_gerar has no influence.
[view reputation]

Offline Offline

Posts: 74


codemonkey


« Reply #132 on: July 09, 2010, 02:15:19 AM »

nice thing youre coding there. i wish we already had a stable version for everyone to be working at.. it will come eventually, but not this weekend (on holidays to morocco till thursday Cheesy)
Logged
kiwi_mat
Corporal
****

Reputation Power: 6
Reputation: kiwi_mat has no influence.
[view reputation]

Offline Offline

Posts: 84



WWW
« Reply #133 on: July 09, 2010, 02:19:18 AM »

lucky you, you should come to christchurch, new zealand this time of year, its raining (snowing up the hills not far away) about 4 degrees Centigrade, windchill to 1 degree, had snow on one of our fields a couple of weeks back so bad we couldnt play..

Smiley

But i do love the weather enough to ride my bike to work in it Smiley

Logged

Visit Christchurch - Play @ Sport Airsoft.
www.sportairsoft.co.nz
Montspy
Private
**

Reputation Power: 3
Reputation: Montspy has no influence.
[view reputation]

Offline Offline

Posts: 11


« Reply #134 on: July 13, 2010, 07:40:19 PM »

WOW !
That's an insane job you did !
When I started to read this topic I really thought I could help for software but after I read everything, I don't think you need more guys on this... It doesn't matter, I really want to help  Tongue
I'm learning C/C++ for 5 years now but most of the time it was for computer. I have some basics for µC programming but I'll try to be useful ! Cheesy

Montspy.
Logged
Pages: 1 ... 7 8 [9] 10 11
  Print  
 
Jump to:

Powered by MySQL Powered by PHP Powered by SMF 1.1.11 | SMF © 2006-2009, Simple Machines LLC Valid XHTML 1.0! Valid CSS!