go_away

Author Topic: Basic to C syntax conversion  (Read 3035 times)

0 Members and 1 Guest are viewing this topic.

Offline vidamTopic starter

  • Supreme Robot
  • *****
  • Posts: 423
  • Helpful? 1
  • Robotronics.org
Basic to C syntax conversion
« on: June 23, 2008, 12:33:55 PM »
Hi,

I posted this question on AVRfreaks so it is a race to see which forum gives me the best answer. he he he

I'm trying to convert this BASIC syntax code to C. I need to know which registers to manipulate to do this conversion:

PULSEIN returns the number of units between 2 occurrences of an edge of a pulse.

PULSEIN var, PINX, PIN, State

1. var - a word variable that is assigned with the result.
2.) PINX - a pin register like PIND.
3.) PIN - the pin number (0-7) to get the pulse time of.
4.) STATE - may be 0 or 1. 0 means sample 0 to 1 transition.
1 means sample 1 to 0 transition.

I'm using an ATmega168.

Thanks in advance,

Offline vidamTopic starter

  • Supreme Robot
  • *****
  • Posts: 423
  • Helpful? 1
  • Robotronics.org
Re: Basic to C syntax conversion
« Reply #1 on: June 23, 2008, 03:28:11 PM »
The answer is related to the Input capture pin (ICP1) or on the Analog comparator output (ACO). I'm investigating further on the datasheet....


Offline vidamTopic starter

  • Supreme Robot
  • *****
  • Posts: 423
  • Helpful? 1
  • Robotronics.org
Re: Basic to C syntax conversion
« Reply #2 on: June 24, 2008, 12:22:10 PM »


Ok forget all the Basic to C conversion questions.

In plain English I just want to measure the pulse width of an incoming PWM signal using a Timer/Counter on the atmega168.

Here is some pseudo-code:
Set the timer/counter clock source and prescaler value

Set the top value for the ICR1

Set ICESI to capture edge on the rising edge

Read the timestamp at the rising edge by reading ICR1 into unsigned int variable s1

Set ICESI to capture trigger on falling edge

Read the timestamp at the falling edge by reading ICR1 into unsigned int variable s2;

pulse-width = s2-s1

Check Timer/Counter for overflow.

Repeat steps above


Does this seem reasonable?





« Last Edit: June 24, 2008, 03:14:06 PM by vidam »

Offline airman00

  • Contest Winner
  • Supreme Robot
  • ****
  • Posts: 3,653
  • Helpful? 21
  • narobo.com
Re: Basic to C syntax conversion
« Reply #3 on: July 24, 2008, 08:15:04 AM »
check the source code by the PING ultrasonic sensor in C. If I recall correctly the PING sensor used the PULSIN command in BASIC. Just check how they did it there.
Check out the Roboduino, Arduino-compatible board!


Link: http://curiousinventor.com/kits/roboduino

www.Narobo.com

Offline vidamTopic starter

  • Supreme Robot
  • *****
  • Posts: 423
  • Helpful? 1
  • Robotronics.org
Re: Basic to C syntax conversion
« Reply #4 on: July 24, 2008, 08:30:27 AM »
This was solved some time ago. Here is the answer:
Basic:
Code: [Select]
Pulsein Scratch , Pind , 4 , 1

converted to the following:

C:
Code: [Select]
// Estimate pulse width using timer2
void pinChangeIntrSetup(void)
{
short index;

// Set up pin change monitor for pins 17(FLIP), 20(RIGHT), 21(LEFT)
PCMSK2 = 0;
PCMSK2 |= (1<<PCINT17);  // Set pin change mask for FLIP
PCMSK2 |= (1<<PCINT20);  // set pin change mask for RIGHT
PCMSK2 |= (1<<PCINT21); // Set pin change mask for LEFT
for(index=0; index<3; index++){
pulseWidth[index] = 0;
inStatus[index] = 0;
}
PCICR = (1<<PCIE2); // Enable pin change interrupt
}

// interrupt for detecting pin state changes
ISR (PCINT2_vect)
{
if(FLIP_IS_LOW) // Negative egde transition -- end of pulse
inStatus[FLIPIN] = DVALID;
else { // Positive edge transition (start of pulse) -- init pulse width
inStatus[FLIPIN] = MACTIVE;
pulseWidth[FLIPIN] = 0;
}

// we only care if there was a change from 0 to 1
if(RIGHT_IS_LOW)
inStatus[RIGHTIN] = DVALID;
else {
inStatus[RIGHTIN] = MACTIVE;
pulseWidth[RIGHTIN] = 0;
}

// we only care if there was a change from 0 to 1
if(LEFT_IS_LOW) {
inStatus[LEFTIN] = DVALID;
}
else {
inStatus[LEFTIN] = MACTIVE;
pulseWidth[LEFTIN] = 0;
}

// PCIFR &= (1 << PCIF2); // Done automatically when ISR is executed
}

#define TIMER2_PERIOD (256-78) // Full count yields 128*78 = 9984usec (9.984msec)
ISR (TIMER2_OVF_vect)
{
TCNT2 = TIMER2_PERIOD; // start clock at t=0
if(inStatus[FLIPIN] & MACTIVE) pulseWidth[FLIPIN]++;
if(inStatus[RIGHTIN] & MACTIVE) pulseWidth[RIGHTIN]++;
if(inStatus[LEFTIN] & MACTIVE) pulseWidth[LEFTIN]++;
// TIFR2 &= (1 << TOV2); // Done automatically when ISR is executed

}

// Setup Timer 2 to generate an interrupt every 32usec
#define TIMER2_CONFIG ((1 << CS20) | (1 << CS21) | (1 << CS22))  // Prescalor = 1024 --> resolution = 128usec
void timer2Setup(void)
{
TCCR2B = 0;
TCNT2 = TIMER2_PERIOD; // Start clock at t=0
TCCR2B |= (1 << CS22);  // Prescale clock at 256
TIMSK2 |= (1 << TOIE2); // Enable check for overflow of timer/counter 2
}


Offline pomprocker

  • Supreme Robot
  • *****
  • Posts: 1,430
  • Helpful? 16
  • Sorry miss, I was giving myself an oil-job.
Re: Basic to C syntax conversion
« Reply #5 on: July 24, 2008, 09:54:16 AM »
Vidam,

check my post under $50 Robot Ping Sensor

you would find explanation and code for doing it with the capture unit and for on an ATMega8/168.


http://www.societyofrobots.com/robotforum/index.php?topic=4656.0

Also have a member tutorial about this:

http://www.societyofrobots.com/member_tutorials/node/174
« Last Edit: July 24, 2008, 09:55:54 AM by pomprocker »

Offline vidamTopic starter

  • Supreme Robot
  • *****
  • Posts: 423
  • Helpful? 1
  • Robotronics.org
Re: Basic to C syntax conversion
« Reply #6 on: July 24, 2008, 10:25:32 AM »
Pomprocker,

Thanks but the code posted here is working perfectly. So there isn't any need for me to look at yours at this time.

Offline Admin

  • Administrator
  • Supreme Robot
  • *****
  • Posts: 11,632
  • Helpful? 169
    • Society of Robots
Re: Basic to C syntax conversion
« Reply #7 on: July 26, 2008, 05:13:57 PM »
If you were using the ATmega168 ($50 robot code) or the Axon, see here:
http://www.societyofrobots.com/axon/axon_function_list.shtml#timers
http://www.societyofrobots.com/axon/axon_function_list.shtml#digital_input

You just need 4 lines of code:

Code: [Select]
//Axon
cbi(DDRG, PG5);  //set G5 as input pin
reset_timer_0();//set timer to zero
while(bit_is_clear(PING, 5));  //wait while pin is low
elapsed_time=timer0GetOverflowCount()*255+TCNT0;//store timer value

Code: [Select]
//$50 Robot with ATmega168
cbi(DDRC, PC5);  //set C5 as input pin
reset_timer();//set timer to zero
while(bit_is_clear(PINC, 5));  //wait while pin is low
elapsed_time=timer0GetOverflowCount()*255+TCNT0;//store timer value

(yeap, the Axon makes life easier ;D)

You can also use a hardware interrupt in the place of the while loop if you don't want to wait for sloooowww sonar.

Offline pomprocker

  • Supreme Robot
  • *****
  • Posts: 1,430
  • Helpful? 16
  • Sorry miss, I was giving myself an oil-job.
Re: Basic to C syntax conversion
« Reply #8 on: July 26, 2008, 05:55:20 PM »
admin, you could actually use your predefined macros instead of cbi, etc...

PORT_OFF(DDRC, 5);  // sets pin 5 on port c as input

loop_until_bit_is_set(PINC, 5);     // Loop until the the Pin goes high  (macro found in sfr_def.h)

reset_timer_0();       //reset timer 0

loop_until_bit_is_clear(PINC, 5);     // Loop until the the Pin goes low  (macro found in sfr_def.h)

//read timer0's overflow counter
//255 is count before overflow, dependent on clock
int elapsed_time=timer0GetOverflowCount()*255+TCNT0;

« Last Edit: July 26, 2008, 05:58:17 PM by pomprocker »

Offline vidamTopic starter

  • Supreme Robot
  • *****
  • Posts: 423
  • Helpful? 1
  • Robotronics.org
Re: Basic to C syntax conversion
« Reply #9 on: July 26, 2008, 07:48:51 PM »
As I said, the solution I posted works perfect, and plus it was a good learning experience for me to see this done at the port, pin, register, bit/byte level of detail. So now when I see stuff like Admin's code, I know what the code is doing on the register, port, pin, byte and bit level.

Offline Admin

  • Administrator
  • Supreme Robot
  • *****
  • Posts: 11,632
  • Helpful? 169
    • Society of Robots
Re: Basic to C syntax conversion
« Reply #10 on: July 26, 2008, 08:49:42 PM »
oops thanks pomprocker for pointing out my errors ;D

Code: [Select]
//Axon
cbi(DDRG, PG5);  //set G5 as input pin
while(PORT_IS_OFF(PING, 5));  //wait till pin goes high
reset_timer_0();//set timer to zero
while(PORT_IS_ON(PING, 5));  //wait till pin goes low
elapsed_time=timer0GetOverflowCount()*255+TCNT0;//store timer value

Offline pomprocker

  • Supreme Robot
  • *****
  • Posts: 1,430
  • Helpful? 16
  • Sorry miss, I was giving myself an oil-job.
Re: Basic to C syntax conversion
« Reply #11 on: July 27, 2008, 02:26:16 AM »
you also don't have to use the while loops, because an optimized compiler would take out that empty loop without a nop in it.

you could just use those loop macros in sfr_defs.h

Offline Admin

  • Administrator
  • Supreme Robot
  • *****
  • Posts: 11,632
  • Helpful? 169
    • Society of Robots
Re: Basic to C syntax conversion
« Reply #12 on: July 27, 2008, 07:34:47 AM »
hmmmm I always turn off optimization . . . it always breaks my code :P

 


Get Your Ad Here

data_list