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.
7 years, 5 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
7 years, 5 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