20
Project 3: Cal Poly Skateboard Ethan Archibald & Christina Sardo CPE 329 13 | LAB CPE 329 14 Spring 2015 Dr. Oliver System Requirements The goal of this project was to create an electrically powered skateboard where the speed of the skateboard would be controlled by the rider’s body position and weight distribution on the board. The skateboard senses the weight distribution of the rider and from this distribution actuates a motor. System Specifications To accomplish this task certain specifications were set.. The skateboard needed to be able to withstand the weight of a person of 200 pounds. The skateboard needed to achieve a max velocity of ten miles per hour. Another specification of this system was that a rider should have fifteen minutes of ride time and be able to travel more than twenty feet. System Architecture This pressure sensitive skateboard used a microcontroller with various hardware components interfaced to capture the changing of a rider’s weight distribution on the board into a viable computer program. In order to do so, two force sensitive resistors (FSR) were used to measure and then send to the micro controller a varying analog voltage. The comparison of the two values would be used to determine the speed of the skateboard. When a rider stands on the skateboard, his/her weight is recorded and it is assumed that he/she is standing with an even weight distribution (half of weight is distributed on each leg). When a rider leans forward, the FSR will register the front foot holding more weight than the other and the skateboard will accelerate. When a rider leans backward, the back foot will hold the majority of the rider’s weight, and the skateboard will decelerate

P3 Archibald Sardo

Embed Size (px)

DESCRIPTION

microcontroller

Citation preview

Page 1: P3 Archibald Sardo

Project 3: Cal Poly Skateboard Ethan Archibald & Christina Sardo CPE 329 13 | LAB CPE 329 14 Spring 2015 Dr. Oliver System Requirements The goal of this project was to create an electrically powered skateboard where the speed of the skateboard would be controlled by the rider’s body position and weight distribution on the board. The skateboard senses the weight distribution of the rider and from this distribution actuates a motor. System Specifications To accomplish this task certain specifications were set.. The skateboard needed to be able to withstand the weight of a person of 200 pounds. The skateboard needed to achieve a max velocity of ten miles per hour. Another specification of this system was that a rider should have fifteen minutes of ride time and be able to travel more than twenty feet. System Architecture This pressure sensitive skateboard used a microcontroller with various hardware components interfaced to capture the changing of a rider’s weight distribution on the board into a viable computer program. In order to do so, two force sensitive resistors (FSR) were used to measure and then send to the micro controller a varying analog voltage. The comparison of the two values would be used to determine the speed of the skateboard. When a rider stands on the skateboard, his/her weight is recorded and it is assumed that he/she is standing with an even weight distribution (half of weight is distributed on each leg). When a rider leans forward, the FSR will register the front foot holding more weight than the other and the skateboard will accelerate. When a rider leans backward, the back foot will hold the majority of the rider’s weight, and the skateboard will decelerate

Page 2: P3 Archibald Sardo

After measuring the rider’s weight distribution divided amongst a front and back FSR, programming embedded into the skateboard’s micro controller would first change each FSR’s analog voltage reading into a direct current voltage via the micro controller’s built in ADC converter. That weight distribution reading, would then be scaled to a Pulse Width Modulation (PWM) duty cycle value which would accelerate the motor to an appropriate degree. The overall flow chart for the program is shown in Figure 1. After initialization of the ADC and PWM, the program polls for readings from the FSR and will then increase or decrease the PWM duty cycle value depending on whether the voltage reading is larger in the front or back (as more load is applied to the FSR, the resistance decreases thus increasing the voltage).

Figure 1. Overall Flowchart for the Cal Poly Skateboard (CPS).

Figure 2 shows the overall circuit diagram of the system. The front and back FSR were connected to the ADC channels of the ATmega 328p microcontroller on pins PC0 and PC1 respectively. The PWM output signals PWM and DIR were sent to the motor controller (Cytron MD10C) via pins PD5 and PD6. The motor controller would then amplify the PWM signal from an external 24 V DC battery source to a higher voltage and current and send that increased signal to a 24 V DC motor (MY69).

Page 3: P3 Archibald Sardo

Figure 2. Overall Circuit Diagram of CPS.

Page 4: P3 Archibald Sardo

Component Design There were seven (microcontroller, FSR, 100K resistor, motor controller, 9V battery, 24V battery, and 24V DC motor) different electrical hardware components needed for this pressure sensitive electrical skateboard which are described below. Microcontroller The microcontroller used was an ATmega328p. The ATmega328p was selected because of its extensive compatible built in peripherals, capabilities, and extended online user generated help and how­to forums ­ as it is found on the popular Arduino. The ATmega 328p had necessary features including sufficient ADC channels to read the FSRs. Also, the built in timers within the microcontroller can be set to PWM modes.

Force Sensitive Resistor (FSR) Flexiforce force sensitive resistor pads were chosen due to ease of packaging and relative ease of implementation, see Figure 3.. The FSRs were capable of measuring loads of up to 50kg.

Figure 3. FlexiForce Force Senstive Resistor.

Motor Controller For simplicity and ease of troubleshooting, a Cytron 10A motor controller board 10A DC motor driver was selected and is shown below in Figure 4.

Page 5: P3 Archibald Sardo

Figure 4. Cytron 10A motor controller board

Features include bi­directional control for a single motor, and continuous 13A control. and able to accept voltages ranging from 5 to 25 V. The interfacing is done with a directional logic signal and pulse width modulation (PWM) for speed control.

24 V Powerizer DC battery NiMH battery The 24 V DC battery provided sufficient power needed by the 24 V DC motor, see Figure 5. NiMH was a suitable battery type since it is better for higher discharge type applications and allows for recharging while still being less expensive than more efficient Li battery based types.

Page 6: P3 Archibald Sardo

Figure 5. 24V DC 3300mAH NiMH battery pack

9V DC Battery An external 9V DC type battery was used to supply power to the microcontroller. (this component is not shown in the system circuit diagram shown on Figure 2).

24 V DC Brushed 100W motor This motor (model: MY69) was selected for its relative low cost and adequate torque output for a prototype purpose, see Figure 6.

Figure 6. 24V 100W DC Brush Permanent Magnet Motor

Page 7: P3 Archibald Sardo

Project Code Listing Figure 7 is the initialization function for the Pulse Width Modulation used to output to the motor. The group began by using the code given in the PWM tutorial4 in class as a base and then edited it in order to have it fit this project’s needs. After looking at the ATmega datasheet (p. 108) the group decided to leave the TCCR0A value set to Fast PWM mode in order to have timer count from 0­255 (the 255 value is due to using the 8­bit timer0). The alternative, Phase Correct PWM mode, would have the timer count up to 255 and then back down again, which is not what the project needed, as the group wanted the skateboard to accelerate to it’s maximum speed and then remain there until the rider chose to decelerate. For the TCCR0B value, the group initially started with the prescalar set to 64 (TCCR0B = 3), but after ride testing determined that dividing the clock by that factor slowed down the acceleration to a point where it was difficult for the rider to start from rest, so the group lowered the prescalar to 8 in order to increase the acceleration at a faster rate and have a higher maximum velocity (p. 112). Finally the group initialized the OCR0A value to 0 to have the board start at rest and remain there until the rider chose to accelerate and begin increasing the OCR0A value. The group also originally included an OCR0B value that was linked to PD6 to move the motor backwards, but after testing the group determined it was too difficult for the rider (and thus impractical) to make the skateboard move backwards and they removed the OCR0B value from the code.

Figure 7. Initialization of the registers for PWM

Figure 8 shows the initialization of registers related to the analog­to­digital converter. The function begins by initializing the ADCSRA (ADC Control and Status Register A). The bits are set to enable the ADC (bit 7), and set the ADC prescalar to system clock / 128 (p 266). Note that the the ADC start conversion bit (bit 6) is not yet set, and will only be set to high in the main function when the program is reading from the sensors.

Page 8: P3 Archibald Sardo

For this project, enabling and using ADC interrupts was not necessary. Because of this, ADCSRB is also cleared because there is no interrupt flag that will trigger a conversion (p 267) as it is triggered manually in the main. The ADMUX register is initialized to reading for channel ADC0, and will be swapped every time the Swap_ADC() function is called (see following Figure ## for more information).

Figure 8. Initialization of the registers for ADC

One problem that the team ran into when creating the project was that the ATMega can only read from one ADC input at a time. Because the skateboard required two sensors (a front and a back), a MUX (see Figure 9) was needed to quickly alternate reading from two different pins. The group used a global variable swap that toggles every time the Swap_ADC() function is called that specifies which analog input pin to read from. The pin is specified with the ADMUX register. Because the two sensors were connected to pins ADC0 and ADC1, the two values used for ADMUX is 0x00 and 0x01 (p 265). In addition, the Digital Input Disable Register 0 (DIDR0) is adjusted according to which channel is currently not being read in order to have the pin to always be read as zero when the bit is set and the digital input from the pin is not needed (p 268).

Page 9: P3 Archibald Sardo

Figure 9. Function to swap pins for ADC input

The accelerateMotor and decelerateMotor functions (Figure 10) are used to change the “speed” of the motor. Because a DC motor such as the one used in this project is either fully “on” or fully “off,” pulse width modulation was needed in order to control the amount of power output to it thus increase it’s speed. The team decided to only have the motor move forward, thus only one timer value (OCR0A) was needed. To accelerate the motor, the OCR0A is incremented, until it reaches its max value of 255, where it remains constant until the decelerate function is called. Originally, the OCR0A value was always incremented by 1, however after testing the board by riding it the group found that the board accelerated from rest too slowly, thus making it difficult for the rider to remain balanced. To counter this, a conditional was added that increased the OCR0A at a quicker rate (+=10) when the OCR0A values are lower (less than 100) in order to accelerate the skateboard quickly and then returned to only increasing at a factor of +=1 once the skateboard gained some momentum. Similarly, for decelerateMotor, the group started by decrementing the OCR0A value by 1 each time the function was called, but after test riding the board the team quickly realized that the it was decelerating too slowly and the rider was unable to stop in time to prevent from crashing. Thus, the decrement value was increased to ­=5 until the OCR0A value becomes so low that it is unable to decrement any more without becoming negative, where it is set to 0 (board is at rest).

Page 10: P3 Archibald Sardo

Figure 10. Functions to accelerate and decelerate motors

The majority of the program logic is found within the while loop of the main function (Figure 11). The loop constantly polls for a reading from either one of the sensors based on the global swap variable set in the Swap_ADC()function. The loop begins by starting the Analog to Digital conversion by setting the ADCSRA (ADC Control and Status Register A). The bits are set to enable the ADC (bit 7), start the ADC conversion (bit 6), and set the ADC prescalar to system clock / 128 (p 266). For this project, enabling and using ADC interrupts was not necessary. The ADCSRA register initialization is then followed by a software delay of 260us in order to ensure a sufficient sampling time for the ADC channel and reference selection to be read before potentially attempting to read the next conversion with different settings (p 257). The group decided to keep the 260us value that Dr. Oliver used in the ADC tutorial because it was already proven to be a sufficient amount of time through completing the tutorial. The voltage from one of the sensors is then read using the bottom 12 bits of the ADC and the value is stored in the 16 bit unsigned int value voltage. Then, based on whatever the swap value is set to (which is set in the Swap_ADC() function that determines which sensor the input was read from) the value of voltage is set to either forwardVoltage (voltage read from the front sensor) or backwardVoltage (voltage read from the back sensor). The forward and backward

Page 11: P3 Archibald Sardo

voltages are then compared and based on whichever is greater the program either calls the accelerateMotor() or decelerateMotor() function to change the speed of the motor. The usart_send(char) function was used for debugging purposes when attempting to read input from the two sensors at every stage of the project’s development. The group used the PuTTY terminal and outputted either an ‘A’ for accelerate, ‘D’ for decelerate, or ‘N’ for neutral to help determine what the sensors were reading and what the output to the motor should be. The usart_send function was taken from the USART tutorial3 unedited.

Page 12: P3 Archibald Sardo

Figure 11. The while loop in the main polling for sensor input

Other Notes on the C Code: Both the usart_init() and the usart_send() functions were taken straight from the USART Tutorial for debugging purposes and not used in the final code. Because the usart_send function sends the output through the USB port, no code edits were needed for pins to be changed. Based on the code the value is also outputted to PD1, but because the pin was not used at any other point in the code, it did not affect the final project. System Integration SKATEBOARD DESIGN The skateboard was shaped and built from 3/2’’ pinewood. A one­wheel rear chain geared drivetrain was mainly chosen for its eccentric reasons. The FSRs are mounted on top of the board below a rectangular cut off. The rectangular cut out has standoffs mounted underneath in order to ensure the total load of the rider is placed on the FSRs, see Figure 12 and 13. The remaining hardware was mounted below the skateboard to provide a cleaner finish and allow the rider to step freely on the top of the board, see Figure 14.

Figure 12. Top View of the skateboard with rectangular load plate.

Page 13: P3 Archibald Sardo

Figure 13. FSR mounting underneath rectangular load plate.

Figure 14. View from below showing all the hardware (except FSRs).

PROGRAM DESIGN The coding portion of the project was broken up into two pieces: reading the input from the sensor and then outputting the appropriate voltage to the motor. The team began by simply using a single FlexiForce A201 Pressure Sensor as an input and putting the voltage read in a PuTTY. After checking the pressure sensor’s data sheet2, the group found that there was no initialization sequence necessary to read the input from the sensor. Thus, all the team had to do was read the voltage input from the sensor using ADC. To do so, first the team used the ADC tutorial3 supplied in class as a base and then combined that tutorial with the UART tutorial.4 One issue the team faced was that they forgot to connect 5V to the AREF pin on the ATMega, and spent numerous hours

Page 14: P3 Archibald Sardo

attempting to debug both the hardware and the code because the sensor was not reading any input. After discovering the issue by speaking with Dr. Oliver, the team was able to read data from the sensor with the code created from the combination of the ADC and USART tutorials. The next portion of the code was outputting a signal to the motor. Because the ATMega328p can only output 5V, the team discovered that a motor driver was needed in order to send an adequate signal to the motor. The team decided that the best driver to use was the Cytron 10A motor controller board 10A DC motor driver. To control the speed of the the motor the team realized that it was necessary to use pulse width modulation (PWM) after reading about the benefits and uses of PWM in the PWM tutorial4. The group then phased in portions of the tutorial to the sensor input code and tested the output with an LED. After verifying the code worked with the LED, the group then connected the output to the motor driver, which was also connected to the motor itself. After riding the skateboard to test out the timing, the group determined that using the 8­bit TIMER0 was sufficient and it was not necessary to divide the clock further using the 16­bit TIMER1. In fact, the team realized that the acceleration (at least when accelerating the board from 0) was a bit slow and thus difficult for the rider to stay balanced, so the team edited the code to accelerate at a faster rate for the lower OCR0A values. Conclusion This project, although challenging at times, taught the team about how analog to digital conversion can be used to read input values from any sensor and further reinforced the advantages of pulse width modulation when it comes to controlling the amount of power delivered to a load such as a motor. The largest setback the team faced was the day before the project was due the motor driver fried due to the battery used to power the motor outputting too high of a voltage for the driver to handle (the driver could support up to 25V, and the battery supplied 27V). The group did not have suitable power protection/voltage regulation between that and the driver, thus in hindsight the driver frying should not have come as a surprise. However, because the team have been testing the skateboard up until that point with good results, they decided to order another driver and record a video demo at a later date with the new replacement driver. Luckily, in the end the group did eventually get the skateboard functional again and a video demo was recorded and submitted to Dr. Oliver. Appendices

Page 15: P3 Archibald Sardo

C Code: /* * Project 3 ­ FInal Project: Cal Poly Skateboard * * This code reads in sensor input from two pressure sensors using * ADC and then outputs a signal to a motor using PWM. * * Authors: Ethan Archibald and Christina Sardo */ #define BAUD_PRESCALE 103 #define F_CPU 16000000 #include<stdlib.h> // Standard C library #include<avr/io.h> #include<util/delay.h> //prototypes void Initialize_ADC0(void); void Swap_ACDC(void); void usart_init(uint16_t baudin, uint32_t clk_speedin); void usart_send( uint8_t data ); void initPWM(); void accelerateMotor(void); void decelerateMotor(void); //global variables uint8_t swap; int main(void)

uint8_t forwardVoltage = 0, backwardVoltage = 0; uint16_t voltage = 0; swap = 0; DDRB = 1 << 5; // Set PB5 output

Initialize_ADC0(); // Initialize ADC0 for manual trigger usart_init(9600, 16000000 ); //initialize usart initPWM(); OCR0B = 0;

Page 16: P3 Archibald Sardo

while(1)

ADCSRA = 0xC7; // start conversion

_delay_us(260);// ensure max sampling rate not exceeded

voltage = ADC & 0x3FF; // read voltage

//polling for input voltage if (swap == 0)

forwardVoltage = voltage; else

backwardVoltage = voltage; if (forwardVoltage > backwardVoltage) //accelerate

usart_send('A'); accelerateMotor();

else if (backwardVoltage > forwardVoltage) //decelerate

usart_send('D'); decelerateMotor();

else //Else the pressures are equal, hold same speed

usart_send('N'); Swap_ACDC();

_delay_ms(50);

return 0;

void Initialize_ADC0(void)

ADCSRA = 0x87; //Turn On ADC and set prescaler (CLK/128)

ADCSRB = 0x00; //turn off autotrigger

ADMUX = 0x00; //Set ADC channel ADC0

Page 17: P3 Archibald Sardo

void Swap_ACDC(void)

if (swap == 1) ADMUX = 0x00; //Set ADC channel ADC0 DIDR0 = 0x01; swap = 0;

else

ADMUX = 0x01; //Set ADC channel ADC1 DIDR0 = 0x02; swap = 1;

void usart_init(uint16_t baudin, uint32_t clk_speedin)

uint32_t ubrr = (clk_speedin/16UL)/baudin­1;

UBRR0H = (unsigned char)(ubrr>>8);

UBRR0L = (unsigned char)ubrr;

/*UBRR0H = (BAUD_PRESCALE>>8);

UBRR0L = BAUD_PRESCALE;*/

/* Enable receiver and transmitter */

UCSR0B = (1<<RXEN0)|(1<<TXEN0);

/* Set frame format: 8data, 1stop bit */

UCSR0C = (0<<USBS0)|(3<<UCSZ00);

UCSR0A &= ~(1<<U2X0); /*the send function will put 8bits on the trans line. */

Page 18: P3 Archibald Sardo

void usart_send( uint8_t data )

/* Wait for empty transmit buffer */

while ( !( UCSR0A & (1<<UDRE0)) );

/* Put data into buffer, sends the data */

UDR0 = data; void initPWM()// initializes motors

TCCR0A = 0b10100011; //timer set to fast pwm TCCR0B = 2; //timer clk = system clk / 8; //outputs 16E6/64/255 = 980Hz PWM OCR0A = 0; //compare value => 20% duty cycle to PD5

void accelerateMotor(void)

if(OCR0A + 1 > 255) OCR0A = 255;

else

if (OCR0A < 100) OCR0A += 10;

else OCR0A += 1;

void decelerateMotor(void)

if(OCR0A ­ 5 < 0) OCR0A = 0;

else

OCR0A ­= 5;

Page 19: P3 Archibald Sardo

USER MANUAL The following is a succinct user manual on how to operate the Cal Poly Skateboard (CPS ­ “what can a free ride do for you’’). DISCLAIMER: The writers of this manual are in no way responsible for the misuse of this transportation system, including mishandling and/or falling from the skateboard itself. An expert in each respective individual component should be consulted before use. To Ride: Insert the external power jack connected to the 9V battery into the ATmega 328p microcontroller. Then stand up on the board. To accelerate/decelerate: While standing on the board, shift your weight onto your front foot to accelerate or shift your weight to your back foot to decelerate. If the skateboard does not move after attempting the above, follow the given procedure:

1st ­ Check to see if the 9V battery is still maintaining charge. This is done by attaching a multimeter and measuring if the battery is still outputting near 9V. If not, replace the battery with an equivalent battery and then reattempt to ride and accelerate the skateboard.

2nd ­ If after verifying the proper voltage for the 9V external microcontroller battery and if the skateboard still does not move, check to see whether the 24V battery is charged. Warning: Do not allow the positive and negative wires of the 24V battery to connect and make contact with each other. Disconnect the 24V battery pack from the motor controller screw terminals and measure the voltage. Charge the battery pack with a smart charger that is capable of charging a 24V NiMH battery pack with 20 cells. Reattempt to ride and actuate the skateboard.

3rd ­ If the skateboard still does not move, send your skateboard to a certified CPS repair shop for a free repair under warranty*.