Gsm interfacing with atmega16 - gsm

I am working on GSM sim900D interfacing with Atmega16. Initially I made the circuit using MAX232 on breadboard. Then I connected it to my PC using a serial port. I tested AT commands, the commands worked perfectly on hyper terminal and I was able to send SMS using hyperterminal. Then I tested it on Proteus and it was working there perfectly too.
I am using codevision avr as the compiler. GSM work on 9600baud but the problem is that in compiler I have to keep the baud rate4800(clock = 1MHz) and at proteus COMPIM(physical baud=9600 & virtual baud=4800) only then it works when I run it on hardware(breadboard) it doesn't work as I have set the baud to 4800. I don't know how to set the baud for hardware. I tried 9600baud for hardware in compiler but it doesn't send SMS at all. Kindly tell me what I should do?

On ATmega16 (and other ATmegas), the serial baud rate is set via UBRRH and UBRRL registers plus the U2X bit in the UCSRA register. The detailed description of how this works starts on page 146 of the ATmega16 datasheet. Basically, UBRR is a 16-bit register and so must be accessed separately via 8 bit parts UBRRH (the high byte) and UBRRL (the low byte). The value you want to put into these registers (and the U2X bit in UCSRA register) depends on
the clock rate
the desired baud rate.
For 1Mhz clock and 9600 baud there are two options (see table 68 on page 168 in the datasheet): cleared U2X bit and UBRR set to 6 or set U2X and UBRR set to 12. The latter option results in a baud rate generation that is closer to the desired baud rate (0.2%) error, therefore, the latter option is recommended. Consequently, the code you want is:
UBRRH = 0;
UBRRL = 12;
UCSRA |= 1<<(U2X);
There is a nasty gotcha lurking here: as the datasheet states, UBRRH and UCSRC are the same register. UCSRC controls parity, stop bits, and other important settings. Therefore if you ever need to write to UCSRC, make sure that you set the URSEL bit at the same time:
UCSRC = (1<<URSEL) | (...other bits...)
or
UCSRC |= (1<<URSEL) | (...other bits...)
Otherwise you will clobber your UBRRH register and wonder why your baud rate is not what you expected.
But you can also make use of the AVR Libc code, which provides a read-made way for setting a baud rate on AVR, see util/setbaud.html

you check data sheet the error rate is too high. when you using 9600 baud rate on 1MHZ this is the main problem . take 8,12,16 MHZ as possible and check data sheet . and dont forget to burn fuse bits related to XTAL frequency if you not burn these bits properly that relate with crystal that is not work properly .
if u need more help ask..

Related

Built-in led glowing on code of led on arduino mega

I had written a code on atmel studio for blinking a led on pin 13. After uploading the code with xloader mega's builtin led was blinking.
I uploaded fade code on my mega and the builtin led was blinking instead of led. What should i do?
I am using arduino mega 2560.
int main(void)
{
DDRB=0b00000000;
while (1)
{
PORTB=0b10000000;
_delay_ms(1000);
PORTB=0b00000000;
}
}
What you should do? Read the manual.
Please refer to https://ww1.microchip.com/downloads/en/devicedoc/atmel-2549-8-bit-avr-microcontroller-atmega640-1280-1281-2560-2561_datasheet.pdf
Chapter 13.2.
The DDxn bit in the DDRx Register selects the direction of this pin.
If DDxn is written logic one, Pxn is configured as an output pin. If
DDxn is written logic zero, Pxn is configured as an input pin.
Working with registers doesn't make sense if you don't know what they do.
DDRB=0b00000000;
Gives you inputs only.
why would you use Arduino and try to program it without its conventional macros and functions?
If you are trying to blink an led or make it breath then use the Arduino IDE and its built-in functions analogWrite() to generate a pwm pulse for your led or any led on suitable pins which support analogwrite(). You shouldn't try to do any direct modifications on registers if you have no suitable knowledge, because your risk destroying your development kit and maybe burning some other stuff around. Please use your kit's schematics to spot the pins which support analogwrite() and then use the code in examples.
That way you will achieve your goal faster and without any issues.
TL/DR: you have to set 7th bit in DDRB to one.
In AVR ports are configured by bits in two registers: DDRx and PORTx.
When the corresponding bit in the DDRx register is set to one, the port is configured as output. And the corresponding bit in the PORTx register chooses which electrical level is output on the pin. If it is 0 then internal MOSFET shorts the pin to "ground" lane, and sinks current from external source. When the bit of the PORTx is one, then the pin is connected to "VCC", sourcing big amount of current enough to lit up a LED.
But if the pin is connected to something, what consumes too much of current, or the pin is shorted to GND or VCC (let's say you have a button connected and pressed), then output MOSFETS might be overloaded and damaged.
If the bit in DDRx is set to zero, then the pin is configured as input. If the corresponding bit in the PORTx is zero, then the pin has no internal connection to power lines, it is called "Hi-impedance" state, or Tri-state. It does not source or sink any current. So, if no external source of current is connected, then pin level is floating, influenced by electrical interference. Logical level is not detectable and can change occasionally. If you want to connect, for example, a button (between the pin and GND), then logical level will be defined only when button is pressed. When it is released, the logical level will be undefined.
But! If the bit in the PORTx is set to one, then internal MOSFET connects the pin thru a resistor (about 35 kOhm) to VCC line. This make the pin to source a little amount of current, setting its logical level to high. Therefore, if a button is connected, when it is released, then pin will have defined high level. This is called "pull-up resistor". When button is pressed, it will not short and damage the MCU, because current flowing thru the button is limited by the resistor, but the logical level will be defined low.
What if instead of button you have a LED connected to the pin? Very small amount of current will flow thru the LED, makes it barely glow.
Read more in the datasheet (chapter 13. I/O-Ports)

Setting the baud rate for USART in STM32 microcontroller

Why do we need to calculate the baud rate using the following formula?
baud = fCK / (16*USARTDIV)
I mean, why can't we write 9600 or any other desired baud rate value directly in USART_BRR register? Why do we need to perform this calculation first? What are we calculating here anyway?
You can't just write your desired baud rate into a register as the processor doesn't know how fast the clock is to that peripheral, so it wouldn't be able to set up dividers correctly.
It would be possible to make a USART that you could tell a baud rate too, but it would require extra complexity and would still need to know how fast its clock is.
You are not configuring software, but hardware. That means, the bits you set are (more or less) directly connected to clock dividers which control the baud rate of the UART module.
As an example, you have to use fCK in your calculation. Imagine the UART module would have to calculate fCK by itself. The problem is, fCK is the result of all used clock dividers and not configured centrally. The effort to calculate fCK in hardware would just be disproportionate (effort = costs). It's just much easier to let the user calculate it.

Why 9600 data rate is used over other rates for Serial.begin()?

I am working on Arduino and for communication purpose with the computer Serial.begin() function is being used. Now since there is a range of data rates from 300...115200.
Majority uses 9600!
Why is it so? What is its significance
During previous millenium 9600 bauds has been a standard for some devices.
Currently this speed is enough for most cases, so they stick to it; many devices use 9600 baud as a default.
Personally I use serial for debugging most often. At 9600 baud, it can print more than 10 lines per second, that is more than I can read.
Yet you can keep in mind that the buffer is limited to 64 char and when it is full, arduino will block a serial.write instruction until there is enough space in buffer. That is why you encounter some slowdown with slow baud rates.
On the other sides you will burden the MCU with speed of 0.5M on hardware serial. And with software serial you may see an impact much sooner.
Personally I had some trouble with chinese nano that used CH340 USB/Serial; python communication to arduino with pyserial was unreliable at speed over 9600 bauds.
Many devices use 9600 or 19200 baud, and I guess that people just copy over values without thinking about them, thereby continuing the practice even if it is no longer necessary.
That said, the maximum length of a serial cable depends on the baud rate you choose. Higher baud rates require shorter cables. So if you don't need the higher rate, just stay with a low one like 9600.

Arduino serial: inverted 7E1. Possible?

I'm trying to talk serial with an SDI-12 device, and it requires inverted seven data bits, even parity and one stop bit (7E1) serial at 1200 baud.
From the datasheet:
SDI-12 communication sends characters at 1200 bits per second. Each character has 1 start bit, 7 data bits (LSB first), 1 even parity bit, and 1 stop bit (Active low or inverted logic levels):
All SDI-12 commands and response must adhere to the following format on the data line. Both the command and response are preceded by an address and terminated by a carriage return line feed combination.
Is this possible with the Serial or SoftwareSerial libraries? I am trying to avoid additional hardware (beyond a levelshifter to 3.3 V), but I will do so if it is the only way.
I have seen that SoftwareSerial can do inverted, and Serial can do 7E1, but I can't find if either can do both.
I have access to a Arduino Mega (R2), and Arduino Uno (R3).
Here is the device I want to communicate with: http://www.decagon.com/products/sensors/soil-moisture-sensors/gs3-soil-moisture-temperature-and-ec/ and here, http://www.decagon.com/assets/Uploads/GS3-Integrators-Guide.pdf is the document explaining the protocol. Page 6 talks about its implementation of SDI.
I'm not familiar with Arduino, however the SDI-12 physical layer is inverted from the standard TTL levels - probably for two reasons:
Since the idle voltage is 0V, this results in lower standby power (due to nominal pull-down resistors in a typical SDI-12 sensor.
It facilitates simple bus 'sniffing' using a standard RS-232 serial port.
Short of bit-banging a 5V IO pin - yes, if using a standard microcontroller UART you will need an external inverter (or 2) and a 3-state buffer. Possibly requiring level shifting, depending on your hardware.
Thumbs down to the Wikipedia entry - SDI-12 uses entirely standard UART bit timings (very much like RS-232), just different signal levels (0 - 5V); see point #2. However, there are specific break sequences and strict timing requirements, which makes firmware development more difficult.
If you are serious about SDI-12 firmware development, you may want to invest in an SDI-12 Verifier. A thorough study of the specification is essential.
A little late... but better late than never
I have actually just written a library for exactly that (actually exactly that including the sensors ... so it should work exactly with the included examples )
https://github.com/joranbeasley/SDISerial (Arduino Library)
#include <SDISerial.h> //https://github.com/joranbeasley/SDISerial (Arduino Library)
#include <string.h>
#define DATA_PIN 2
SDISerial connection(DATA_PIN);
char output_buffer[125]; // just for uart prints
char tmp_buffer[4];
char sensor_info[]
//initialize variables
void setup(){
connection.begin();
Serial.begin(9600);//so we can print to standard uart
//small delay to let the sensor do its startup stuff
delay(3000);//3 seconds should be more than enough
char* sensor_info = connection.sdi_query("0I!",1000); // get sensor info for address 0
}
//main loop
void loop(){
//print to uart
Serial.println("Begin Command: ?M!");
//send measurement query (M) to the first device on our bus
char* resp = connection.service_request("0M!","0D0!");//Get Measurement from address 0
sprintf(output_buffer,"RECV: %s",resp?resp:"No Response Recieved!!");
Serial.println(output_buffer);
delay(10000);//sleep for 10 seconds before the next read
}

An issue with uart and pic 18f452

i have a problem with pic18f452 and uart
i use simplest code like that:
UART1_Init(9600); // Initialize UART module at 9600 bps
Delay_ms(100); // Wait for UART module to stabilize
and between forever while loop i have this code
UART1_Write_Text("HELLO2");
Delay_ms(1000);
also i have in my hardware lcd module it works very fine but my received data on pc
is a scrap like that
???m
i have checked all connection sothand time nothing wrong also i have changed MAX232 ic but with no luck ?!
my hardware is like that
finall all my connections are ok (polarity and every thing else ?)
EDIT : i use mikroc as a compiler
Looks like a baud rate error. Have you checked that your oscillator settings are resulting in the expected frequency? Does the serial library you are using expect a certain clock frequency and you are sure that you are running at that frequency, or does it work over a set of frequencies and you have correctly informed the serial library what frequency you are using? Also it would be useful to see the byte received as a decimal or hex number rather than just ASCII.
What about the start bits, number of data bits, parity, and stop bits? Are they the same on both ends?
It happens when you have loose connections i.e. from max 232 to Pic & from max 232 to PC.
Try checking the fluctuations over the transmit pin or usr Oscilloscope to see the ASCII values of Hello World alphabets.

Resources