Important changes to forums and questions
All forums and questions are now archived. To start a new conversation or read the latest updates go to forums.mbed.com.
6 years, 7 months ago.
run TCPServer and PressButton event at the same time
I have problem in my code. Please help! I want to run TCPServer for send data to web browser and I want to action when press the button .
[Running mode] I pressed the button but no action until I call data from TCPServer with web browser.
I use MBED-OS 5.x and STM32 f746zg
This is my code
#include "mbed.h" #include "EthernetInterface.h" EthernetInterface net; TCPServer srv; TCPSocket client_sock; SocketAddress client_addr; char *wbuffer = new char[256]; InterruptIn button1(USER_BUTTON); volatile bool button1_pressed = false; // Used in the main loop volatile bool button1_enabled = true; // Used for debouncing Timeout button1_timeout; // Used for debouncing // Enables button when bouncing is over void button1_enabled_cb(void) { button1_enabled = true; } // ISR handling button pressed event void button1_onpressed_cb(void) { if (button1_enabled) { // Disabled while the button is bouncing button1_enabled = false; button1_pressed = true; // To be read by the main loop button1_timeout.attach(callback(button1_enabled_cb), 0.3); } // Debounce time 300 ms } void doButton() { printf("BUTTON PRESSED\r\n"); } int main() { net.connect(); const char *ip = net.get_ip_address(); printf("IP address: %s\r\n", ip ? ip : "No IP\r\n"); printf("NetMask: %s\r\n", net.get_netmask()); printf("Gateway Address: %s\r\n", net.get_gateway()); printf("Mac Address: %s\r\n", net.get_mac_address()); printf("Ethernet Setup OK\r\n"); srv.open(&net); srv.bind(net.get_ip_address(), 80); srv.listen(1); printf("TCP Server open success\r\n"); button1.fall(callback(button1_onpressed_cb)); // Attach ISR to handle button press event while(1) { printf("TCP Server Listen\r\n"); srv.accept(&client_sock, &client_addr); printf("Accepted %s:%d\n", client_addr.get_ip_address(), client_addr.get_port()); strcpy(wbuffer, "HELLO WORLD"); client_sock.send(wbuffer, strlen(wbuffer)); client_sock.recv(wbuffer, 10000); client_sock.close(); delete[] wbuffer; if (button1_pressed) { // Set when button is pressed button1_pressed = false; doButton(); } }//end while }
Sorry for my english language
Thank you so much.
1 Answer
6 years, 7 months ago.
Hello Teerawat,
You can make the push button operational by handling it in a concurrent thread as below:
#include "mbed.h" #include "EthernetInterface.h" //#define USER_BUTTON p21 EthernetInterface net; TCPServer srv; TCPSocket client_sock; SocketAddress client_addr; char* wbuffer = new char[256]; InterruptIn button1(USER_BUTTON); volatile bool button1_pressed = false; // Used in the main loop volatile bool button1_enabled = true; // Used for debouncing Timeout button1_timeout; // Used for debouncing Thread button1Thread; // Enables button when bouncing is over void button1_enabled_cb(void) { button1_enabled = true; } // ISR handling button pressed event void button1_onpressed_cb(void) { if (button1_enabled) { // Disabled while the button is bouncing button1_enabled = false; button1_pressed = true; // To be read by the button1Loop button1_timeout.attach(callback(button1_enabled_cb), 0.3); // Debounce time 300 ms } } void doButton() { printf("BUTTON PRESSED\r\n"); } void button1Loop() { while (1) { if (button1_pressed) { button1_pressed = false; doButton(); } } } int main() { net.connect(); const char* ip = net.get_ip_address(); printf("IP address: %s\r\n", ip ? ip : "No IP\r\n"); printf("NetMask: %s\r\n", net.get_netmask()); printf("Gateway Address: %s\r\n", net.get_gateway()); printf("Mac Address: %s\r\n", net.get_mac_address()); printf("Ethernet Setup OK\r\n"); srv.open(&net); srv.bind(net.get_ip_address(), 80); srv.listen(1); printf("TCP Server open success\r\n"); button1.mode(PullUp); button1.fall(callback(button1_onpressed_cb)); // Attach ISR to handle button press event button1Thread.start(button1Loop); while (1) { printf("TCP Server Listen\r\n"); srv.accept(&client_sock, &client_addr); printf("Accepted %s:%d\n", client_addr.get_ip_address(), client_addr.get_port()); strcpy(wbuffer, "HELLO WORLD"); client_sock.send(wbuffer, strlen(wbuffer)); client_sock.recv(wbuffer, 10000); client_sock.close(); delete[] wbuffer; } //end while }
But this will not make the program act as you wished. Because it's always the client (in this case a web browser) who initiates a data exchange, I think that's even impossible to achieve. The server can just wait (listen) for that to happen (in this case by executing the srv.accept(&client_sock, &client_addr);
statement in context of the main thread).
To control your NUCLEO-F746ZG board (while it is hosting a TCP server) from a TCP client (web browser) you can try the https://os.mbed.com/users/hudakz/code/WebSwitch_mbed-os/ example program.
posted by 08 May 2018Thank you for your answer. Your code is successful. And learning more the THREAD subject. https://os.mbed.com/docs/v5.8/reference/thread.html
posted by 10 May 2018