I'm trying to create a system in which one unit acts as a central server to 25 special hardware clients.
All devices utilize the same specs that I will explain in a moment.
The system begins with the central server sending out an 11-byte packet to the first client. This packet is similar to UDP in a sense where one byte is sender, one byte is recipient, bytes in-between are data and last byte is checksum of all bytes. The client will have x amount of time to reply back to the server with a packet in the same format. Only different is that the sender and recipient values are swapped and the other fields are different. If the client replied in time, then the server stalls until x amount of time has reached. Process repeats with the next client and wraps back to client 1 after client 25.
All radio modules are the HM-TRP and are attached to the micro uarts. They're set to the following:
56Kbps uart speed 56Kbps air link speed 175Khz bandwidth 58Khz deviation Maximum transmission
Each microcontroller is an AT89S52 with a 22.1184Mhz crystal attached and I ordered some AT89S8253 because it has a X2 speed option that I'll utilize when I receive them, but until I receive those, I want to try to work with what I have to achieve the best speed.
The way the uart data system works on each client and server when receiving data is as follows:
A low-priority timer is run to determine when no more data arrives. If data arrives, then the serial routine interrupts the program to load in the new byte and the timer is overflown so that the timeout value is reset and the remote will have time to send the next character. If data is timed out, then the receive buffer is flushed and the sender must start over with sending data. But if the serial routine receives all the characters (after 11 interruptions of course) and the checksum is correct, then data is received and ready to be processed.
Having said all that, you'd think that I could pull a whole data exchange off within a 10mS block, but my micros (or maybe the radio modules) are choking to the point where I need a 32mS block for each client.
I estimate 10mS because I investigated various areas of my code, and for a packet to come in at 56K, 11 bytes will need about 2mS time for the data to come in. The overhead for each incoming data byte is under 300uS, so 2mS for receiving data + 2mS for sending out data, + 3.3mS for all in-between serial processing + 3mS (worst case) for other necessary processing = about 10mS.
So now I'm baffled, and I feel I have two options of which one I'm taking...
1. Upgrade the microcontroller (I'm gonna try AT89S8253)
2. Change radio module settings (but to what?)
I'm baffled because for each test, I played with the value of x (global client reply to server timeout value). When the timeout is ridiculously low, the modules show the server sends data at a high speed and the client receives it(?) but when the client tries to send, the server received nothing. If I make the value of x a high timeout (like 32mS) then I see that both units are sending and receiving equally but 32mS is too long.
what can I do?
So I suggest looking at the client transmit data stream to the modem and its receive data stream back from one of the servers. Do this with a digital oscilloscope so you can check the timing of the 'out' and 'in' data streams to and from the modem. Once you know this you can think about how long it will take the software to do a complete transaction of transmitting the polling packet and receiving back and decoding the reply.
If you don't have an oscilloscope then all you can do it instrument the transmit and receive functions in your code to time stamp the various points in the program. For this you will need a free running timer. You could start by recording a time stamp of when the first and last bytes are sent to the uart, when the receive interrupt routine gets each returned byte and finally when the received packet is decoded and checked that it is OK.
Initially loop back the transmit and receive connections of your 'client's UART so you are only using the 'client' part of the system. This way you should see the transmitted bytes received back in as they are transmitted. This will help to give you confidence that the software is doing what you expect it to do.
By the way, from what you say your chosen processor should be more than capable of doing this task.
All the best.
Yes on the client/server nomenclature!
You've accounted for the 2 + 2 ms to send + receive 11 bytes at 56 kbps, and have added 6 ms for processing time.
That's would be 6 ms processing time total, 3 ms at each end. If your processing is not completely and immediately event driven, for example if there is a scheduled task that runs periodically to look for an available frame (I hope you don't process the frame in the interrupt), this could be an additional source of overhead and introduces a min/max range of receive response latency.
It sounds like all clients receive every frame, but only respond when they are addressed. I'm not sure how you handle flushing data when it is addressed to another client, but if it doesn't some how happen immediately (eg. waiting for a timeout to expire) this could add delay before a client can successfully receive a subsequent frame.
As JohnHPote mentioned, there is going to be some time required to turn off the server transmitter, turn on the client transmitter and synchronize the transmitter and receiver. I don't see this accounted for in your analysis. Transmit turn-off can happen in overlap with receive processing, but turn-on and synchronization cannot. There are various methods of achieving transmit/receive bit timing lock over a radio channel. I've seen some touting "instantaneous" lock, perhaps that is what you are using and your turn-on and sync time is so low you that can ignore it, but perhaps it is not in which case you'll see it twice in the course of send + receive. Your radio module documentation should have these details.
Sadly the HMTRP radio module documentation doesn't offer much detail.
Yes its a nice idea to do a loopback but in a microcontroller world, I'll have to write another routine for that. Maybe I should invest in a digital oscilloscope...
One thing I did attempt which sadly made no difference is attempt to reduce stray capacitance by connecting a 10K resistor from VCC to the TX pin of the module.
I'm also going to try disabling SMOD because I think in microcontroller docs that SMOD=0 means sample a bit 32x a second instead of 16x a second and the more an incoming bit is sampled, the more accurate it is? I'm not entirely sure.
Also, I'm wondering if my choice of logic gate is correct.. Currently I use a 74HCT04 inverter IC with VCC connected to 3.3V and I connect two of them in series between the correct GPIO pin of the microcontroller and the correct pin of the radio module. I do this twice. One for the transmit and one for the receive. The reason for this is because the micro operates on 5V and the radio module cannot operate past 3.9V.
Do I take it your radio module is part of the PCB that also holds the microcontroller? If so then a loop back may be difficult but from your description may be essential for you to try and understand what is going on. But you need to do this in hardware and not pure s/w in the micrcontroller. You need to keep to the 56 kbps bit rate with corresponding byte rate.
Also from your latest post it is evident you need an introduction to basic electronics. At 56 k serial rate a 10 k pull up resistor is not going to have any effect and in any case will only affect the UART's output waveform, not its bit rate. Also the o/p pin of the microcontroller should be set (if it can be) to a totempole output that drives the ouput signal both high and low, in which case the resistor is pointless.
Again the SMOD control bit will not (or should not) affect the 56 k bit rate. All it does is change the sampling rate of the incoming bit stream from the modem. (On your micrcontroller changing the SMOD bit may require a change in thebaud rate generator settings to keep the 56 k rate. But the key point is that you keep the 56 k rate otherwise communications to the modem will fail.
HCT chips are not designed to work at 3.3 V supply voltage but at normal room temperature usually work fine. However, if you drive the HCT chip directly from the micro you will be slightly overdriving the input to the gate. This forward biases the HCT input pin's protection diode causing extra current to be drawn from the micro. I doubt this extra current will be enough to upset the gate or the micro but a potential divider between the micro and gate would be ideal. Also for what you are doing a 74HC04 would be better as these are usually specified to work down to about 2 V . Alternatively 74HC4049 and 4050 buffers are designed with inputs that can be over driven so high input voltages can be used without any problems.
Ah so that's why you tried the 10 k pull up. Stray capacitance is not your problem at these bit rates, voltage levels are. But again normally at room temperature a 3.3 V ouput from the the modem will be read as a logic '1' by the micro. BUT it is not a proper 5V CMOS logic level and will result in extra current drawn by the micro's input pin (look up shoot-through).
So you have this buffer chip between the micro and modem? This is an ideal place to do a h/w loopback. If this is a prototype breadboard type system and the HCT chip is in a socket then just pull it out and link the two relevant pins together with a piece of wire. If you have SMD construction then cut tracks and solder on test wires. (You only need to do this for the modem to micro connection) And yes get an oscilloscope if you can.
Hope the above helps.
Do I take it your radio module is part of the PCB that also holds the microcontroller?
Almost. I made a special radio module adapter that brings out the pins to a female header which I can plug into my board
At 56 k serial rate a 10 k pull up resistor is not going to have any effect and in any case will only affect the UART's output waveform, not its bit rate.
But the waveform is important. Without the resistor, I could end up with garbled data. Maybe one is already present in the radio module itself. My goal is to eliminate noise.
Also the o/p pin of the microcontroller should be set (if it can be) to a totempole output...
The micro I have has no option for totem-pole. Just the basic FET mode
Again the SMOD control bit will not (or should not) affect the 56 k bit rate. All it does is change the sampling rate of the incoming bit stream from the modem.
Don't more samples increase chances of accuracy of data? This is something I could end up trying.
(On your micrcontroller changing the SMOD bit may require a change in the baud rate generator settings to keep the 56 k rate. But the key point is that you keep the 56 k rate otherwise communications to the modem will fail.
I always used the same fixed baud rate across all devices in the network and I do not use the internal baud rate generator.
HCT chips are not designed to work at 3.3 V supply voltage but at normal room temperature usually work fine. However, if you drive the HCT chip directly from the micro you will be slightly overdriving the input to the gate...
Ok, Now Just maybe this is the beginning to the root of the problem. Since the micro's output is either high-impedance or ground, I guess that's where you get the "slightly overdriving" from.
This forward biases the HCT input pin's protection diode causing extra current to be drawn from the micro.
I thought HCT doesn't have the protection diodes and I thought the HC ones do which is why I avoided them for the buffer
I doubt this extra current will be enough to upset the gate or the micro but a potential divider between the micro and gate would be ideal. Also for what you are doing a 74HC04 would be better as these are usually specified to work down to about 2 V . Alternatively 74HC4049 and 4050 buffers are designed with inputs that can be over driven so high input voltages can be used without any problems.
Ok, I'll have to find something that I can swap out with pin settings the same as 74HCT04. But I thought the thing with 74HC04 is that if the inputs are given 5V, then the VCC is given 5V even if VCC is under 5V? I'm referring to "Phantom power". At least I experienced that when I hooked up a circuit I made in the past to the parallel port and it used 74HC IC's.
Just out of curiosity, would the 74ACT04 work even better? There's mention that it runs faster than the 74HCT04 but I'm not sure.
I ran more tests. This time instead of using radio modules, I used a direct link (still with the 74HCT04 buffers in circuit). The link consisted of ardruino (can't spell it right) compatible female-female jumper cables which I plugged into each unit. The results are the same. So now I ruled out the radio modules. Do I need to add delays between sending bytes from the micro?
You said earlier if you wait 32 ms then the packets get through in your micro's software. This indicates something somewhere is running slower than you expect. So why are you concentrating on the hardware link between micro & modem? You now mention using an ACT buffer which is a much faster CMOS family compared to the earlier HC/HCT family. At 56 k the HCT is more than fast enough.
At this stage in your development don't worry about noise/interference on the micro to modem link. Get the basic functioning of the system first.
So you can unplug the modem? In which case make up a loopback cable to plug in to replace the modem. Just connect the tx pin to the modem to the rx pin from the modem.
Now get a simplified version of your software that just sends out a byte and reads any returned bytes back in. Do you get back what you send out? An oscilloscope would be very useful to check the waveform.
How do you intend to get out the data gathered from the 25 remote units? The central data logger gathers this data and then what? With systems like this I always try and add a standard serial (RS232) connection to the logger that I can connect to from a PC. Nowadays I would get a USB to serial converter that has 3.3 or 5 V non-inverted TTL/CMOS input/outputs and connect it directly to a UART in the micro (maybe through a buffer for some protection), write a simple bit of software to read bytes from the UART and send them back out (ie an echo program). I now know I can talk to the micro from the PC. (On the PC run a terminal emulator program such as PuTTY) Next I would expand the 'echo' program into a simple command interpreter so debugging commands can be sent to the micro and the replies seen on the PC screen. This all takes time but at least you now have a window into the micro so you can start to see what is going on.
Ok, I should just leave my serial hardware as-is.
One thing I have at my client end is another micro attached (AT89C4051). Basically its a high-speed sensor that detects light and when it does, it will have a code ready to send to the main micro (with the serial connection) when serial data arrives. I'm basically using the serial data also as the synchronizer in the system.
I attempted programming an AT89LP4052 in parallel mode without success. I'm going to look at the second micro to see if I can improve its code speed because maybe its slowness is causing me to not process characters.
You need a scope
This is a really good 4-channel scope under $400
You did not hear it from me, but there are several sources for a little program that will convert the 50MHz to 100MHz by changing a byte in the EEPROM