**EDIT 6/19/2012***********************************************************
Ok, so after you added your code I have made a few changes for you to try (and to understand!)
First of all, we have declared our character array volatile so that the compiler knows it may change unexpectedly from an interrupt. Likewise, we have created a variable to keep track of our index position in the array:
/**************************************************
* Global Variables
*/
int trigger=0, length=0;
int i=0, n=0;
uint8_t data;
volatile char arr[8];
volatile char arr_idx = 0;
Next, i have edited your UART initialization code based on the ATMega16L Datasheet and your comments:
//USART SETUP
UCSRA = 0x00; //no Frame Error, no parity error, no Data OverRun
UCSRB = 0xD8; //receiver enable, transmitter enable (0x18)
UCSRC = 0x86; //Asynchronous USART mode, no parity, 1 stop bit, 8-bit character size, Data transmitted on rising edge and received on falling edge of the clock
UBRRL = 51; //Baud rate of 9600bps (8MHz clock?)
UBRRH = 0;
Look closely at the datasheet (page ~166). I believe I have correctly configures the UART now based on your comments. I will not go over each bit, but you should. Please ask questions if you think I made a mistake or you don't get something.
Finally, I have edited your ISR routine:
ISR(USART_RXC_vect){
arr[arr_idx] = UDR;
arr_idx++;
arr_idx %= 7; //make sure index stays within array
trigger = 1;
}
Note that, the ISR is executed every time a single byte (or character) is received. This means we want to process the single character (add it to our array), increment our index location, and get out of it quickly so that we are ready for the next character to come in.
You now need to look at the arr[] through whatever method you have been using and see if it is now receiving your characters correctly.
**END OF EDIT****************************************
One option is to just use one of the available libraries included in AVR Studio:
#include <stdlib.h>
and then somewhere in your code...
char num2[5]; //create a buffer for the ascii string
itoa(num1,num2,10); //convert the integer (num1) to an ascii string (num2) in base 10
If you are then displaying this on a character LCD, you can send the num2 array to the lcd print function that you are using.
If you are concerned about code space you can fairly easily write your own simple itoa (integer to ascii) function. You will need to grab each "tens" position from your integer using the "/" and "%" operators and convert it to ascii:
(source: asciitable.com)
From the table above, you can see that once you grab each digits value (0-9), just add 48 to it to convert it into the ascii character representation.
EDIT
Ok, so after you adding your information and assuming:
- You have correctly initialized the UART baud rate etc on your ATMEGA
- The android code is successfully sending the ascii bytes across the WiFly and out of its UART
Then the microcontroller should already be receive these characters as Ascii, and the ITOA function is not what is needed here and in fact would mess up your string data coming in.
It could still be a lot of different things though...How are you viewing the uart data that is being received by your microcontroller?
I dont understand your confusion. You want to communicate between the two controllers with UART, then ofcourse both of them need UART capabilities and code for this. Your computer has drivers and software for dealing with this, so your microcontroller also needs a driver for it.
Your ATmega32 need UART TX functionality, while AT90USB1287 need UART RX functionality. Having already written both TX and RX for your ATmega32, writing the UART RX routine for AT90 should be a breese. You could add a bitvalue of some kind, identifying that the UART RX on AT90 is coming from your ATmega32, and directly pass it through to USB.
EDIT: Code from AVRFreaks that is written for at90usb1287
#include <avr/io.h>
#include <util/delay.h>
#define RXC (RXC1)
#define TXC (RXC1)
#define UCSRC (UCSR1C)
#define UCSRB (UCSR1B)
#define UCSRA (UCSR1A)
#define UDR (UDR1)
#define UBRRL (UBRR1L)
#define UBRRH (UBRR1H)
#define UBRR (UBRR1)
#define UDRE (UDRE1)
#define RXCIE (RXCIE1)
#define TXEN (TXEN1)
#define RXEN (RXEN1)
#define UCSZ0 (UCSZ10)
#define UCSZ1 (UCSZ11)
#define UMSEL0 (UMSEL10)
#define UMSEL1 (UMSEL11)
#define FRAMING_ERROR (1<<FE1)
#define PARITY_ERROR (1<<UPE1)
#define DATA_OVERRUN (1<<DOR1)
#define DATA_REGISTER_EMPTY (1<<UDRE1)
#define RX_COMPLETE (1<<RXC1)
#define FOSC 16000000
typedef unsigned char Uchar;
typedef unsigned long int Uint32;
#define Wait_USART_Ready() while (!(UCSR1A & (1<<UDRE1)))
#define lowByte(w) ((uint8_t) ((w) & 0xff))
#define highByte(w) ((uint8_t) ((w) >> 8))
int main(void)
{
/* Disable clock division */
clock_prescale_set(clock_div_1);
UBRRH = (Uchar)((((Uint32)FOSC)/((Uint32)USART_BAUDRATE*16)-1)>>8);
UBRRL = (Uchar)(((Uint32)FOSC)/((Uint32)USART_BAUDRATE*16)-1) & 0x0ff;
UCSRB |= (1 << RXEN) | (1 << TXEN);
UCSRC |= (1 << UCSZ1) | (1 << UCSZ0);
char ReceivedByte;
for (;;) // Loop forever
{
while ((UCSRA & (1 << RXC)) == 0) {}; // Do nothing until data have been received and is ready to be read from UDR
ReceivedByte = UDR; // Fetch the received byte value into the variable "ByteReceived"
while ((UCSRA & (1 << UDRE)) == 0) {}; // Do nothing until UDR is ready for more data to be written to it
UDR = ReceivedByte; // Echo back the received byte back to the computer
}
}
Best Answer
Although I have not used that specific printer, I'll answer based on previous experience with similar printers.
You should also consider the interface handshaking, to avoid over-running the input buffer of the printer. That's why it is best not to send commands "blind" to the printer, but check the state of the hardware or XON/XOFF handshake (whichever you configured on the printer), before sending commands or data.
Since the printer uses an RS-232 serial interface, not logic-level, you will need to use suitable interface ICs for the data and handshaking signals from your MCU. See the printer's user manual for more details about the handshaking signals used by the printer.
On the download page of the manufacturer's website for that printer, the "58 Driver & Tool" download for the RP58 printer family contains a Windows utility in the "PrinterTool" folder, to set hardware or XON/XOFF handshaking, serial data rate, and other initial printer settings.
To send printable characters to the printer, you just send the relevant ASCII bytes e.g. send the byte 0x31 followed by Line Feed (0x0A) to print the character "1" on the paper. Again, take care about the handshaking.
I expect the default state when starting the printer, would be that it will be "online", so that this command is unlikely to be necessary unless you have sent the "offline" command first.
As I explained above - just send the ASCII characters, followed by LF (0x0A) when needed.
That is a shopping question and so it is off-topic. Remember, readers cannot know what is cheap for you, easy to acquire for you, and all your other purchasing considerations (e.g. good technical support, on-going hardware availability etc.).