Rs232 conection for microcontroller
-
Hello, Wen I sent data to my µC, It reciefd only 1/2 of my data. Al the communication parameters are goed. I try software flow control but it dont works. Can sombody help my plaese.
Dag Jelle, tell us some more about your set-up. I assume you mean SerialPort.Handshake.XOnXOff? This is how I expect it to work: - communication is enabled by default - when one side sends XOFF character, the other side should stop transmitting (but may take a while, say 5 character times, to understand that) - when one side sends XON character, the other side is allowed to resume transmission - it works both ways (you can't do different schemes for transmit and receive) - each side will send XOFF when its transmit buffer is nearly full; on Windows the serial driver does that automatically, you should not explicitly send XOFF or XON - each side will send XON when its transmit buffer has sufficient room - each side will receive and interpret incoming XON and XOFF according to the above, the application will never receive them as data - warning: if you send data (say binary data) that happens to contain bytes with the same value as XON or XOFF your communication will fail. Hope this helps. Groeten.
Luc Pattyn [Forum Guidelines] [My Articles]
this weeks tips: - make Visual display line numbers: Tools/Options/TextEditor/... - show exceptions with ToString() to see all information - before you ask a question here, search CodeProject, then Google
-
Dag Jelle, tell us some more about your set-up. I assume you mean SerialPort.Handshake.XOnXOff? This is how I expect it to work: - communication is enabled by default - when one side sends XOFF character, the other side should stop transmitting (but may take a while, say 5 character times, to understand that) - when one side sends XON character, the other side is allowed to resume transmission - it works both ways (you can't do different schemes for transmit and receive) - each side will send XOFF when its transmit buffer is nearly full; on Windows the serial driver does that automatically, you should not explicitly send XOFF or XON - each side will send XON when its transmit buffer has sufficient room - each side will receive and interpret incoming XON and XOFF according to the above, the application will never receive them as data - warning: if you send data (say binary data) that happens to contain bytes with the same value as XON or XOFF your communication will fail. Hope this helps. Groeten.
Luc Pattyn [Forum Guidelines] [My Articles]
this weeks tips: - make Visual display line numbers: Tools/Options/TextEditor/... - show exceptions with ToString() to see all information - before you ask a question here, search CodeProject, then Google
Hallo, My setting are, PortName = "COM6"; hComm = CreateFile( PortName, GENERIC_READ | GENERIC_WRITE , 0, 0, OPEN_EXISTING, 0, 0); if(hComm == INVALID_HANDLE_VALUE) { Application->MessageBoxA("Kan COM Poort niet openen !\n" "Neem de kabel uit de poort en\n" "plaats hem vervolgens terug.", "Error", MB_OK | MB_ICONSTOP ); Form6->Close(); } else { dcb.DCBlength = sizeof(dcb); if(!GetCommState(hComm , &dcb)) { Application->MessageBoxA("Kan Setting COM poort niet lezen !\n", "Error", MB_OK | MB_ICONSTOP ); CloseHandle(hComm); Form6->Close(); } else { dcb.BaudRate = 9600; dcb.fBinary = TRUE; dcb.fParity = TRUE; dcb.fOutxCtsFlow = FALSE; dcb.fOutxDsrFlow = FALSE; dcb.fDtrControl = DTR_CONTROL_DISABLE; dcb.fDsrSensitivity = FALSE; dcb.fRtsControl = RTS_CONTROL_DISABLE; dcb.fTXContinueOnXoff = FALSE; dcb.fOutX = TRUE; dcb.fInX = TRUE; dcb.fErrorChar = FALSE; dcb.XonLim = 20; dcb.XoffLim = 20; dcb.ByteSize = 8; dcb.Parity = NOPARITY; dcb.StopBits = ONESTOPBIT; dcb.XonChar = 0xFF; dcb.XoffChar = 0xFE; if(!SetCommState(hComm , &dcb)) { Application->MessageBoxA("Instelling COM poort fout !\n", "Error", MB_OK | MB_ICONSTOP ); CloseHandle(hComm); Form6->Close(); } } I dont now of this works, I'm just a beginner. I onderstand the flow control not so good. Wen the µC send a XOFF charactar, must I read this on my program of read this autometalic the XOFF character. Is my setting good of not good. I don't now. If you Netherlands, you may me in the Netherlands. Thanks, Jelle Groeten
-
Hallo, My setting are, PortName = "COM6"; hComm = CreateFile( PortName, GENERIC_READ | GENERIC_WRITE , 0, 0, OPEN_EXISTING, 0, 0); if(hComm == INVALID_HANDLE_VALUE) { Application->MessageBoxA("Kan COM Poort niet openen !\n" "Neem de kabel uit de poort en\n" "plaats hem vervolgens terug.", "Error", MB_OK | MB_ICONSTOP ); Form6->Close(); } else { dcb.DCBlength = sizeof(dcb); if(!GetCommState(hComm , &dcb)) { Application->MessageBoxA("Kan Setting COM poort niet lezen !\n", "Error", MB_OK | MB_ICONSTOP ); CloseHandle(hComm); Form6->Close(); } else { dcb.BaudRate = 9600; dcb.fBinary = TRUE; dcb.fParity = TRUE; dcb.fOutxCtsFlow = FALSE; dcb.fOutxDsrFlow = FALSE; dcb.fDtrControl = DTR_CONTROL_DISABLE; dcb.fDsrSensitivity = FALSE; dcb.fRtsControl = RTS_CONTROL_DISABLE; dcb.fTXContinueOnXoff = FALSE; dcb.fOutX = TRUE; dcb.fInX = TRUE; dcb.fErrorChar = FALSE; dcb.XonLim = 20; dcb.XoffLim = 20; dcb.ByteSize = 8; dcb.Parity = NOPARITY; dcb.StopBits = ONESTOPBIT; dcb.XonChar = 0xFF; dcb.XoffChar = 0xFE; if(!SetCommState(hComm , &dcb)) { Application->MessageBoxA("Instelling COM poort fout !\n", "Error", MB_OK | MB_ICONSTOP ); CloseHandle(hComm); Form6->Close(); } } I dont now of this works, I'm just a beginner. I onderstand the flow control not so good. Wen the µC send a XOFF charactar, must I read this on my program of read this autometalic the XOFF character. Is my setting good of not good. I don't now. If you Netherlands, you may me in the Netherlands. Thanks, Jelle Groeten
Hi Jelle, your settings seem acceptable, I have a few comments: - I am not sure what dcb.fParity = TRUE; does when dcb.Parity = NOPARITY; I would set it false just to make sure no false parity errors can occur - dcb.XonChar = 0xFF; dcb.XoffChar = 0xFE; that is a peculiar choice of characters, normally one uses XOFF = 0x13 (CTRL/S) and XON = 0x11 (CTRL/Q) your choice could work also, provided the other side uses the same characters ! you said earlier you were receiving half of the characters, care to explain that a bit? and what is on the other side of your serial cable? PS: yes we could have this conversation in Dutch, but the forum police here does not like us to do that, and other people might be interested too. groeten
Luc Pattyn [Forum Guidelines] [My Articles]
this weeks tips: - make Visual display line numbers: Tools/Options/TextEditor/... - show exceptions with ToString() to see all information - before you ask a question here, search CodeProject, then Google
-
Hi Jelle, your settings seem acceptable, I have a few comments: - I am not sure what dcb.fParity = TRUE; does when dcb.Parity = NOPARITY; I would set it false just to make sure no false parity errors can occur - dcb.XonChar = 0xFF; dcb.XoffChar = 0xFE; that is a peculiar choice of characters, normally one uses XOFF = 0x13 (CTRL/S) and XON = 0x11 (CTRL/Q) your choice could work also, provided the other side uses the same characters ! you said earlier you were receiving half of the characters, care to explain that a bit? and what is on the other side of your serial cable? PS: yes we could have this conversation in Dutch, but the forum police here does not like us to do that, and other people might be interested too. groeten
Luc Pattyn [Forum Guidelines] [My Articles]
this weeks tips: - make Visual display line numbers: Tools/Options/TextEditor/... - show exceptions with ToString() to see all information - before you ask a question here, search CodeProject, then Google
Hello Luc, I try it in Englich. This is my code from sending text to my µC. I main the half of characters : I want to send "versturen van data naar microcontroller" and the µC recievd only "versrn a mcr ". I have no problem with a other terminal. I think that it maby the programcode is. Hier is my code to transmitting data. bfData = "Versturen van data naar microcontroller."; unsigned long dwNumberOfBytesWritten; if(!WriteFile(hComm , bfData , 30 , &dwNumberOfBytesWritten , NULL)) { Application->MessageBoxA("Fout bij het versturen van de data !", "Error", MB_OK | MB_ICONSTOP ); CloseHandle(hComm); } else { Edit1->Text = dwNumberOfBytesWritten; } } Thanks, Jelle.
-
Hello Luc, I try it in Englich. This is my code from sending text to my µC. I main the half of characters : I want to send "versturen van data naar microcontroller" and the µC recievd only "versrn a mcr ". I have no problem with a other terminal. I think that it maby the programcode is. Hier is my code to transmitting data. bfData = "Versturen van data naar microcontroller."; unsigned long dwNumberOfBytesWritten; if(!WriteFile(hComm , bfData , 30 , &dwNumberOfBytesWritten , NULL)) { Application->MessageBoxA("Fout bij het versturen van de data !", "Error", MB_OK | MB_ICONSTOP ); CloseHandle(hComm); } else { Edit1->Text = dwNumberOfBytesWritten; } } Thanks, Jelle.
Hi Jelle, my first impression is the problem is on the microcontroller side; I think it can not keep up with the transmission speed. When you use a terminal instead of your app, you send characters as fast as you can type, which is only a few per second; your app would send that string in less than a second. Is you microcontroller using interrupts to receive serial characters? is there an operating system? does it need a task switch for every incoming character? or is there a buffer that could store an entire message (whatever that means, maybe something ending on CR or LF), and just signals the main program once the entire message has been received? what are you programming your uC in? assembly, C? what type of uC is it? do you disable interrupts for a long period of time? or do you have interrupt priorities, with some higher priority interrupt handler temporarily disabling your serial receive handler? you may try the following: - reduce the baud rate - add more stop bits Normally there should be no problem receiving data at 9600bd, that is assuming you did everything right. If the receiver is say a STAMP, programmed in Basic, then things may go wrong because too many CPU cycles get waisted in order to process a single incoming character. groeten
Luc Pattyn [Forum Guidelines] [My Articles]
this weeks tips: - make Visual display line numbers: Tools/Options/TextEditor/... - show exceptions with ToString() to see all information - before you ask a question here, search CodeProject, then Google
-
Hi Jelle, my first impression is the problem is on the microcontroller side; I think it can not keep up with the transmission speed. When you use a terminal instead of your app, you send characters as fast as you can type, which is only a few per second; your app would send that string in less than a second. Is you microcontroller using interrupts to receive serial characters? is there an operating system? does it need a task switch for every incoming character? or is there a buffer that could store an entire message (whatever that means, maybe something ending on CR or LF), and just signals the main program once the entire message has been received? what are you programming your uC in? assembly, C? what type of uC is it? do you disable interrupts for a long period of time? or do you have interrupt priorities, with some higher priority interrupt handler temporarily disabling your serial receive handler? you may try the following: - reduce the baud rate - add more stop bits Normally there should be no problem receiving data at 9600bd, that is assuming you did everything right. If the receiver is say a STAMP, programmed in Basic, then things may go wrong because too many CPU cycles get waisted in order to process a single incoming character. groeten
Luc Pattyn [Forum Guidelines] [My Articles]
this weeks tips: - make Visual display line numbers: Tools/Options/TextEditor/... - show exceptions with ToString() to see all information - before you ask a question here, search CodeProject, then Google
Hello Luc, Type µC is AT90S2313 or ATMEGA8535. Assemble is in C. nl : CodeVision. I do the follown. I recieved one character and place it in de eeprom, then I recieved the next character. That all with the USART from the µC. It is possible that the clock-cycles for this meby to slow. I tray with a slower bautrate. wil se. Jelle.
-
Hi Jelle, my first impression is the problem is on the microcontroller side; I think it can not keep up with the transmission speed. When you use a terminal instead of your app, you send characters as fast as you can type, which is only a few per second; your app would send that string in less than a second. Is you microcontroller using interrupts to receive serial characters? is there an operating system? does it need a task switch for every incoming character? or is there a buffer that could store an entire message (whatever that means, maybe something ending on CR or LF), and just signals the main program once the entire message has been received? what are you programming your uC in? assembly, C? what type of uC is it? do you disable interrupts for a long period of time? or do you have interrupt priorities, with some higher priority interrupt handler temporarily disabling your serial receive handler? you may try the following: - reduce the baud rate - add more stop bits Normally there should be no problem receiving data at 9600bd, that is assuming you did everything right. If the receiver is say a STAMP, programmed in Basic, then things may go wrong because too many CPU cycles get waisted in order to process a single incoming character. groeten
Luc Pattyn [Forum Guidelines] [My Articles]
this weeks tips: - make Visual display line numbers: Tools/Options/TextEditor/... - show exceptions with ToString() to see all information - before you ask a question here, search CodeProject, then Google
Hello Luc, I have my setting chance in Bautrate = 300 and stopbits = TWOSTOPBITS. It works. Thanks for everiting. If you have a problem. mail my. Jelle.
-
Hello Luc, I have my setting chance in Bautrate = 300 and stopbits = TWOSTOPBITS. It works. Thanks for everiting. If you have a problem. mail my. Jelle.
Hi Jelle, programming an EEPROM cell takes a while, could be from 10 microseconds to several milliseconds, really depends on specific hardware. If you did the code to program, you had to insert either a fixed delay, or a loop testing some READY bit; of course if you use a library to do it, you may not be aware of it (the documentation may tell you). If the EEPROM is also holding the code that is executing, then interrupts would (have to) be disabled I guess. Maybe the better approach is to have a buffer in RAM, collect a number of bytes, then program all of them (assuming programming N bytes is faster than N times programming 1 byte, depends again on hardware). If code is not running from same EEPROM (hence interrupts enabled), you may use two "ping-pong" buffers, one buffer gets programmed to EEPROM while the other receives new bytes; then switch their roles. Doing so would enable communication at 9600bd while programming! If you are new to this all, it may be too hard to get is all right. Even with your current set-up, you may try to figure out (from documentation or experiment) what the highest baudrate is for things to work reliably. 300 baud is really slow if you have say several KB to handle ! greetings
Luc Pattyn [Forum Guidelines] [My Articles]
this weeks tips: - make Visual display line numbers: Tools/Options/TextEditor/... - show exceptions with ToString() to see all information - before you ask a question here, search CodeProject, then Google
-
Hello Luc, I have my setting chance in Bautrate = 300 and stopbits = TWOSTOPBITS. It works. Thanks for everiting. If you have a problem. mail my. Jelle.
Hi Jelle, since you are transmitting binary data that goes into EEPROM, I assume it is code, hence all byte values can occur, including the ones you have selected for XON and XOFF. If your microcontroller has dataflow handshaking installed, this may go wrong when it receives these values, intended as data bytes, but interpreted as flow control characters. As far as I know there are only three correct approaches to solve this: 1. don't use flow control at all while transmitting binary data (so set dcb.fOutX and dcb.fInX false). 2. use a protocol, where your bytes are transmitted in another way, that does not conflict with the selected XON/XOFF characters; several of them are based on hex, meaning you send two characters to represent one byte. Examples are "Motorola S-records" and "Intel Hex". 3. use hardware handshake (that's based on some "control lines" such as "RTS" and "DTR", to be found on some of the connector pins of your serial port. Of course this requires you change the settings on the PC side, and the code on the microcontroller side. Anyway, some kind of protocol would be nice to have, so you do not just send the data to the microcontroller, but you actually have a conversation, so the PC keeps informed as to "everything goes well" or "failed to program EEPROM" or "Done" or whatever. Your original problem was having "character overrun", that is receiving a character while the previous character was not yet been read. There must be an error flag for that in one of the control registers, possibly also an error interrupt. Hope this helps you to better understand how it works, and how you can improve the robustness of your communication. Greetings
Luc Pattyn [Forum Guidelines] [My Articles]
this weeks tips: - make Visual display line numbers: Tools/Options/TextEditor/... - show exceptions with ToString() to see all information - before you ask a question here, search CodeProject, then Google
-
Hi Jelle, since you are transmitting binary data that goes into EEPROM, I assume it is code, hence all byte values can occur, including the ones you have selected for XON and XOFF. If your microcontroller has dataflow handshaking installed, this may go wrong when it receives these values, intended as data bytes, but interpreted as flow control characters. As far as I know there are only three correct approaches to solve this: 1. don't use flow control at all while transmitting binary data (so set dcb.fOutX and dcb.fInX false). 2. use a protocol, where your bytes are transmitted in another way, that does not conflict with the selected XON/XOFF characters; several of them are based on hex, meaning you send two characters to represent one byte. Examples are "Motorola S-records" and "Intel Hex". 3. use hardware handshake (that's based on some "control lines" such as "RTS" and "DTR", to be found on some of the connector pins of your serial port. Of course this requires you change the settings on the PC side, and the code on the microcontroller side. Anyway, some kind of protocol would be nice to have, so you do not just send the data to the microcontroller, but you actually have a conversation, so the PC keeps informed as to "everything goes well" or "failed to program EEPROM" or "Done" or whatever. Your original problem was having "character overrun", that is receiving a character while the previous character was not yet been read. There must be an error flag for that in one of the control registers, possibly also an error interrupt. Hope this helps you to better understand how it works, and how you can improve the robustness of your communication. Greetings
Luc Pattyn [Forum Guidelines] [My Articles]
this weeks tips: - make Visual display line numbers: Tools/Options/TextEditor/... - show exceptions with ToString() to see all information - before you ask a question here, search CodeProject, then Google
Luc, The max bauts I test is 1200 bauts. It works and I do not sent Kb. I try with programming my interrups from the µC for using faster bauts. Now I do it with this. It's fast enof. Thanks, I let you now of it is works. Jelle.