Society of Robots - Robot Forum

Software => Software => Topic started by: pomprocker on July 14, 2008, 03:58:44 PM

Title: atmega168 upgrade
Post by: pomprocker on July 14, 2008, 03:58:44 PM
upgrading from atmega8 to 168

running across some problems...attaching screenshot of the errors, and heres my code:
Code: [Select]
/****************************************************************************
*
*   Copyright (c) 2007 www.societyofrobots.com
*   (please link back if you use this code!)
*
*   This program is free software; you can redistribute it and/or modify
*   it under the terms of the GNU General Public License version 2 as
*   published by the Free Software Foundation.
*
*   Alternatively, this software may be distributed under the terms of BSD
*   license.
*
* SoR Utilities v1, March 10th, 2007
*
****************************************************************************/



//AVR includes
#include <avr/io.h>     // include I/O definitions (port names, pin names, etc)
#include <avr/interrupt.h> // include interrupt support
#include <avr/wdt.h>        // include watchdog timer

//AVRlib includes
#include "global.h" // include global settings
#include "buffer.h" // include buffer function library
#include "uart.h" // include uart function library
#include "rprintf.h" // include printf function library
#include "timerx8.h" // include timer function library (timing, PWM, etc)
#include "a2d.h" // include A/D converter function library


// For newer AVRs such as ATmega1281
// Function Pototype
int MCUSR;
void wdt_init(void) __attribute__((naked)) __attribute__((section(".init3")));

// Function Implementation
void wdt_init(void)
{
    MCUSR = 0;
    wdt_disable();

    return;
}


// Macros

//define port functions; example: PORT_ON( PORTD, 6);
#define PORT_ON( port_letter, number ) port_letter |= (1<<number)
#define PORT_OFF( port_letter, number ) port_letter &= ~(1<<number)
#define PORT_ALL_ON( port_letter, number ) port_letter |= (number)
#define PORT_ALL_OFF( port_letter, number ) port_letter &= ~(number)
#define FLIP_PORT( port_letter, number ) port_letter ^= (1<<number)     // toggle port
#define PORT_IS_ON( port_letter, number ) ( port_letter & (1<<number) )
#define PORT_IS_OFF( port_letter, number ) !( port_letter & (1<<number) )



// soft reset macro using watchdog timer
#define soft_reset()        \
do                          \
{                           \
    wdt_enable(WDTO_15MS);  \
    for(;;)                 \
    {                       \
    }                       \
} while(0)








//************CONFIGURE PORTS************
//configure ports for input or output - specific to ATmega8
void configure_ports(void)
{
DDRC = 0x00;  //configure all C ports for input
PORTC = 0x00; //make sure pull-up resistors are turned off
DDRD = 0xFF;  //configure all D ports for output
rprintf( "\n\n\t\t\tPorts Configured.\n\n" );
}
//***************************************

//************DELAY FUNCTIONS************
//wait for X amount of cycles (23 cycles is about .992 milliseconds)
//to calculate: 23/.992*(time in milliseconds) = number of cycles
//or (number of cycles)*.992/23 = time in milliseconds
void delay_cycles(unsigned long int cycles)
{
while(cycles > 0)
cycles--;
}
//***************************************

//**************RESET TIMER**************
void reset_timer_0(void)
{
//restart timer count
TCNT0=0x00;//clear timer
timer0ClearOverflowCount();//clear timer0's overflow counter.
}
//***************************************

//*********SIMPLIFIED FUNCTIONS**********
//functions to make coding easier for a beginner
//but could cause port mixup confusion for intermediate users
void LED_on(void)
{
PORT_OFF(PORTD, 4);//turn LED on
}
void LED_off(void)
{
PORT_ON(PORTD, 4);//turn LED off
}
void servo_left(signed long int speed)
{
PORT_ON(PORTD, 2);
delay_cycles(speed);
PORT_OFF(PORTD, 2);//keep off
delay_cycles(1600); // 200 * 8
}
void servo_right(signed long int speed)
{
PORT_ON(PORTD, 3);
delay_cycles(speed);
PORT_OFF(PORTD, 3);//keep off
delay_cycles(1600); // 200 * 8
}
void servo_scan(signed long int speed)
{
PORT_ON(PORTD, 4);
delay_cycles(speed);
PORT_OFF(PORTD, 4);//keep off
delay_cycles(1600); // 200 * 8
}
void robot_turn_left(void)
{
servo_left(200); // 25 * 8
servo_right(200); // 25 * 8
}
void robot_turn_right(void)
{
servo_left(352); // 44 * 8
servo_right(352); // 44 * 8
}
void robot_go_straight(void)
{
servo_left(200); // 25 * 8
servo_right(352); // 44 * 8
}
void hold_position(void)//37
{
servo_left(312);//39 * 8
servo_right(280);//35 * 8
}
//***************************************

//*************INITIALIZATIONS***********
void initialize(void)
{
//other stuff Im experimenting with for SoR
uartInit();  // initialize the UART (serial port)
uartSetBaudRate(57600);// set the baud rate of the UART for our debug/reporting output
rprintfInit(uartSendByte);// initialize rprintf system


timer0Init(); // initialize the timer system

configure_ports(); // configure which ports are analog, digital, etc.
a2dInit(); // initialize analog to digital converter (ADC)
a2dSetPrescaler(ADC_PRESCALE_DIV32); // configure ADC scaling
a2dSetReference(ADC_REFERENCE_AVCC); // configure ADC reference voltage

rprintf("\t\t\tInitialization Complete\n\n");
}
//****************************************


void resetChip(int delayTime) {
   /* if the project does not typically receive data, and accidental chip resets are tolerable,
   * this is a simple method that should work just fine. Otherwise it is recommended that the
   * reset request string be part of a call-response sequence, be transmitted with a
   * reserved byte or byte string, or be transmitted in some way out of band, so that it is not
   * accidentally received.
   */
   
   rprintf("\nMCU will reset in ");
   rprintf("%d milliseconds...\n\r", (int)((delayTime *.992)/184));
   delay_cycles(delayTime); // wait for the specified amount of time, doing nothing
   rprintf("\nResetting NOW.\n\r");
   soft_reset(); // reset macro
}
Code: [Select]
/****************************************************************************
*
*   Copyright (c) 2007 www.societyofrobots.com
*   (please link back if you use this code!)
*
*   This program is free software; you can redistribute it and/or modify
*   it under the terms of the GNU General Public License version 2 as
*   published by the Free Software Foundation.
*
*   Alternatively, this software may be distributed under the terms of BSD
*   license.
*
* $50 Robot with Sharp IR using Stampy Technology v1, May 19th, 2007
* Simple case-based method for a robot to do edge detection.
*
*
****************************************************************************/

//SoR Include
#include "SoR_Utils.h" //includes all the technical stuff


//global variables
char myReceivedByte;
int sharp_IR_reading=0;
int sensor_left=0;
int sensor_right=0;
int batt=0;
int photo_thresh=8;

int scan_thresh=0;//threshold value of scanning sensor

int scan_angle=240;//position of scanner, in units of servo command -> 30 * 8
int max_scan_angle=448;//maximum position scanner can rotate to (57) -> 56 * 8


//this function causes scanning servo to center on edge of object
void scan(void)
{
//lower (-) goes right
//higher (+) goes left
//30 far right, 50 straight, 56 far left (until it jams)

/*psuedocode
object is detected
scan right object detected
object not detected
scan left until object detected*/

sharp_IR_reading=a2dConvert8bit(3);
    sensor_left=a2dConvert8bit(5);
sensor_right=a2dConvert8bit(4);
batt=a2dConvert8bit(2);
    rprintf( "Scanner: %d, \tAngle: %d, \tL Photo: %d, \tR Photo: %d, \tBatt: %d\r\n",
          sharp_IR_reading, scan_angle, sensor_left, sensor_right, batt );
   

if (sharp_IR_reading > scan_thresh)//object detected
{
if (scan_angle>328) //overflow protection -> 41 * 8
scan_angle-=16;//scan right -> 2 * 8?
}
else //object not detected
{
if (scan_angle<=max_scan_angle) //maximum servo angle
scan_angle+=16; //scan left -> 2* 8?
else //if scanned all the way, this forces it to start over
scan_angle=240;    // 30 * 8
}

//servo scan code
servo_scan(scan_angle);
}

void ping(void)
     {
     int PingPin = 0x02;// assign a pin to the Ping Sensor
     int PingVal = 0;// initialize and assign Ping Sensor Reading Value
     PORT_ON(DDRC, 1);// Switch signalpin to output
     // ------Trigger Pulse--------------
     PORT_OFF(PORTC, 1);   // Send low pulse, 0=low, 1=high
     delay_us(2);        // Wait for 2 microseconds
     PORT_ON(PORTC, 1); // Send high pulse, 0=low, 1=high
     delay_us(5);       // Wait for 5 microseconds
     PORT_OFF(PORTC, 1);; // Holdoff low
     //--------End Trigger Pulse---------------------
     FLIP_PORT(DDRC, 1);   //  Switch signalpin to input
     //clears timer, reset overflow counter
     reset_timer_0();//reset timer 0
delay_us(200);   //   wait for burst frequency to end.
     PINC = PINC | PingPin;
     while(PINC == 1) {   
          // wait until pin goes low or times out
  //asm volatile ("NOP");
          //nop();   //  to prevent an optimized compiler from removing the loop
     }
     //read timer0's overflow counter
     //255 is count before overflow, dependent on clock
     int elapsed_time=timer0GetOverflowCount()*255+TCNT0;
     PingVal = elapsed_time/93;
     } // end ping function



//automatically calculates threshold value before run
void autocalibrate(void)
{
scan_thresh=a2dConvert8bit(3);//sensor reading
}

int main(void)
{
//LED_on();

initialize();

delay_cycles(336000);//two second wait delay -> 42000 * 8

/*********ADD YOUR CODE BELOW THIS LINE **********/

//find thresholds
autocalibrate();

//LED_off();


while(1)
{




scan();
ping();

        //Object Avoider
    if (sharp_IR_reading > scan_thresh)

robot_turn_right();


//object is centered
else
robot_go_straight();
         
        /*

    object chaser
//object on left
if(scan_angle > 456)     // 57 * 8
robot_turn_left();

//object on right
else if(scan_angle < 328)    // 41 * 8
robot_turn_right();

//object is centered
else
robot_go_straight();

         */



if (uartReceiveByte(&myReceivedByte))
{
    // if there are bytes waiting on the serial port
    char inByte = uartGetByte(); // read a byte
    if (inByte == 'r')
    {
    //if that byte is the desired character
        //int len = 5; // expected string is 6 bytes long
        //char inString[len]; // declare string variable
        //for (int i = 0; i < len; i++)
        //{
        //    inString[i] = uartGetByte();
        //}
        //if ( strstr(inString, "reset") != -1 ) // check to see if the respose is "reset"
              hold_position();       // stop the robot
              delay_cycles(336000);  //two second wait delay
              resetChip(5000);       // reset the chip after waiting for the specified # of milliseconds
    } // end if
if (inByte == 'h' )
{
     hold_position();
    }
}  // end if
 



delay_cycles(3200);//a small delay to prevent crazy oscillations -> 400 * 8
}  // end while loop
/*********ADD YOUR CODE ABOVE THIS LINE **********/

return 0;
}   // end main


/*********************COMMAND LIST*************************

delay_cycles(cycles);
Delays - you can make your robot wait for a certain amount of time with this function.
Put the number of computational cycles to delay in the ().
23 cycles is about .992 milliseconds
to calculate: 23/.992*(time in milliseconds to delay) = cycles
Check servo datasheet where it says: 'Direction: Clockwise/Pulse Traveling 1500 to 1900usec'

servo_left(speed); and servo_right(speed);
Commands your servos to rotate at a certain speed.
Vary speed (which represents a delay in cycles) from 20 to 50.
Left is for port D0 and right is for port D1.

robot_turn_left(); and robot_turn_right(); and robot_go_straight();
Dont want to deal with speed?
Just call this function and it will 'just work.'

LED_on(); and LED_off();
Turns on and off your LED. The LED is on port D4.
By bringing port D4 low, you are turning on the LED.


variable=a2dConvert8bit(pin);
Reads analog pin. For example, set 'pin' to 5 to read PC5.
'variable' will store the value.

***********************************************************/




Title: Re: atmega168 upgrade
Post by: pomprocker on July 14, 2008, 07:21:39 PM
hmmm it had to do with this line I put in S0R_Utils.h

int MCUSR;
void wdt_init(void) __attribute__((naked)) __attribute__((section(".init3")));


The ATMega8 was fine with it, but the 168 doesn't like it.
Title: Re: atmega168 upgrade
Post by: pomprocker on August 11, 2008, 11:01:17 PM
MCUSR should not be an 'int' cause its a register  :-X