Saturday, January 26, 2013

Stepper Demo and Serial LCD

I have finally got my Stepper motor demo program working. As well as the problems in the last post there were a couple others. The first one of these was that I was trying to add a signed integer to an unsigned one. I fixed this which then made me realise I would have to change the number of steps for reversing from -1 and -2 to 7 and 6 respectively. This wasn't so bad but I then found that the motor was going quite slow compared to the test program. This stumped me for a while until it came to me that unsigned 8bit integer, is just that 8 bit not 8 numbers in total (4bit). So I put in an if statement that stated if the counter position was greater than 7 to remove 8 from it so to get back into the correct range of 0-7. I won't post the code in this post as I still need to tidy it up and comment it. Here is another video of the stepper motor, this time running the demo code. Basically it moves 45 degrees forward, 45 degrees back, then flashes a light (not shown) and then starts alternating going backwards and forwards 360 degrees.
The video is slightly better quality today as I took this on my camera rather than my phone. Same goes with the pictures further down the post.

So after getting the stepper motor finally working, I decided I would start on the LCD display but this time using serial communication. This started fairly well and had a good example in the manual for the chip. There was also a tutorial on AVR Freaks that helped. So I wrote all this up and sent it to the microcontroller and it started writing to the screen, the only problem was that it wasn't writing what it should have. This looked like the next picture, which looks like asian symbols but I think are just normal symbols that are part of the extended ascii sequence.
At I gave up programming and did some research before bed. I found another forum topic on AVR Freaks about UART corruption which is what I thought was happening. These posts indicated that it was most likely to do with the baud prescaller number calculated in the code. The next morning I tried moving around the number given in the manual for 8Mhz but no such luck. I had been seeming to get better results from lower numbers so I decided to try the number for 4Mhz which worked. I have no idea why it is running at 4Mhz as the fuses in AVR Studio say its running from a 8Mhz clock and not divided by 8 but there may be something I'm missing.

After fixing the communication I was finally able to turn on the back light of the LCD03-20x4. Next I managed to get some text written to the screen. With the help of this set of posts, again on AVR Freaks, I set up stdout for C to be the LCD screen and so printf now prints directly to the LCD.

I'll post the code for what I have done with the screen below. I would do a circuit schematic but really its quite obvious for the ATmega88a as there is only one UART module and so there is only one TX and one RX pin on the chip. I'm also quite tired tonight after redoing the roof on part of our house (doing the same tomorrow), so can't think what else I was going to post.

 #define BAUD_PRESCALE 51 // Started at 103 , down to 95, upto 112  
 #define USART_LCD_MAXLINES 4  
 #define USART_LCD_CHARS 20  
   
 #include <avr/io.h>  
 #include <util/delay.h>        // for _delay_ms()  
 #include <stdio.h>  
 #include <stdint.h>  
 #include <ctype.h>  
   
 void USART_Init (unsigned int ubrr)  
 {  
      /* baud rate */  
      UBRR0H = (unsigned char) (ubrr>>8);  
      UBRR0L = (unsigned char)ubrr;  
      /* Enable receiver and transmitter */  
      //UCSR0B = (1<<RXEN0)|(1<<TXEN0);  
      UCSR0B = (1<<TXEN0);  
      /* Set frame format: 8bit data, 2 stop bit */  
      UCSR0C = (1<<USBS0)|(1<<UCSZ00)|(1<<UCSZ01);  
 }  
   
 void USART_Transmit (unsigned char data)  
 {  
      /* Wait for empty transmit buffer */  
      while (!(UCSR0A & (1<<UDRE0)))  
           ;  
      /* Put data into buffer, sends the data */  
      UDR0 = data;  
 }  
 int USART_PrintChar (char character, FILE *stream)  
 {  
      USART_Transmit (character);  
      return 0;  
 }  
 FILE uart_str = FDEV_SETUP_STREAM(USART_PrintChar, NULL, _FDEV_SETUP_RW);   
   
 void USART_Print_Location(uint8_t line, uint8_t pos) {  
      if ((line < 1) || (line > USART_LCD_MAXLINES)) {  
           line = 1;  
      }  
      if ((pos < 1) || (pos > USART_LCD_CHARS)) {  
           pos = 1;  
      }  
      USART_Transmit(3);  
      USART_Transmit(line);  
      USART_Transmit(pos);  
 }  
   
 int main(void)  
 {  
      USART_Init(BAUD_PRESCALE);  
      stdout = &uart_str;  
      unsigned char sendChar = 65;  
      USART_Transmit(19);  
      USART_Transmit(12);  
      USART_Print_Location(1,5);   
      printf("Hello World");  
      USART_Print_Location(2,9);  
      printf("from");  
      USART_Print_Location(3,1);  
      printf("RichRobo on Blogger");  
      while(1)  
   {  
     //TODO:: Please write your application code   
   }  
 }  

The code really should be commented but I'm too tired to do so now and I'll most likely update and clean up the code soon so I can post it after that. Next job I'm thinking I'll do is to get SPI working between two chips. Before I do this though, I need to get the chip to run without the need for the programmer (AVR ISP mkII) being plugged in.