Problem with the first byte when receiving data

agalmarini

New Member
Hi!

I've some strange problem with the RF receiver (NKM2401+14M2) circuit connected to the PC (via sertxd).

Everything is working fine, with the exception of the firtst byte.

For example, if the Transmitter sends "Test1234", I receive in the PC: [F5]est1234

Any idea to solve the problem is more than welcome!
:D

Below I'm enclosing the code. The ciruit is the standard one (AXE213).

Thanks for your help!
Agustin


Code:
symbol pinDATA = B.4
symbol pinREADY = pinB.3
symbol pinSEND = B.5
symbol pinLED = C.0

main:
	low pinSEND
	high pinLED

MainLoop:
	low pinSEND
        if pinREADY=1 then goto MainLoop
	high pinSEND
	serin pinDATA, n2400,b0,b1,b2,b3,b4,b5,b6,b7
	low pinSEND
	sertxd (b0,b1,b2,b3,b4,b5,b6,b7,CR,LF)
	goto MainLoop
 

agalmarini

New Member
Thanks westaus55 for your prompt reply.

The error is consistent, I mean, same input => same erroneus output.

For the first byte (the other 7 are OK):

Instead of [01] it writes [C0]
Instead of [02] it writes [E0]
Instead of [03] it writes [E0]
Instead of [04] it writes [F0]
Instead of [05] it writes [C1]
Instead of [06] it writes [F0]
Instead of [07] it writes [F0]
Instead of [08] it writes [F8]

Is this aligned with your explanation?
Thanks again!
 

hippy

Technical Support
Staff member
First thing to check would be that the data you are seeing is actually corrupted, isn't actually a corruption of the SERTXD first byte giving the impression data is corrupted when it isn't. Change your SERTXD to ...

sertxd ("First Byte = ", #b0, 9, "Text = ", b0,b1,b2,b3,b4,b5,b6,b7,CR,LF)
 

hippy

Technical Support
Staff member
Looking at the results, "T" ($54) sent, $F5 received; it could be that the PICAXE is not ready quickly enough to receive the first byte sent after it sets the 'send' signal high ...

Code:
"T" = $54 = %01010100, lsb first = 00101010
          _____   _   _   _ 
Nbaud = _|     |_| |_| |_| |_______
        I S 0 0 1 0 1 0 1 0 P I I I

$F5 = %11110101, lsb first = 10101111
                  _   _   _
Nbaud =         _| |_| |_| |_______________ 
                I S 1 0 1 0 1 1 1 1 P I I I
It may be worth adding a "SETFREQ M16" and changing to N2400_16, seeing if that improves things.
 

agalmarini

New Member
Thanks hippy, I set the frequency to 16 and started to work!

I understand the principle of your explanation (not enough time to receive the first byte between instructions), but I'm not very familiar with the protocol...

it sends first (I+S?)+8bytes and then 1's?

In such case, I understand that it missed the first 4 bytes (0010) and replaced them with 1111 (from the end).

Is that correct?

Thanks again!
 

hippy

Technical Support
Staff member
Sorry for not explaining; in the diagrams; I = Idle, S = Start Bit, 0/1 = Data Bit, P = Stop Bit.

You are right, except it is bits not bytes.

SERIN reading a byte waits for an Idle level, waits for the Start Bit, then clocks in the eight subsequent data bits. After that it starts looking for the Idle level then another Start Bit and does it again, or is done and executes the next command in the program.

If the SERIN starts executing when the sender is already outputting the Start Bit (or later ), it will skip the Start Bit and Data Bits until it finds what it thinks is an Idle followed by a Start Bit. It then reads what it thinks are eight Data bits and likely takes some Idle in as the data it thinks it received.
 

giokal

New Member
Regards, friends, I have been looking for some explanation of the behavior of this command, I have a similar problem that has me head !, in my case waiting for the "OK" response of an ESP01. The esp01 transmits at 9600 bps and my command serin (in my 40x2) set it to: t9600_16, however sometimes I can read the "OK" and in others not, will "serin" not see the idle levels? I found that the output pin of the esp01 when it is inactive is high, I do not know if this helps to find the problem.
Thanks for any help!
 

giokal

New Member
Hello, Phil, the connection between 40x2 and esp01 goes through a logic level converter like that offered by BricoGeek or Sparkfun (based on the mosfet bss138). What I notice is that the port of the 40x2 that at that moment is in high impedance, needs a logical level zero (according to entering the thread # 5 the idle is in low level) but in my case the esp01 delivers a high level while not Shows activity (at rest), sometimes the command "serin" reads "OK" but at other times not, then I suspect that the port is confused in ilde reading, am I correct?
 

PhilHornby

Senior Member
Logic levels ... or voltage levels...

Well it's entirely possible that the logic levels are the wrong way round - but that wouldn't explain why it works sometimes and not others, would it?

Have you got a USB-to-Serial adaptor (this sort of thing), that you could connect in parallel with the ESP output, just to prove that it is valid data. Monitor on a PC, using Realterm or Putty. Those little adaptor boards normally have a 3V/5V jumper, but I think it only affects their o/p signals - I've used them successfully with Picaxe @ 5V and Esp8266 @ 3.3V.
 

giokal

New Member
Between the esp01 and the 40x2 port connect this logic level converter https://learn.sparkfun.com/tutorials/bi-directional-logic-level-converter-hookup-guide , no creo que alla conflicto en los niveles voltaicos sin embargo revise esto valores y son aceptables: 4,85v (para TTL) y 3,27 (hacia el esp01) ,Following your advice connect the usb to serial converter, and the esp01 (TX-esp01) output pin RX to the USB-SERIAL To monitor the responses of esp01, The data that shows the PUTTY is correct, I see how the esp01 is interrogated by the 40x2 and it responds (esp01)

screen putty.JPG

As you can see the situation is simple, to each sending of data using the command "serout" the esp01 responds with "OK", my situation is that I need to verify the response of esp01 since according to the sending can respond OK, ERROR, busy p...
And for this of course I need to support myself in the command "serin",I suspect that the issue is in the "IDLE" (which I still have not clear) my transmission as I told you is T9600_16 and the esp01 also responds at 9600 bps.....I will continue investigating
 

PhilHornby

Senior Member
I think this might be the age-old problem of the Picaxe simply not having a SERIN command active at the time the data arrives. Or even that SERIN doesn't see enough data to complete, or it terminates (on a timer) too soon.

No 'type-ahead' buffering is implemented, so if the data arrives before the SERIN is executed, it's just lost. (This doesn't seem to be the case going the other way, Picaxe->ESP8266).

If true, there are several ways to counter it:-
  • Careful tailoring of the SERIN - consider using things like the leading <linefeed> character as prefix, to stay in sync. If it's purely down to timing, this may not help you. (Lower the baud rate, and increase the clock speed?)
  • Make of use of Background-Serial-Receive - i.e. HSERIN
  • Modify the code that the ESP8266 is running, to make it more Picaxe-friendly. This is not as involved as it sounds, but the learning curve is not insignificant. (The Arduino IDE has been ported to the ESP8266, and there's another one - who's name I can't remember at the moment). Any modifications would have to be made in that nasty 'C' language, but it doesn't have to be pretty, if only you will see it :). This is what I would do, for the simple reason that I found the default "AT" firmware, rather awkward to use (IIRC, there is no truly 'transparent' mode, for example.)
 
Last edited:

giokal

New Member
Ok Phil,I will consider all your suggestions,I made some lines of code to recognize that it is entering:
Code:
serout A.7,baud,("AT+CIPSTART=1,",34,"TCP",34,",",34,"192.168.1.8",34,",3332",13,10)
pause 500

 'B44 to  B51 load response CPISTART
serin A.6,baud,B44,B45,B46,B47,B48,B49,B50,B51
sertxd("b44=",#b44," b45=",#b45," b46=",b46," b47=",b47," b48=",b48," b49=",b49," b50=",b50," b51=",#b51,13,10)
And this is what I get:
Code:
b44=13 b45=10 b46=O b47=K b48=13 b49=10 b50=85 b51=110
b44=13 b45=10 b46=O b47=K b48=13 b49=10 b50=76 b51=105
b44=13 b45=10 b46=O b47=K b48=13 b49=10 b50=85 b51=110
b44=13 b45=10 b46=O b47=K b48=13 b49=10 b50=76 b51=105
b44=13 b45=10 b46=O b47=K b48=13 b49=10 b50=76 b51=105
b44=13 b45=10 b46=E b47=R b48=R b49=O b50=R b51=13
b44=13 b45=10 b46=E b47=R b48=R b49=O b50=R b51=13
b44=13 b45=10 b46=E b47=R b48=R b49=O b50=R b51=13
As you can see the esp01 answers before the "OK" or "ERROR" with CR and LF, why does that?
 
Last edited:

PhilHornby

Senior Member
As you can see the esp01 answers before the "OK" or "ERROR" with CR and LF, why does that?
The "AT" command set was used on modems, back in the early 1980s. The device attached to a modem was a simple VDU/teletype (and a human!). The LF was to move to the next line down on the screen, and the CR to move to the start of that line. It's a very odd 'protocol' to be using in 2016, for communication between microcontrollers!

As your code stands, the delay between the ESP receiving the instruction "AT+CIPSTART=..." and it responding has to be very close to 500mS, or the SERIN will miss it. If you were to issue the SERIN immediately after the SEROUT, and use "CR,LF" as the prefix - you may find this bursts into life. Use a TIMEOUT label, since you can't be completely sure of the length of the response. Also, consider using the @BPTRINC instruction (multiple times) to receive your data, so that you don't tie up all your named variables.

This sort of thing:

Code:
      [COLOR=purple]bptr [/COLOR][COLOR=darkcyan]= [/COLOR][COLOR=black]SomewhereInRam                           [/COLOR][COLOR=green];address of our storage
      [/COLOR][COLOR=blue]serin [PLAIN][[/PLAIN][/COLOR][COLOR=black]OneSecond,noAnswer[/COLOR][COLOR=blue][PLAIN]][/PLAIN][/COLOR][COLOR=black],[/COLOR][COLOR=blue]RX_Pin[/COLOR][COLOR=black],Baudrate,[/COLOR][COLOR=blue](CR[/COLOR][COLOR=black],[/COLOR][COLOR=blue]LF)[/COLOR][COLOR=black],[/COLOR][COLOR=purple]@bptrinc[/COLOR][COLOR=black],[/COLOR][COLOR=purple]@bptrinc[/COLOR][COLOR=black],[/COLOR][COLOR=purple]@bptrinc[/COLOR][COLOR=black],[/COLOR][COLOR=purple]@bptrinc[/COLOR][COLOR=black],[/COLOR][COLOR=purple]@bptrinc[/COLOR][COLOR=black],[/COLOR][COLOR=purple]@bptrinc[/COLOR][COLOR=black],[/COLOR][COLOR=purple]@bptrinc[/COLOR][COLOR=black],[/COLOR][COLOR=purple]@bptrinc [/COLOR][COLOR=green]; 8 bytes.[/COLOR]
[COLOR=black]noAnswer:[/COLOR]
 
Last edited:

giokal

New Member
Ok Phil, these are my calculations:
Code:
pause 500@8Mhz = 500ms=0,5s but i use 16Mhz, then pause 500 = 250ms
ESP01 transmit to 9600 bps, so "[COLOR="#0000FF"]LF[/COLOR]" and "[COLOR="#0000FF"]CR[/COLOR]" = 16bit's ,Then by three simple rule these 16 bits consume 1.67ms
Then "pause 500" is a very long time with respect to the time passed by LF and CR while "O..K" or "E ... RROR" arrives, I understood correctly?...
On the other hand if I delete this "pause" between serout and serin then "serin" will start loading the registers from the first byte that dispatches the esp01 and thus see in which address "drops" the byte that interests me, is this reasonable?
The timeout you propose is one second? or an estimated time?
 
Last edited:

hippy

Technical Support
Staff member
Code:
serout A.7,baud,("AT+CIPSTART=1,",34,"TCP",34,",",34,"192.168.1.8",34,",3332",13,10)
pause 500
serin A.6,baud,B44,B45,B46,B47,B48,B49,B50,B51
You really don't want a PAUSE between SEROUT and SERIN; that will be unreliable at some point in time.

Perhaps if you could define what you want to achieve it would help in providing the most satisfactory answer. If you just want to check the "OK" was sent so you know the AT command was actioned you can probably do the following -

Code:
serout A.7,baud,("AT+CIPSTART=1,",34,"TCP",34,",",34,"192.168.1.8",34,",3332",13,10)
serin [1000,Failed], A.6,baud,("OK")
pause 500
You will need a label "Failed:" somewhere to handle when things have not worked. You should be able reduce, maybe remove, the "PAUSE 500" after the SERIN, but leave them in until you get it to work, eg ...

Code:
serout A.7,baud,("AT+CIPSTART=1,",34,"TCP",34,",",34,"192.168.1.8",34,",3332",13,10)
serin [1000,Failed], A.6,baud,("OK")
pause 500

serout A.7,baud,("AT+......................",13,10)
serin [1000,Failed], A.6,baud,("OK")
pause 500
 

giokal

New Member
Hi hippy, If I use "timeout" it means that the answer that receives "serin" can not be either before it concludes in time or after that after this lapse of waiting, that is to say it must receive exactly once the timeout is concluded, I am in the correct thing?
 

hippy

Technical Support
Staff member
If "OK" is received ( regardless of whether any leading CR or LF is present or not ) the program will continue immediately with the next command. There may need to be a PAUSE to allow for any subsequent CR or LF after the "OK".

If nothing is received, or anything other than that "OK", the code will continue at the "Failed:" label.
 

PhilHornby

Senior Member
@giokal The approach that Hippy has suggested, is simpler than mine - and should work for the 'setup' commands. When it comes to handling the actual data, you may need to take the approach I suggested.
 

giokal

New Member
Certainly what says hippy is quite clear however my intrigue is: how wide should be the pulse of "timeout" for the command "serin" wait for the qualifier or time out waiting for the qualifier and go to the tag that accompanies To the timeout. I did several tests reducing the timeout below 1000 and effectively runs out of time and jumps to "Failed" on the contrary raise the value of timeout far from 1000 and serin caters to the qualifier with which I approach more to the explanation of behavior of the timeout.
The code suggested in thread # 15 seems to me quite useful, in fact it allows me to load all the answers of the esp01 that can analyze and to infer, certainly it is a line of code very useful! .... I am already advancing ... thanks for Support Phil and equally hippy!:cool:
 

PhilHornby

Senior Member
my intrigue is: how wide should be the pulse of "timeout" for the command "serin" wait for the qualifier or time out waiting for the qualifier and go to the tag that accompanies To the timeout. I did several tests reducing the timeout below 1000 and effectively runs out of time and jumps to "Failed" on the contrary raise the value of timeout far from 1000 and serin caters to the qualifier with which I approach more to the explanation of behavior of the timeout.
In Hippy's code, the SERIN is waiting for the string "OK", and will complete - and do nothing else, once it sees it. However, what if the ESP8266 sends "ERROR" instead? ... or some other string ... or nothing at all. Without the timeout, you'd be stuck there for ever ... so if "OK" hasn't been seen after the specified timeout period, code execution will resume at the specified label.

Regarding its value; it needs to be 'long enough', that it never times out in normal operation ... and 'short enough', that your code is not held up unnecessarily. You'll have to make a judgement on that!

(You may find you want to use different timeouts for different commands. Setting some parameters on the ESP8266 will be very quick, whereas instructing it to connect to a particular Access Point, may take much longer.)
 

hippy

Technical Support
Staff member
An important thing to to do is list all the AT commands you will be sending, what responses you need to be able to continue, and which responses you need to extract information from.

Then the response handling commands can be tailored to what those responses are expected to be.

The program will be sending a series of AT commands, so what are those commands and what other interaction is there ? An overview of what you are attempting to achieve in total may also help

Regarding SERIN timeouts; it won't matter how long they are when the expected response is received, as the program will continue immediately. If there is a long timeout for when that response is not received it probably does not matter either because things are not going anywhere fast if the responses are not as required to be.

In this phase of development it is more important that the program works rather than how well it works. I would not worry over timeout and pause periods for now if things work. Get everything working then come back if needed to adjust timeouts and pauses.
 

hippy

Technical Support
Staff member
The ESP8266 AT Command datasheet is available here ...

https://www.itead.cc/wiki/images/5/53/Esp8266_at_instruction_set_en_v1.5.4_0.pdf

I have never used the ESP8266 but it seems it should be easy enough to connect to a Wi-Fi router or access point, send out status reports to an appropriate server, close the connection and repeat using SEROUT/SERIN.

For more complicated interactions, receiving data from servers or clients, it may be necessary to utilise the PICAXE background serial receive capabilities of X2 variants.

It might also be appropriate to run a LUA or some other interpreter on the ESP8266 and have that run a script which can manage what interactions there are between the internet and PICAXE, make things easier for the PICAXE to deal with through SERIN and SEROUT.

How it would be done would depend on what the project goal is. It would be best to define what the project goals are, design a solution using a top-down approach, rather than attempt to evolve a bottom-up solution which might not suit how the ESP8266 works.
 

PhilHornby

Senior Member
It might also be appropriate to run a LUA or some other interpreter on the ESP8266 and have that run a script which can manage what interactions there are between the internet and PICAXE, make things easier for the PICAXE to deal with through SERIN and SEROUT.
I'd forgotten about the LUA stuff; I'd also forgotten about the 'Basic' implementation - see: https://www.esp8266basic.com/
 

giokal

New Member
Hi, Thanks to all for the contribution of these last two post, in principle regarding the line that comments Phil
Code:
serin [1000,Failed], A.6,baud,("OK")
I did some tests with it (excluding in timeout) and I can conclude that it can be used to establish a strict control of the qualifier that should arrive and if this does not arrive the micro will be waiting eternally for this, of course the timeout establishes a maximum lapse of waiting (I already understood its use) by the qualifier.

(You may find you want to use different timeouts for different commands. Setting some parameters on the ESP8266 will be very quick, whereas instructing it to connect to a particular Access Point, may take much longer.)
This is true since although most of the answers are: OK, ERROR, SEND OK, Linked and in other cases you get a very long data string, in my case for now I need to verify OK and ERROR. The length of data I send through SEROUT varies in length so the time of sending varies, not so much the response time (I have already measured it) so that reflection is quite right.
Already organize the commands that I have to use and as hippy suggests to make an internet connection and this is done in two stages: one is connection to the router:
Code:
serout A.7,baud,("AT",13,10) 'Send attention command+CR+LF to rx_ESP-01
pause 1000

	;sertxd("AT OK",13,10)

CWMODE:'mode AP:1 Station:2 AP+STA:3
serout A.7,baud,("AT+CWMODE=1",13,10)
pause 1000
CWJAP:'join to wifi
serout A.7,baud,("AT+CWJAP=",34," name router",34,",",34,"password router",34,13,10)
pause 10000 '
 
CIFSR:'get IP
serout A.7,baud,("AT+CIFSR",13,10)
pause 1000
	
CIPMUX:'ajuste modo conexion 1:conex multiple,0:mode conex individual	
serout A.7,baud,("AT+CIPMUX=1",13,10)
Then you already have a connection to the router...
The next step is the internet connection to reach a server, To do this use the line that posts above: + CIPSTART and then + CIPSEND, and finally I am using + CIPCLOSE to close the connection to the server and + CWQAP to disconnect me from the ruoter.
Based on these two ideas I'm already starting to do supervising the responses in the AT commands that are mentioned above.

The esp8266 is quite powerful starting from two gpio for the case of esp01 and arriving at a good amount in the versions of ESP's more sophisticated that not counting that runs at 40Mhz and more ...So it seems to me an excellent device to develop IoT.

How it would be done would depend on what the project goal is. It would be best to define what the project goals are, design a solution using a top-down approach, rather than attempt to evolve a bottom-up solution which might not suit how the ESP8266 works.
On this reflection I think it's a golden rule for developers ..

I'd forgotten about the LUA stuff; I'd also forgotten about the 'Basic' implementation - see: https://www.esp8266basic.com/
Is a really good page and is referential, for those who like to work with picaxe, serious as the adage says: "handle bicycle" ... thanks again for the contribution ...
 
Top