Unable to read string from USART

Go To Last Post
29 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I am unable to read answer string from modem, stuck in the row WHILE (!(USART0.STATUS & USART_RXCIF_bm)) in USART_0_read(). What's wrong in the code?

 

/*
 * File:   main.c
 * ATtiny202, MPLAB X IDE, XC8, Snap Debug Tool
 */

#define F_CPU 3333333

#include <xc.h>
#include <util/delay.h> // _delay_ms()

#define USART0_BAUD_RATE(BAUD_RATE) ((float)(3333333 * 64 / (16 * (float)BAUD_RATE)) + 0.5)

char AT_Send_OK[] = "AT\r"; // 3x

char OK_buff[16]; // 16x
char c; // Read char
int idx; // Index to OK_buff

//Disable digital input buffer on all IO pins

void USART_0_write(const uint8_t data) {
    while (!(USART0.STATUS & USART_DREIF_bm))
        ;
    USART0.TXDATAL = data;
}

uint8_t USART_0_read() {
    while (!(USART0.STATUS & USART_RXCIF_bm))
        ;
    return USART0.RXDATAL;
}

void Send_AT_CMD(char str[], int n_chars) {
    for (int n = 0; n < n_chars; n++) {
        USART_0_write(str[n]);
        while (!(USART0.STATUS & USART_TXCIF_bm)); //wait for USART TX complete
        USART0.STATUS = USART_TXCIF_bm; //Clear TXCIF flag
    }
}

void Read_AT_OK() {
    idx = 0;
    do {
        c = USART_0_read();
        asm("nop");
        OK_buff[idx++] = c;
        if (idx > 16) // More than 16 chars ?
            idx = 0;
    } while (c != ('\r' || '\n'));

    do
        c = USART_0_read(); // Flush '\n'
    while (c != '\n');

    OK_buff[idx++] = '\0';
}

int main() {
    VPORTA.DIR |= PIN6_bm; // Configure USART TX pin as output pin 2 (ATtiny202)
    VPORTA.DIR &= ~PIN7_bm; // Configure USART RX pin as input pin 3

    USART0.BAUD = (uint16_t) USART0_BAUD_RATE(9600);

    USART0.CTRLB |= USART_TXEN_bm; // Enable Transmitter
    USART0.CTRLB |= USART_RXEN_bm; // Enable Reciever

    while (1) {
        Send_AT_CMD(AT_Send_OK, 3); // Send AT command to modem ("AT\r")
        _delay_ms(100);  // Some delay to finish with send and to get reply from modem
        Read_AT_OK(); // Input string is 4F 4B 0D 0A ("OK\r\n")
        asm("nop");
        _delay_ms(500);
    }
}

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Is your cpu frequency  REALLY 3.333 MHz?

 

Why on earth do you do

((float)(3333333 * 64 / (16 * (float)BAUD_RATE)) + 0.5)

 When the result needs an integer? Do you know about  integer division?

 

Jim

Jim Wagner Oregon Research Electronics, Consulting Div. Tangent, OR, USA http://www.orelectronics.net

Last Edited: Sat. Oct 5, 2019 - 11:14 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
while (c != ('\r' || '\n'));

('\r' || '\n') is the same as (1)

 

so you end up with-

while( c != (1) );

and will probably be a long time before that is not true

 

this is probably want you wanted-

while( c != '\r' && c != '\n' );

Last Edited: Sat. Oct 5, 2019 - 11:37 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

See Microchip Getting Started with USART in the link here (pdf page 7).

 

Sending of strings works fine.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

It looks like that TXCIF is missing in the STATUS register:

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

>It looks like that TXCIF is missing in the STATUS register:

 

There is more than one STATUS register, you happen to be looking at the Nvmctrl STATUS for some reason (check the bit names, and the address of 0x1002). I don't know why it shows up as plain STATUS, but it does.

 

Use the IO view to check out io registers, which gives a better view of peripherals.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Why wouldn't you use getchar()/scanf()?

 

Just do an FDEV_SETUP_STREAM.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I corrected the STATUS to USART0.STATUS but still no progress. Unable to receive strings even in a loopback, sending works fine.

 

I would appreciate example code how to send and receive strings without interrupt for MPLAB X IDE with XC8 compiler for AVR Microcontroller (ATtiny202).

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

First- figure out what you are expecting to receive. When sending, you use '\r' as termination. When receiving, your code is looking for either \r\n or \n\n. If all you receive is a '\r',  then  you will be stuck waiting for a \n that will never show up.

 

Here is a modification of your original code, for an attiny416 nano board-

 

#define F_CPU 3333333

#include <xc.h>
#include <util/delay.h>
#include <stdbool.h>

#define USART0_BAUD_RATE(BAUD_RATE) ((float)(3333333 * 64 / (16 * (float)BAUD_RATE)) + 0.5)

void USART_0_write(const uint8_t data) {
    while (!(USART0.STATUS & USART_DREIF_bm));
    USART0.TXDATAL = data;
    //clear txcif any time writing data so can always
    //check this flag anytime to see if data is done
    //transmitting
    USART0.STATUS = USART_TXCIF_bm;
}

//return value = -1 = timeout or error
//return value >=0 = good data
//using a simple timeout (65k loops in this case)
int16_t USART_0_read(){
    uint8_t Hrx, rx;
    for(uint16_t timeout = 0xFFFF;;){       //pick a number
        Hrx = USART0.RXDATAH;               //get RXCIF and errors
        if( Hrx & 0x80 ) break;             //RXCIF set, have data
        if( timeout-- == 0 ) return -1;     //timeout error
    }
    rx = USART0.RXDATAL;                    //get data from rx buffer
    if( Hrx & 0x46 ) return -1;             //some error?, return -1
    return rx;                              //8 bit data (bit 9 is in Hrx if needed)
}

//just read rx 3 times to flush
//2 level buffer + shift register
void USART_0_flushrx(){
    (void)USART0.RXDATAL;
    (void)USART0.RXDATAL;
    (void)USART0.RXDATAL;
}

void Send_AT_CMD(const char* str) {
    for( ; *str; ) USART_0_write(*str++);
    USART_0_write('\r');
    //don't want any previous data that somehow came in
    //like extra \r or \n or unexpected error messages
    //so flush whatever is in rx before checking reply
    USART_0_flushrx();
    //now wait for USART TX complete so do not
    //start to attempt receive until done sending
    while (!(USART0.STATUS & USART_TXCIF_bm));
}

//incoming data needs to match str
//then a \r or a \n
bool Read_AT(const char* str) {
    int16_t c = 0;
    for( ; *str; str++ ){       //until end of str
        c = USART_0_read();     //get char (if timeout or error, is -1)
        if( c != *str ) break;  //not a match, no more checking
    }
    c = USART_0_read();         //try to get terminator
    //if last char was a terminator char, and *str is 0, then
    //the match is true, else is false
    return ( c == '\r' || c == '\n' ) && *str == 0;
}

//blink led n times
//at416 nano board
void tiny416nano_ledblink(uint8_t n){
    for( ; n--; ){
        VPORTB.OUT &= ~PIN5_bm; //on
        _delay_ms(50);
        VPORTB.OUT |= PIN5_bm; //off
        _delay_ms(50);
    }
}

int main() {
    //VPORTA.DIR |= PIN6_bm; // Configure USART TX pin as output pin 2 (ATtiny202)
    //VPORTA.DIR &= ~PIN7_bm; // Configure USART RX pin as input pin 3

//  (ATtiny416)
VPORTA.DIR |= PIN1_bm;
VPORTA.DIR &= ~PIN2_bm;
PORTMUX.CTRLB |= 1; //alt pins

    USART0.BAUD = (uint16_t) USART0_BAUD_RATE(9600);

    USART0.CTRLB |= USART_TXEN_bm; // Enable Transmitter
    USART0.CTRLB |= USART_RXEN_bm; // Enable Reciever

USART0.DBGCTRL = 1;
//tiny416 nano board led
VPORTB.OUT |= PIN5_bm; //high=off
VPORTB.DIR |= PIN5_bm; //output

    while (1) {
        Send_AT_CMD("AT");
        if( Read_AT("OK") ){
            tiny416nano_ledblink(5);
        } else {
            tiny416nano_ledblink(1);
            _delay_ms(400);
        }
        _delay_ms(1000);
    }
}

 

this was compiled/debugged on a tiny416 nano board, and the AT\r command was being received on the pc, and the pc was sending OK\r to the board and the led lights indicated the OK was a match.

 

There may be ideas in there that you can use if wanted. Some notes-

 

-when dealing with 0 terminated strings, there is usually no need to be concerned with size as you have the 0 to mark the end of the string

-a usart receive with some method to deal with errors and timeouts (when polling) is not too hard to do, so may as well do it

 you can also move the timeout out of the read() function and let the caller deal with it (just return -1 if no data available)

 what you don't want, is waiting around (blocking) for something that never shows up or will never show up for any number of reasons

-clear the txcif flag anytime you write to tx, so this flag can be checked anytime and always be valid (with one exception, if no data was ever tx)

-the Read_AT function will try to match a passed in string from the rx data, I think its correct (and did work when tested with "OK"), but you can

 work out what is happening- anything other than an exact match of the string followed by a \r or \n will return false- and also leave any other

 incoming chars in the rx buffer(s), which will get flushed later (I don't know what the incoming terminator char is, but will work with any combo of \r and \n)

-you may have to play around with the timeout values in USART_0_read(), or just use _delay_us() in the loop, or something else, I think

 65k loops of that code at 3.3MHz will be over 150ms but using a _delay_us() in there may be better as you then know what you are getting

 

 

 

 

 

Last Edited: Mon. Oct 7, 2019 - 04:53 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Maybe:

    USART0.DBGCTRL = 1;  // run during debug

during initialization?

 

Otherwise, my (working) code looks just like yours.

https://github.com/Optiboot/opti...

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

As I said in #7 life is a lot easier if you just connect stdout/stin/stderr to a UART stream:

void USART_0_init() {
    VPORTA.DIR |= PIN6_bm; // Configure USART TX pin as output pin 2 (ATtiny202)
    VPORTA.DIR &= ~PIN7_bm; // Configure USART RX pin as input pin 3

    USART0.BAUD = (uint16_t) USART0_BAUD_RATE(9600);

    USART0.CTRLB |= USART_TXEN_bm; // Enable Transmitter
    USART0.CTRLB |= USART_RXEN_bm; // Enable Reciever
}

int USART_0_write(char data, FILE *stream) {
    while (!(USART0.STATUS & USART_DREIF_bm))
        ;
    USART0.TXDATAL = data;
    return 0;
}

int USART_0_read(FILE *stream) {
    while (!(USART0.STATUS & USART_RXCIF_bm))
        ;
    return USART0.RXDATAL;
}

FILE uart0_stream = FDEV_SETUP_STREAM(UASRT_0_write, USART_0_read, _FDEV_SETUP_RW);

int main(void) {
    char c = 'x';

    USART_0_init();

    stdin = &uart0_stream;
    stdout = &uart0_stream;
    stderr = &uart0_stream;

    printf("Hello world\n");
    printf("c is %02X\n", c);
    c = getchar();
    printf("c is now %c\n", c);
    // hopefully you get the idea? puts(), printf(), getchar(), scanf() all work...
}

The single character write and read functions are the ONLY ones you have to implement - you get all the other IO functions in the standard C library for free!

Last Edited: Mon. Oct 7, 2019 - 08:46 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

Once you've sorted out your basic serial comms issues, note:

Kevil wrote:

        Send_AT_CMD(AT_Send_OK, 3); // Send AT command to modem ("AT\r")
        _delay_ms(100);  // Some delay to finish with send and to get reply from modem
        Read_AT_OK(); // Input string is 4F 4B 0D 0A ("OK\r\n")

You are making the classic mistake of relying upon blind delays - do not do that!!

 

See: https://www.avrfreaks.net/commen... and the linked threads in the rest of that thread.

 

 

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

>Otherwise, my (working) code looks just like yours.

RXCIF is also in the rx data H byte, so you can save yourself one lds by eliminating the need to also read status. Not that important, but its there so may as well use it.

 

>As I said in #7 life is a lot easier if you just connect stdout/stin/stderr to a UART stream:

You just filled up 97% of the flash in his tiny202 with your example and have not yet begun to use scanf. Eliminating var arguments to printf in your example cuts that down quite a bit (so then no purpose to it), but bring in any scanf variants and you are over 2k again.

 

 

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

clawson wrote:
you get all the other IO functions in the standard C library for free!

"Free", that is, in terms of programmer effort to write the code;

but, as curtvm wrote:
You just filled up 97% of the flash in his tiny202

 

Which all goes to show that there is no such thing as a free lunch!

 

laugh

 

Pretty sure it has been questioned before whether the Tiny202 is actually a sensible choice for this project - as AT Commands is going to involve a lot of formatted string I/O ...

 

frown

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

curtvm wrote:
You just filled up 97% of the flash in his tiny202 with your example and have not yet begun to use scanf. Eliminating var arguments to printf in your example cuts that down quite a bit (so then no purpose to it), but bring in any scanf variants and you are over 2k again.
I simply showed printf() to show that it was available - no one said it HAS to be used. Simply that <stdio.h> is no "switched on" and everything it offers is available - like a kid in a sweet shop nothing says you HAVE to grab everything!

 

PS I agree with Andy - a 2K micro is not the right place for an AT based UART app.

Last Edited: Mon. Oct 7, 2019 - 10:17 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Actually I am downsizing the working code for Arduino Pro Mini ATMega328P 3.3V to ATtiny202. I am almost done, the code is about 1 kB (1/2 ATtiny202) and I don't need to use any string library (more than 1k) to send and receive data to Wisol modem BRKWS01 (SigFox IoT). I guess I have somewhere just a small bug in my code to be able to catch reply from the modem.

I have a SNAP step debugger (UPDI) and TeraTerm program to see (and log) received and sent modem data. As I mentioned already sending of dat works without any problem, modem answers correctly (TeraTerm).

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

Kevil wrote:
bug in my code to be able to catch reply from the modem.

See above - Blind Delays.

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I don't think it has something to do with delays, sending works without any problems.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 2

I fear you may have missed the point. You were being warned about the general design of:

        Send_AT_CMD(AT_Send_OK, 3); // Send AT command to modem ("AT\r")
        _delay_ms(100);  // Some delay to finish with send and to get reply from modem
        Read_AT_OK(); // Input string is 4F 4B 0D 0A ("OK\r\n")

Suppose that:

 

a) the modem is going to respond "OK" but it does not do so within 100ms or,

 

b) the modem returns something other than "OK"

 

There's been about 4 decades of development based around the Hayes command set so the general approach is well known these days. As there are so many different send/receive response patterns in Hayes the usual way to operate is with some kind of "state machine". You send a command and then start to receive the returned characters one by one. As each comes in you can make a decision about where to go next. You don't just delay N milliseconds and expect the response to be present. Instead you just wait for characters - however in doing that it is permissible to also implement some kind of timeout. If the modem has died or it's firmware has locked up or whatever it might be that you could wait for ever for a response so you maybe say "if I haven't got anything in 1000ms I give up" and return that as an error condition to the higher processing levels.

 

Don't just think that because most of the time you send a command and after allowing it 100ms it always seems to respond OK that this is what will always happen. You have to program for all eventualities or you could end up with code that gets "out of sync" with what the modem is up to.

 

As I say, folks have been driving Hayes for 4 or more decades so they way to handle it is well established with lots of internet published example code to study.

 

EDIT: Hayes is currently 38 years old in fact ;-)

Last Edited: Mon. Oct 7, 2019 - 02:33 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

Kevil wrote:
I don't think it has something to do with delays

Why not?

 

 sending works without any problems.

Indeed - it has nothing at all to do with sending.

 

You said you have a problem with receiving.

 

Putting an arbitrary, blind delay before you start listening could mean that you will miss (some of) the reply.

 

That will give you a problem with receiving.

 

even if it isn't the immediate problem now, using blind delays in AT commands is asking for trouble.

 

See the linked threads for details.

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

clawson wrote:
Don't just think that because most of the time you send a command and after allowing it 100ms it always seems to respond OK that this is what will always happen.

Especially with cellular modems!

 

Often, the command will require the modem to interact with the network; that will introduce variable - and potentially long - delays.

 

So you might find that it all seems to go OK while it's just sitting on your desk, but then you get some network "hiccup" and your entire system stops completely - because it keeps trying to blindly trundle on with its arbitrary delays, just getting further & further out of step with reality.

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

If there are no decisions made based on what is replied, you may not even need to deal with any replies. Somewhere I got the impression you are simply waking up, reading a voltage, sending it out, go back to sleep. If the wireless does not respond to 'AT', then what? If you do not get an 'OK', what are you going to do about it? Keep trying until you get an 'OK'? Keep re-sending the same thing that is causing the error? or is the wireless device not reliable enough to accept a simple command, and needs multiple tries?

 

My guess is you could send your commands with a certain delay between them (if multiple commands), and do it all day long without ever having to deal with the replies. If you think that is not reliable enough for some reason, then just send your data a few times before sleeping again- if there was a problem, one of them probably succeeded, if not there was nothing you were going to do about it anyway (we are talking tiny202, not a pc).

 

Maybe you want the receive whether needed or not, and that is fine. Just suggesting maybe it is of little value in this case.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Usually, if the result is not OK it will be an error code giving the reason for failure.

 

You should check that reason to see if it's likely to be recoverable or not, or if a simple re-send is sensible, or ...

 

 

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
 Send_AT_CMD(AT_Send_OK, 3); // Send AT command to modem ("AT\r")
        _delay_ms(100);  // Some delay to finish with send and to get reply from modem
        Read_AT_OK(); // Input string is 4F 4B 0D 0A ("OK\r\n")

Thus far, people have been complaining about this, but the OP has been resistant, not understanding how problems *there* can lead to their apparent hang in USART0_read()

But it's right there:   In the 100ms that you're simply delaying, you're expecting the other side to send 4 characters.  The hardware USART has ONLY 2 bytes of buffering, so one of the characters will be discarded.

Then read_AT_OK() will try to read more characters than are in the buffer, but some of them won't be there, so it will apparently "hang" looking for a "received data complete" of a character it as already thrown away.

 

This would be a little more obvious with a longer string, and an "echo" function that prints what you've received somewhere.

If you send a sleeping chip "ABCDEFGH" and then read "all the characters", you'll usually see something like "ABH" (two characters sitting in the buffer, one still in the shift register that couldn't be transferred.)

 

The whole "sleep while waiting for the full response" that is pretty common in Arduino-style programming (or, "big computer processing", though then it'll be hidden by the OS) is fraught with peril (as many people have said, already), ESPECIALLY when the buffering available is smaller than the messages.   (OTOH, it might also be considered a way to save memory.  Why buffer data in an ISR and then have another buffer in your main code that will hold the same message?.)  But for this to work, your main code needs to be relatively convoluted, passing bytes through some sort of state machine or parser "on the fly."

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

This is also glossed over-

https://www.avrfreaks.net/commen...

 

He is trying to 'flush' a \n that may or may not ever be seen.

 

I think this is his modem, and its at commands-

https://github.com/Thinxtra/Xkit-Sample/blob/master/Document/Wisol_ATCommands_and_Datasheets/WISOL_WSSFM10R_AT%20command_SFM10R_Rev.00_1.pdf

 

not much info about CR/LF usage, or even if there is any error messages (I doubt it- seems to be OK for responses without data, or response with data, or no reply if error?)

all examples use \r for sending commands, so maybe the device replies with only \r also, and a \n is never seen (which would be one reason he is stuck in his loop)

 

There seems to be enough info in this thread, it just needs to be read.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The use of CR and LF is part of the Hayes standard - now formalised as V.250:

 

https://www.avrfreaks.net/commen...

 

eg, see: https://www.avrfreaks.net/commen...

 

Command Terminator (S3) & Result Formatting (S4) characters: https://en.wikipedia.org/wiki/Ha...

 

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
Last Edited: Tue. Oct 8, 2019 - 08:57 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

>The use of CR and LF is part of the Hayes standard - now formalised as V.250:

 

Somehow, I doubt that the maker of the wireless device is too concerned with following any kind of standard. Like most of these devices they just copy the general idea of the AT command set. If they send a \r only, that is what you get and waiting around for \n that will never show up will keep you waiting until your batteries die-

   do
        c = USART_0_read(); // Flush '\n'
    while (c != '\n');

Its certainly easy enough to figure out what is being sent and code accordingly.

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

curtvm wrote:
Its certainly easy enough to figure out what is being sent and code accordingly.

Indeed.

 

Or even code to accept either CR or LF - or both

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The sending to IoT network can takes about 12 seconds in the IRQ routine once a hour. I need to get a response from the modem to be sure I can safely let sleep the modem and ATtiny202 again before next IRQ wakeup an hour later.

I will try to modify the code to use USART interrupt driven send and receive.