I am using the USART in synchronous mode to communicate from the host computer to firmware(resides in ATMega 1284P). My maximum buffer size in the firmware side is 20, If I send the data continuously from the host to the firmware and some replies from firmware to host computer, somehow the communication locks up. I doubt that the UDR register which is common for both Transmit Data Buffer(TXB) and Receive Data Buffer(RXB) to send/receive the data in/out of the firmware is locked which results in ceasing of communication. Any Suggestion for this issue?
PS:
For transmisson from firmware to host, the codition is:
UCSRA & (1 << UDRE) should be TRUE
For reception from host to firmware, the condition is:
UCSRA & (1 << RXC) should be TRUE
I am using hardware interrupt M_USARTx_RX_vect for checking the availability of the serial characters from host.
Update: Firmware - Initial Source : MarlinSerial.cpp : USART Definitions, Marlin_main.cpp : Program Flow
The UDR register is physically two times present at the same address in the avr address space ( special io register mapping). There is no locking between the udr of the rx and tx of the uasrt in hardware.
The shown conditions seems ok to me, but I have not looked in the avr datasheet.
Maybe you have some problems while writing/reading to your cyclic? 20 char buffer? Please show your code ( please shrink for the minimum we need to understand ).
Related
I am trying to connect a WiFi module (ESP8266) to a "funduino" development board (Arduino Nano) but I have no success. Since I tried so much schematics I've found on the internet about the connection between them two, I kindly ask here if is anyone who succeed in "pairing" this two devices.
I am asking for the schematic and a functional source code.
Regards
The ESP-01 by default comes with nonOS SDK bootloader that communicated via AT commands, you can find the complete command set from Expressif here. This is designed for an MCU (like Arduino Nano) to use it purely as an WiFi module rather than using it as a stand-alone MCU (for which it will require NodeMCU SDK).
If you ever upload an Arduino sketch up to the ESP-01, it will erase the AT Command firmware.
Assuming your ESP-01 is still having the AT Command firmware. What #Ben provided is a sketch that allows you to type AT commands via the Serial Monitor to internact with the ESP-01, it is manual, and good for testing if ESP-01 is working (you type AT and press return on Serial Monitor, the ESP-01 will ack with Ok) but not practical as a real application. The minimum commands required to established an WiFi connection with ESP-01 is listed below.
AT+CIPMUX=1 - Enable single (0) or multiple connection (1) to the web server.
Multiple connection is a good option if you are repeatedly sending
out or reading data from the Internet.
AT+CWMODE=3 - Set WiFi mode: 1 is station mode (ESP8266 is client), 2 is AP mode
(ESP8266 acts like a WiFi router where your phone or PC can connect),
3 is AP+station mode (make the ESP8266 do both)
AT+CWJAP=“<your-ssid>”,”<your-pw>” - Connect to your WiFi. Provide your SSID name
and password inside the double qoutes.
AT+CIFSR - This returns the IP address of the module, indicating that it has
successfully connected to your WiFi router.
Once the WiFi connection is established, you can further communicate with the ESP-01 via the connection, like accessing a website for example:
AT+CIPSTART=0,"TCP", "www.example.com","80” - Start TCP or UDP connection. The
0 is the id of the connection.
AT+CIPSEND=0,16 - Command to tell the module data is ready to be sent. 0 is the
connection id, and 16 is the length of the data to be sent.
After this command, the ESP8266 will reply with the “>”
character to tell us that it will be waiting for the data to be
sent. If successful, the module will reply with “SEND OK”
GET / HTTP/1.1 - Send the http header, and other data, etc...
You can write your own sketch to automate those AT commands for interacting with with ESP-01 once you understand the AT commands required for establish a WiFi connection.
Here are two resources that I personally found extremely useful for doing more than connecting to WiFi.
STM32-ESP-01 Web Server - although this is for interfacing with STM32, the main difference is the pin assignment, so you should be able to port to Arduino easily.
MQTT via ESP-01
As for hardware interface, please noted that what #Ben provided is correct in principle, but you need to be aware that the ESP-01(ESP8266 to be precise) is a 3V3 MCU, so the connection is depended on what kind of host board you are using. If you are using Arduino Uno/Nano, both are having a 5V MCU, you will need a voltage divider (two resistors to drop the voltage to 3v3 before connecting to ESP-01) or a level shifter chip at least for the ESP-01 Rx pin to avoid the potential damage to the ESP-01.
I'm writing a simple program to transmit data from the MCU to the PC.
I'm using FTDI cable to achieve that.
Data that I'm sending is string digits from 0 to 9 (0x30 to 0x39 as ascii codes).
Both the MCU and the PC terminal are configured to 9600 kbps, 8 bits, no parity, no flow control, one stop bit.
When the data transferred from the MCU to the PC - symbols are wrong.
When TX and RX lines of the MCU are both connected to each other - I can see, that all symbols that were sent, were received by the MCU.
When TX and RX lines of the FTDI cable (connected to the PC) are connected to each other - all symbols that were sent from the PC terminal were received by the PC.
I cannot understand what can be wrong in sending data from the MCU to the PC.
Please, help!
The symptoms you describe suggest a timing mismatch between the PC and the MCU. UART serial comms can tolerate a baud rate mismatch of <5% at either end. In practice because teh PC is certainly accurate, you might get away with up to 10% in the embedded target - but that is extreme. Either the baud rate divisor for your part is incorrectly programmed, or your system clock is inaccurate or simply not the frequency you believe it to be. RC oscillators on some MCUs used to reduce costs can be off-nominal as bad as +/-10%.
You should verify the clock and the baud rate directly with an oscilloscope, or laboriously verify every clock setting from the PLL to the UART baud-rate generator.
The solution is more simple than I thought.
For my previous applications I used the ATC-810 cable (USB-to-UART, FT232BL chip).
At the past it worked, but now for some reason it doesn't works. New drivers from FTDI, may be...
When I took the TTL-232R-3V3 cable - all data that I'm sending from the MCU I'm receiving on the PC!
Thanks a lot for trying to help!!
I need a serial communication in 'raw' mode when only the data byte will be transmitted . The purpose is transmitting information using any RF tx module to boards around using bi-phase codification. The start e stop bit don't permit do this with flexibility.
With regards to Arduino EEPROM when writing and reading to certain EEPROM devices it asks for a transmission of the following format:
Wire.beginTransmission(ADDR);
Wire.write(highADDR);
Wire.write(lowADDR);
Wire.write(data);
Wire.endTransmission();
What do the high address and low address mean? Why can I not just tell it to write to the byte at address 4. Why do I need to prove a high and low?
It looks to me like you are using I2C, I am going to make that assumption and base my answer off of it. Perhaps you should clarify which EEPROM you are using.
The way I2C works is that you can have one master (your Arduino) communicate with multiple slaves (your EEPROM for example) on the same I2C bus. Since it is possible to have multiple slaves connected on the same bus, I2C protocol requires you to specify what slave device you are communicating with. This is what Wire.beginTransmission(ADDR) does. It is selecting which device it wants to initiate communication with. If you want to communicate with your EEPROM you will need to send the address of your EEPROM (you should be able to find the address in the EEPROM datasheet).
Next, you need to specify the memory location inside your EEPROM where you want to access. This is done using the two bytes highADDR and lowADDR. If for instance you wanted to access the address 0x01AB, then set highADDR to 0x01 and lowADDR to 0xAB.
The rest is fairly simple. You send your data then end the transmission.
To Summarize:
Select device to communicate with (Select your EEPROM)
Wire.beginTransmission(ADDR);
Tell your EEPROM what memory address you want to write to
Wire.write(highADDR); // Send the most significant address bits
Wire.write(lowADDR); // Send the least significant address bits
Send data to write.
Wire.write(data);
End the transmission
Wire.endTransmission();
I strongly recommend reading more about how the I2C protocol works. http://en.wikipedia.org/wiki/I%C2%B2C#Message_protocols
I have a processing sketch that pumps out basic serial commands to an xbee.
Then I have two (soon to be 3, maybe 4) arduino's with their own xbee's who receive the data and do stuff.
Thing is each Arduino has it's own purpose, and therefore it's own data packet.
So, to implement this. Is there a way to send a message to a particular xbee? I.e. can I assign the xbee an index or channel of some sort, then get the broadcasting xbee to send data to whatever index or channel it needs to?
Or, will this need to be implemented in the Arduino software?
i.e. Processing prefix the data packet with an index/identifier and the arduino ignore incoming messages with that prefix?
Or is there another option entirely :P
Thanks in advance for your advice.
While not a specific answer to your question, with this type of communication some packet error checking would be beneficial. Send the data using a crc error checking algorithm. Packet structure could look something like:
0x7F 0x02 (Address Bytes) (Command Bytes) (CRC bytes) 0x7F 0x03
Where 0x7F is the DLE character used to indicate either a start byte will follow, and end byte will follow, or a data byte with the value of DLE will follow. This means any DLE character that is part of the address or command should be preceded by a 'Stuffed' DLE character. The CRC is calculated from the address and command bytes and used to check the integrity of the data that is received. The CRC check bytes are included in each packet.
This type of communication will prevent packets going to the wrong source from being used, and also packets that are in error from being used.
To read more on serial framing here is a good place to start: http://eli.thegreenplace.net/2009/08/12/framing-in-serial-communications/.
To what i understood is that you want to be able to tell the diffrence to what Xbee you are sending data to. You can do this by using IP adresses. If you have for example two Xbees with the IPs:
Xbee1 - 192.168.80.50
Xbee2 - 192.168.80.51
Xbee3 - 192.168.80.52
You can send information between them by just connecting the Xbee that will start the communication to the Xbee that will receive it. If you want to have any kind of communication over the wireless network (or ethernet) you must have an IP assigned to every Xbee.
EDIT:
If you have a server on a computer that you have made yourself in for example Java. You can connect the Xbees to that and connect of them to the computer server. Then you can set up the server to receive and send data to the diffrent Xbee clients.
I did something similar to this: Maintaining communication between Arduino and Java program , but i didn't use a Xbee, i used the official WiFi shield.
Hope this helped!
-Kad