Encoders and buttons and lights...

I’ve been trying to use the arduino as a useful general purpose I/O device for exhibits and kept running into problems when I broadcasted serial messages on changed values. The following is an attempt to continuously read and write the inputs and outputs and only send serial on demand. So far, I’ve tested inputs and encoders; a 1024-count encoder can be read at about 30 rpm (which is 30,000 counts, so that’s probably overkill). Past that speed, the encoder starts slipping and losing counts, because it’s happening in main() vs. using an interrupt. I avoided using interrupts because I wanted 2 encoders (X and Y) and only had 1 interrupt available, since the other one is being used for serial communication with the CPU.
Arduino also remembers if any of the buttons were pressed since the last poll. If they were, it reports them as a “pressed”. I’m polling 30 times a second; if someone were to press and release a button faster than that (or it was a fast, momentary event instead of a button), Arduino would most likely catch it and remember it. For these situations, you would probably want to monitor Pressed instead of In.
The analogs float and send annoying messages on every poll; I’ve got mine tied to ground unless I’m using them. That forces them to 0, so they don’t broadcast changing values. That becomes important when you interpret the values on the cpu side; I’m looking for changes and when I find them, interpreting the change.

Code doesn’t fit the 5000 character limit; I’ll post it on my website:
http://www.rshields.com/arduino/

Maybe my client will fit; this is cli PHP.

#!/usr/bin/php -q

<?php

$oldMessage = "";
$message = "";
$value = array();
$oldValue = array();

function makeconnection() {
      $Enc1Pos = 1000;
      $Enc2Pos = 1000;
      print ".";
      $fp = @fopen("/dev/cu.usbserial-A4001sSV", "w+");
      exec("stty -f /dev/cu.usbserial-A4001sSV 115200");
      stream_set_blocking($fp, false); 
      print "-";
      if (!$fp) {
            echo "Could not connect to device \r\n";
            return(0);
      } else {
            print "connection to device established.\r\n";
            $send = "?";
            while ($fp) {
                  fwrite($fp, $send);
                  $message = fgets($fp, 1024);
                  if ($message == "") {
                        print "empty message\r\n";
                  } else {
                        if ($message != $oldMessage) {
                              for ($i = 0; $i < strlen($message); $i++) {
                                    $value[$i] = ord($message[$i]);
                              }
                              $printEOL = false;
                              for ($i = 0; $i < count($value); $i++) {
                                    if ($value[$i] != $oldValue[$i]) {
                                          switch ($i) {
                                                case 0: print "Ins:".$value[0];
                                                      $printEOL = true;
                                                      break;
                                                case 1: print "InP:".$value[1];
                                                      $printEOL = true;
                                                      break;
                                                case 2: if ($value[2]-128) {
                                                      $Enc1Pos += ($value[2]-128);
                                                      if ($Enc1Pos < 0) $Enc1Pos += 2000;
                                                      if ($Enc1Pos > 2000) $Enc1Pos -= 2000;
                                                      print "En1:".$Enc1Pos;
                                                      $printEOL = true;
                                                      }
                                                      break;
                                                case 3: if ($value[3]-128) {
                                                      $Enc2Pos += ($value[3]-128);
                                                      if ($Enc2Pos < 0) $Enc2Pos += 2000;
                                                      if ($Enc2Pos > 2000) $Enc2Pos -= 2000;
                                                      print "En2:".$Enc2Pos;
                                                      $printEOL = true;
                                                      }
                                                      break;
                                                case 4: print "A1:".($value[4]);
                                                      $printEOL = true;
                                                      break;
                                                case 5: print "A2:".($value[5]);
                                                      $printEOL = true;
                                                      break;
                                          }
                                          $oldValue[$i] = $value[$i];
                                    }
                              }
                              if ($printEOL) print "\r\n";
                        }
                  }
                  $oldMessage = $message;
                  usleep (33333);
            }
      }
}

while (true) {
      makeconnection();
      sleep (10);
}
?>

Yeah, so the client would need the device identified properly; on my mac, it’s “/dev/cu.usbserial-A4001sSV”. You can find your arduino on a mac by opening terminal and typing “ls /dev/usbserial”.

With the arduino programmed, you can request readings and read changes by running the client shown above. Just copy and paste the code into a text editor, save as “ardClient.sh”, and save it somewhere (~/Documents/arduino/showcontroller, maybe?). Open terminal again, go to the directory (cd /Documents/Arduino/showcontroller), change permissions to allow executing (sudo chmod 0774 ardClient.sh), and run it (./ardClient.sh). Because of the new software reset, it’ll give about 1 second of empty readings (program restarting on connection); after that, you’re set. I’ll be revising this code to talk and listen to a TCP socket; makes it easier to pass to various programs.

hi

you should try putting this in the Playground, which is a permanent resource.

D