{"id":85,"date":"2026-02-27T17:33:27","date_gmt":"2026-02-27T23:33:27","guid":{"rendered":"http:\/\/aa6kj.hopto.org\/wp\/?p=85"},"modified":"2026-02-28T09:06:35","modified_gmt":"2026-02-28T15:06:35","slug":"bandmaster-v-info-widget","status":"publish","type":"post","link":"http:\/\/aa6kj.hopto.org\/wp\/?p=85","title":{"rendered":"Bandmaster V info widget"},"content":{"rendered":"\n<p>Wrote the following info widget for Bandmaster V (Linux):<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">#include &lt;stdio.h&gt;<br \/>#include &lt;string.h&gt;<br \/>#include &lt;stdlib.h&gt;<br \/>#include &lt;fcntl.h&gt;<br \/>#include &lt;unistd.h&gt;<br \/>#include &lt;termios.h&gt;<br \/>#include &lt;qt6\/libqt6c.h&gt;<br \/><br \/>\/\/ Define the antenna names<br \/>#define ANTENNA1 \"6m beam\"<br \/>#define ANTENNA2 \"WARC beam\"<br \/>#define ANTENNA3 \"Stack\"<br \/>#define ANTENNA4 \"40m beam\"<br \/>#define ANTENNA5 \"No antenna\"<br \/>#define ANTENNA6 \"No antenna\"<br \/>#define ANTENNA7 \"No antenna\"<br \/>#define ANTENNA8 \"No antenna\"<br \/>#define ANTENNA9 \"No antenna\"<br \/>#define ANTENNA10 \"No antenna\"<br \/>#define ANTENNA11 \"No antenna\"<br \/>#define ANTENNA12 \"No antenna\"<br \/><br \/>#define DEVICE \"\/dev\/serial\/by-id\/usb-FTDI_FT232R_USB_UART_B003ISA1-if00-port0\"<br \/><br \/>int fd;<br \/>void *widget, *label;<br \/><br \/>int read_untilcr(int fd, char *buf, int maxlen) {<br \/><br \/>  int pos = 0, bytes_rd;<br \/><br \/>  while(1) {<br \/>    if((bytes_rd = read(fd, buf + pos, 1)) &lt; 0) return -1;<br \/>    if(bytes_rd == 0) {<br \/>      sleep(1); \/\/ could be less than 1sec<br \/>      continue;<br \/>    }<br \/>    if(!pos &amp;&amp; (*buf == '\\r' || *buf == '\\n')) continue;<br \/>    if(pos == maxlen) return -1;<br \/>    if(buf[pos] == '\\r') break;<br \/>    pos++;<br \/>  }<br \/>  buf[pos] = '\\0';<br \/>  return pos;<br \/>}<br \/><br \/>void set_tty() {<br \/><br \/>  struct termios param;<br \/><br \/>  if(tcgetattr(fd, &amp;param) &lt; 0) {<br \/>    fprintf(stderr, \"Status get failed.\\n\");<br \/>    exit(1);<br \/>  }<br \/><br \/>  param.c_cflag &amp;= ~PARENB;<br \/>  param.c_cflag &amp;= ~CSTOPB;<br \/>  param.c_cflag |= CS8;<br \/>  param.c_cflag &amp;= ~CRTSCTS;<br \/>  param.c_cflag |= CREAD | CLOCAL;<br \/>  param.c_lflag &amp;= ~ICANON;<br \/>  param.c_lflag &amp;= ~ECHO;<br \/>  param.c_lflag &amp;= ~ECHOE;<br \/>  param.c_lflag &amp;= ~ECHONL;<br \/>  param.c_lflag &amp;= ~ISIG;<br \/>  param.c_iflag &amp;= ~(IXON | IXOFF | IXANY);<br \/>  param.c_iflag &amp;= ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL);  <br \/>  param.c_oflag &amp;= ~OPOST;<br \/>  param.c_oflag &amp;= ~ONLCR;<br \/>  cfsetispeed(&amp;param, B57600);<br \/>  cfsetospeed(&amp;param, B57600);<br \/><br \/>  if(tcsetattr(fd, TCSANOW, &amp;param) &lt; 0) {<br \/>    fprintf(stderr, \"Status set failed.\\n\");<br \/>    exit(1);<br \/>  }<br \/>}<br \/><br \/>char *txt_noant = \"&lt;b&gt;&lt;font color='red'&gt;No antenna.&lt;\/font&gt;&lt;\/b&gt;\",<br \/>     *txt_40m = \"&lt;b&gt;&lt;font color='blue'&gt;40m beam.&lt;\/font&gt;&lt;\/b&gt;\",<br \/>     *txt_warc = \"&lt;b&gt;&lt;font color='blue'&gt;WARC beam.&lt;\/font&gt;&lt;\/b&gt;\",<br \/>     *txt_stack = \"&lt;b&gt;&lt;font color='blue'&gt;Stack.&lt;\/font&gt;&lt;\/b&gt;\",<br \/>     *txt_6m = \"&lt;b&gt;&lt;font color='blue'&gt;6m beam.&lt;\/font&gt;&lt;\/b&gt;\";<br \/><br \/>void update_band_info(void *asd) {<br \/><br \/>  int len, antenna, relay;<br \/>  char buf[512];<br \/>  <br \/>  if((len = read_untilcr(fd, buf, sizeof(buf))) &lt; 0) {<br \/>     fprintf(stderr, \"Read error.\\n\");<br \/>     exit(1);<br \/>  }<br \/>  if(sscanf(buf, \"[TC4RFA29H00M0%1d01EEEEEEEEEEEE%4d]\", &amp;antenna, &amp;relay) != 2) return; \/\/ Some other mesg<br \/><br \/>  switch(antenna) {<br \/>    case 1:<br \/>      sprintf(buf, \"&lt;b&gt;&lt;font color='blue'&gt;%s (%d)&lt;\/font&gt;&lt;\/b&gt;\", ANTENNA1, relay);<br \/>      q_label_set_text(label, buf);<br \/>      break;<br \/>    case 2:<br \/>      sprintf(buf, \"&lt;b&gt;&lt;font color='blue'&gt;%s (%d)&lt;\/font&gt;&lt;\/b&gt;\", ANTENNA2, relay);<br \/>      q_label_set_text(label, buf);<br \/>      break;<br \/>    case 3:<br \/>      sprintf(buf, \"&lt;b&gt;&lt;font color='blue'&gt;%s (%d)&lt;\/font&gt;&lt;\/b&gt;\", ANTENNA3, relay);<br \/>      q_label_set_text(label, buf);<br \/>      break;<br \/>    case 4:<br \/>      sprintf(buf, \"&lt;b&gt;&lt;font color='blue'&gt;%s (%d)&lt;\/font&gt;&lt;\/b&gt;\", ANTENNA4, relay);<br \/>      q_label_set_text(label, buf);<br \/>      break;<br \/>    case 5:<br \/>      sprintf(buf, \"&lt;b&gt;&lt;font color='blue'&gt;%s (%d)&lt;\/font&gt;&lt;\/b&gt;\", ANTENNA5, relay);<br \/>      q_label_set_text(label, buf);<br \/>      break;<br \/>    case 6:<br \/>      sprintf(buf, \"&lt;b&gt;&lt;font color='blue'&gt;%s (%d)&lt;\/font&gt;&lt;\/b&gt;\", ANTENNA6, relay);<br \/>      q_label_set_text(label, buf);<br \/>      break;<br \/>    case 7:<br \/>      sprintf(buf, \"&lt;b&gt;&lt;font color='blue'&gt;%s (%d)&lt;\/font&gt;&lt;\/b&gt;\", ANTENNA7, relay);<br \/>      q_label_set_text(label, buf);<br \/>      break;<br \/>    case 8:<br \/>      sprintf(buf, \"&lt;b&gt;&lt;font color='blue'&gt;%s (%d)&lt;\/font&gt;&lt;\/b&gt;\", ANTENNA8, relay);<br \/>      q_label_set_text(label, buf);<br \/>      break;<br \/>    case 9:<br \/>      sprintf(buf, \"&lt;b&gt;&lt;font color='blue'&gt;%s (%d)&lt;\/font&gt;&lt;\/b&gt;\", ANTENNA9, relay);<br \/>      q_label_set_text(label, buf);<br \/>      break;<br \/>    case 10:<br \/>      sprintf(buf, \"&lt;b&gt;&lt;font color='blue'&gt;%s (%d)&lt;\/font&gt;&lt;\/b&gt;\", ANTENNA10, relay);<br \/>      q_label_set_text(label, buf);<br \/>      break;<br \/>    case 11:<br \/>      sprintf(buf, \"&lt;b&gt;&lt;font color='blue'&gt;%s (%d)&lt;\/font&gt;&lt;\/b&gt;\", ANTENNA11, relay);<br \/>      q_label_set_text(label, buf);<br \/>      break;<br \/>    case 12:<br \/>      sprintf(buf, \"&lt;b&gt;&lt;font color='blue'&gt;%s (%d)&lt;\/font&gt;&lt;\/b&gt;\", ANTENNA12, relay);<br \/>      q_label_set_text(label, buf);<br \/>      break;<br \/>    default:<br \/>      q_label_set_text(label, \"&lt;b&gt;&lt;font color='red'&gt;Unknown antennan.&lt;\/font&gt;&lt;\/b&gt;\");<br \/>  }<br \/>}<br \/><br \/>int main(int argc, char *argv[]) {<br \/><br \/>  QApplication *app;<br \/>  QTimer *timer;  <br \/><br \/>  if((fd = open(DEVICE, O_RDONLY)) &lt; 0) {<br \/>    fprintf(stderr, \"Can't open device.\\n\");<br \/>    exit(1);<br \/>  }<br \/>  set_tty();<br \/><br \/>  app = q_application_new(&amp;argc, argv);<br \/>  widget = q_widget_new2();<br \/>  timer = q_timer_new2(widget);<br \/>  q_widget_set_window_title(widget, \"Antenna selection\");<br \/>  q_widget_resize(widget, 150, 30);<br \/>  label = q_label_new5(\"------------------------------\", widget);<br \/>  q_label_set_alignment(label, QT_ALIGNMENTFLAG_ALIGNCENTER);<br \/>  q_label_set_text_format(label, QT_TEXTFORMAT_RICHTEXT);<br \/>  q_timer_start(timer, 100);<br \/>  q_timer_on_timeout(timer, update_band_info);<br \/>  q_widget_show(widget);<br \/>  (void) q_application_exec();<br \/>  q_widget_delete(widget);<br \/>  q_application_delete(app);<br \/><br \/>  close(fd);<br \/>}<br \/><\/pre>\n\n\n\n<p>Uses libqt6c (QT bindings for C).<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Wrote the following info widget for Bandmaster V (Linux): #include &lt;stdio.h&gt;#include &lt;string.h&gt;#include &lt;stdlib.h&gt;#include &lt;fcntl.h&gt;#include &lt;unistd.h&gt;#include &lt;termios.h&gt;#include &lt;qt6\/libqt6c.h&gt;\/\/ Define the antenna names#define ANTENNA1 &#8220;6m beam&#8221;#define ANTENNA2 &#8220;WARC beam&#8221;#define ANTENNA3 &#8220;Stack&#8221;#define ANTENNA4 &#8220;40m beam&#8221;#define ANTENNA5 &#8220;No antenna&#8221;#define ANTENNA6 &#8220;No antenna&#8221;#define ANTENNA7 &#8220;No antenna&#8221;#define ANTENNA8 &#8220;No antenna&#8221;#define ANTENNA9 &#8220;No antenna&#8221;#define ANTENNA10 &#8220;No antenna&#8221;#define ANTENNA11 &#8220;No antenna&#8221;#define ANTENNA12 &#8220;No [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[5],"tags":[],"class_list":["post-85","post","type-post","status-publish","format-standard","hentry","category-ham_radio"],"_links":{"self":[{"href":"http:\/\/aa6kj.hopto.org\/wp\/index.php?rest_route=\/wp\/v2\/posts\/85","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/aa6kj.hopto.org\/wp\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/aa6kj.hopto.org\/wp\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/aa6kj.hopto.org\/wp\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/aa6kj.hopto.org\/wp\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=85"}],"version-history":[{"count":3,"href":"http:\/\/aa6kj.hopto.org\/wp\/index.php?rest_route=\/wp\/v2\/posts\/85\/revisions"}],"predecessor-version":[{"id":91,"href":"http:\/\/aa6kj.hopto.org\/wp\/index.php?rest_route=\/wp\/v2\/posts\/85\/revisions\/91"}],"wp:attachment":[{"href":"http:\/\/aa6kj.hopto.org\/wp\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=85"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/aa6kj.hopto.org\/wp\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=85"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/aa6kj.hopto.org\/wp\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=85"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}