I have some hard time trying to find a method to restart my state machine. In other words some part of what I ve got:
I have a module that when is powered up it stays for a debounce time of 0.5 s and then it goes in a state machine: first it send a string#anotherstring# then he start a timer of some period and when timer elapsed, it converts an analog signal/read a data (SPI,I2C) and sends that data followed by another #. The state machine goes back and start again the timer and send again the data ...
On another chip. I receive info from that module. So here is a state machine that complete the first string, second string, and then cumulates values in a buffer, again and again.
In some moment some external device ask for data, moment when the chip make some computation and sends it.
SO far so good. Every single part of this is working exept the part when the module is disconnected. Ok you may say no problem no data is send. Yes this is true, but what happens if the module is connected back. Until now to test my work I have reseted the chip disconect and connect the module. By doing this the chip is on the first state and the module goes from first state, everything is ok.
My qestion is how to determine when the device is disconected from the chip to restart the chip stat machine and to wait for the string#anotherstring# combination(first state).
Another question is how to determine if the communication is broken and not the power down. When putting back the comunication the data should be again send,preferably both modules to go from init state.
What I have in mind is to send some ack to the module from the chip. But I do not know exactly how. Basically I want this: when the module is disconected its state machine obviously start over and the chip state I want again to goes back to initial state.
if the comunication of the module is unplugged some how both statemachines to start over.
I do not know if I am clear with this. but please if there are questions ask. I will come with edits if I found something.
OTHER INFO: The module and the chip are some microcontrolers, the comunicaiton is UART.
Let me sketch a basic scheme you can use on the receiving side:
On your receiving side, you'll want to time-out if no valid/complete message is received within a reasonable time frame. This way, you'll detect when the module goes offline for whatever reason at any point in time.
The state machine that receives and processes the messages will also be reset in this case. This means you'll have a timer which, for example, is started when data is received and stopped when a message was correctly and fully received. If the timer times out, any message currently being received is declared invalid and discarded, and the receiver goes back to the start, looking for the next message.
Then, you'd have to implement in the receiver the code to detect when a message starts and/or ends. So if the module always starts by sending string#anotherstring# then the receiver will wait until it sees string# for example; anything else received is ignored by the receiver. Only after the expected prefix was detected the rest of the message receiving is done.
During the whole process, the receiver's messsage timeout timer is active and if any part of the message is not received in time the receiver assumes transmission problems and goes back to waiting for the start of the next message.
Related
hello i'm new with using RTOS with my board is NUCLEO-G474RE,with my question maybe not clear
well using C# making a GUI to Connect with my board i and sending a value while using RTOS method,
RTOS i have two task there ,Task1 is receive and sendback value that user type also led toggle,
Task2 also is UART receive then flash into my memory,with both task i have send back msg to tell
the task done,the problem is while i send value i cant accuracy flash my value into my board
i have type serval times,i forget to say i only open one uart so i dont think need semaphore
also the GUI i saw the value sendback is right but when i look at the stm32 memory side the value
is ASCII value when i send string is right but sending interger is wrong
fix my question with some pircture sorry i'm new here the picture only show the links
My goal is flash data with uart below is what happen
1.Here is two task ,Task 1 is write the uart receive data into my memory
enter image description here
here is my C# gui when i sending data i send back value
enter image description here
And while i looking at the memory but the data which write in is wrong
enter image description here
i'm trying to pass data between two bluetooth devices, when both connected to two different computers.
After having hci device in each of the computers, i'm using rfcomm to pass information between the two.
I'm trying to pass 10MB of random data just to check the ability of the system.
On the beginning everything seems to work fine. After a few seconds, it looks like there is a delay between the sender and the receiver, when sometimes data stopps to arrive, and then a "massive" amount of data is suddenly arriving the receiver.
Exactly like some buffer is keeping all the data. As long i keep sending data
the delay is getting longer.
I'm trying to figure out where in the chain such buffer can be, or how to
solve this buffering.
Many Thanks :)
I'm using a WinForm app to communicate with a micro processor (Arduino Micro). The MCU's serial port requires a few seconds to become available after calling a 'serialPort1.Open();'. So I need to add some kind of delay of perhaps 2 or 3 seconds before attempting to read from the serial port. In addition, I am sending and receiving commands to the MCU during which time I also require a 100ms delay between serial writes and reads.
I've tried using Thread.Sleep (which of course locks up the form) and various timer methods with no luck. I'd be using this delay often so I'd like to have a method that looks something like this:
Anywhere in my form: invokeTimer(2000); // call a delay method with time in ms
private void invokeDelay(int time)
{
// delay here and do nothing for specified time in milliseconds
}
Simple examples:
serialPort1.Open(); // connect to MCU
invokeDelay(3000); // give MCU time to make serial stream available
// serial stream should now be available so ...
serialPort1.WriteLine("?"); // ask MCU to provide a response
invokeDelay(100); // 10-100ms depending on baud rate of MCU to respond
string response = serialPort1.ReadLine();
Alternatively, I'd be happy with any way of checking if there is serial data available and in this way avoid delays/timers all together. In the Arduino IDE there is a Serial.Available() function, but I don't see anything similar to this in Visual Studio. Otherwise I'd sit in a while loop until a serial stream became available.
Any advice would be most appreciated!
I implemented my own frame decoder to parse the bytes received through a UDP socket (using NioDatagramChannelFactory and ConnectionlessBootstrap) according to our protocol.
Just to follow what is happening in the server while receiving messages, I added trace logs in each callback method of the decoder.
It appears that for almost every message the server receives, we can see that the event "channelInterestChanged" is received twice in the method channelInterestChanged(). The value of the event is first 0 (OP_NONE) then 1 (OP_READ).
I read the documentation about this, but I am still not sure to understand why I receive such events. I first through it was because the receive buffer (or the selector queue) was full, but the server receives this event the same number of times it receives the "messageReceived" event (before the decode() method is called) and all the messages/frames are properly decoded as expected. When messages are missing, I do no see any event at all. In this case it is probably because the receive buffer of the datagram socket is full. But even if I increase this receive buffer, I continue to see these events and to miss messages.
So, I am wondering why for each message received, the server also receives two "channelInterestChanged", one with the OP_NONE value and one with the OP_READ value. Please, takes note also that in the channel pipeline, after my frame decoder, there is an ExecutionHandler and another business-specific handler (which sends a JMS message to an ActiveMQ instance).
Any idea or explanation for me?
Thank you.
When a DownStreamChannelStateEvent fired from a handler (e.g calling channel.setReadable(), channel.setWriteable()), the event will change the channel's nio selector key's interested option in the NioDatagramWorker, later, a UpstreamChannelStateEvent will be fired with changed option (i.e OP_READ or OP_NONE)
Your frame decoder handler receives UpstreamChannelStateEvents because, some other handlers in the pipeline are changing the channel's read interest options (the purpose of calling channel.setReadable/setWriteable is, throttling the read/write to avoid congestion, OutOfMemoryError in the application).
If you have any MemoryAwareThreadPoolExecutor in your pipeline (which monitors the size of the channel memory used), it may suspend or resume reading by calling channel.setReadable() any time if the channel receives messages too fast. You may have to configure the MATPE instance with optimum maxChannelMemorySize, maxTotalMemorySize or disable it by setting it to 0.
I don't have much experience with multithreading and I'm writing a c program which I believe is suited to running in two threads. The program will listen on the serial port for data, read and process new data when it's available, and publish the newest processed data to other (irrelevant) modules via a third party IPC api (it's confusingly named IPC) when requested.
In order to receive the request to publish data via IPC, the program must call IPC_listenwait(wait_time);. Then if a request to publish is received while "listenwaiting" a handler is invoked to publish the newest data.
One option is to do this in one thread like:
for(;;) {
read_serial(inputBuffer);
process_data(inputBuffer, processedData); //Process and store
IPC_listenwait(wait_time); //If a request to publish is received during this,
} //then a handler will be invoked and the newest piece of
//processedData will be published to other modules
publishRequestHandler() { //Invoked when a message is received during IPC_listenwait
IPC_publish(newest(processedData));
}
And this works, but for the application it is important that the program is very responsive to the request to publish new data, and that the data published is the newest available. These goals are not satisfied with the above because data may arrive after the process begins listenwaiting and before a request to publish message is received. Or the process may be reading/processing when a request to publish message is incoming, but won't be able to service it until the next IPC_listenwait call.
The only design I can think of is to have one thread to read, which will just do something like:
readThread() {
for(;;) { //pseudocode
select();
read(inputBuffer);
process(inputBuffer, processedData);
}
}
And have the main thread just listening for incoming messages:
mainThread() {
IPC_listenwait(forever);
}
publishRequestHandler() { //Invoked when a message is received during IPC_listenwait
IPC_publish(newest(processedData));
}
Is this the design you would use? If so, will I need to use a semaphore when accessing or writing processedData?
Will this give me good responsiveness?
Thanks
You're mostly on the right track.
The one thing you have to watch out for is concurrent access to the publishable data, because you don't want one thread clobbering it while another is trying to read it. To prevent that, use a pair of buffers and a mutex-protected pointer to whichever one is considered current. When process_data() has something ready, it should dump its results in the non-current buffer, lock the pointer mutex, repoint the pointer to the buffer containing the new data and then release the mutex. Similarly, the publisher should lock the pointer mutex while it reads the current data, which will force anything that might want to clobber it to wait. This is a bit more complex than having a single, mutex-protected buffer but will assure that you always have something current to publish while new data is being prepared.
If your processing step takes long enough that you could get multiple sets of data to read, you might split the read/process thread into two and let the reader make sure the processor only ever gets the latest and greatest so you don't end up processing stuff you won't ever publish.
Excellent first question, by the way. Have an upvote.