karl3ļ¼ writeme.com wrote:
> > > > so, sending robots into [air]space first lets them accumulate supplies 
> > > > for you there until you move there yourself.
> > > > > thinking for a final product you'd want 2-3 ways to connect to it 
> > > > > remotely (and get gps) in case it is high in the sky and one of them 
> > > > > breaks.
> > > > > so, things i could buy today to make a barebones prototype today:
> > > > - power pack (ideally a solar one) to power arduino and motors
> > > > - power adapter for motors?
> > > > - party balloons
> > > > - twine, construction materials
> > 
> > i'm spending time working on setting up an SOC. my current chosen approach 
> > is my cellphone wired to an arduino with termux running tmate on boot.
> > 
> > this approach roughly means patching avrdude to accept a filedescriptor on 
> > the command line so as to connect to the arduino via android. i'm working 
> > on that now.
> > 
> > tmate lets other people watch you; the login for that would be 
> > karl3wm/conn...@nyc1.tmate.io or something like that
> > 
> > the example code for patches to access usb devices on termux is at 
> > https://wiki.termux.com/wiki/Termux-usb#Details
> 
> well the avrdude code is based on libusb 0.1 whereas termux has 1.0 and it's 
> pretty slow to code over tmate.io on a phone; i think it makes more sense to 
> program the arduino elsewhere and use a serial interface to preprogrammed 
> code on the phone for now.
> 
> There's an example in c and python for serially interfacing with arduinos via 
> libusb at https://github.com/tytouf/libusb-cdc-example .
> 
> so that's the essentials :s :s :s
> 
> i think it makes sense to acquire a power supply next to make the motors run, 
> but i'll slow down now we'll see how it goes.
> 
> a day trip today for this might involve:
> - visit cricket and put a data plan on this phone, or get a phone anywhere
> - get a power pack (ideally solar) to run everything
> - get bare wiring for the power pack sufficient to power a motor
> - get general hobby wiring and wire cutters and optionally a soldering tool 
> - get party balloons
> - get some prototype construction materials, umm i guess: twine, duct tape, 
> hot glue, some rods
> - get hobby wiring and optional soldering tool
> 
> now, i have a toy fan and a servo gimbal. this might not be sufficient to 
> move something around in the air :s continued work seems presently 
> conditioned a functioning result :s :s

i've got my phone controlling a servo from the gimbal via ssh !

I think this is the sketch I put on the arduino: 
https://projecthub.arduino.cc/Kub_Luk/using-serial-monitor-to-control-servo-motor-c55083#section5

Of course arduino sketches are silly and I would prefer a makefile but there is 
less normativity and clear instructions to navigate confusion.

I put the red wire into 5VDC, the dark wire into GND, and the yellow wire into 
pin 9.

This is the first time I've ever controlled a motor with a phone as far as I 
know!

My changed cdc_example.c is viewable at https://bpa.st/654Q . The diff is at 
https://bpa.st/WRAA and pasted below:

diff --git a/cdc_example.c b/cdc_example.c
index fd21e23..e6a35e8 100644
--- a/cdc_example.c
+++ b/cdc_example.c
@@ -11,12 +11,6 @@
 
 #include <libusb-1.0/libusb.h>
 
-/* You may want to change the VENDOR_ID and PRODUCT_ID
- * depending on your device.
- */
-#define VENDOR_ID      0x2341   // Arduino LLC
-#define PRODUCT_ID     0x0034   // Arduino Leonardo
-
 #define ACM_CTRL_DTR   0x01
 #define ACM_CTRL_RTS   0x02
 
@@ -28,18 +22,21 @@ static struct libusb_device_handle *devh = NULL;
  * the values corresponding to your device.
  */
 static int ep_in_addr  = 0x83;
-static int ep_out_addr = 0x02;
+static int ep_out_addr = 0x04; // UNO
 
-void write_char(unsigned char c)
+int write_char(unsigned char c)
 {
     /* To send a char to the device simply initiate a bulk_transfer to the
      * Endpoint with address ep_out_addr.
      */
     int actual_length;
-    if (libusb_bulk_transfer(devh, ep_out_addr, &c, 1,
-                             &actual_length, 0) < 0) {
-        fprintf(stderr, "Error while sending char\n");
+    int rc;
+    if ((rc = libusb_bulk_transfer(devh, ep_out_addr, &c, 1,
+                             &actual_length, 0)) < 0) {
+        fprintf(stderr, "Error while sending char: %s\n", 
libusb_error_name(rc));
+        return -1;
     }
+    return 0;
 }
 
 int read_chars(unsigned char * data, int size)
@@ -51,10 +48,10 @@ int read_chars(unsigned char * data, int size)
     int rc = libusb_bulk_transfer(devh, ep_in_addr, data, size, &actual_length,
                                   1000);
     if (rc == LIBUSB_ERROR_TIMEOUT) {
-        printf("timeout (%d)\n", actual_length);
-        return -1;
+        //printf("timeout (%d)\n", actual_length);
+        return 0;
     } else if (rc < 0) {
-        fprintf(stderr, "Error while waiting for char\n");
+        fprintf(stderr, "Error while waiting for char: %s\n", 
libusb_error_name(rc));
         return -1;
     }
 
@@ -63,13 +60,11 @@ int read_chars(unsigned char * data, int size)
 
 int main(int argc, char **argv)
 {
+    libusb_context * ctx;
     int rc;
 
-    /* Initialize libusb
-     */
-    rc = libusb_init(NULL);
-    if (rc < 0) {
-        fprintf(stderr, "Error initializing libusb: %s\n", 
libusb_error_name(rc));
+    if (argc != 2) {
+        fprintf(stderr, "Usage: termux-usb -e %s /dev/bus/usb/00?/00?\n", 
argv[0]);
         exit(1);
     }
 
@@ -77,20 +72,29 @@ int main(int argc, char **argv)
      */
     libusb_set_debug(NULL, 3);
 
-    /* Look for a specific device and open it.
+    /* Initialize libusb
      */
-    devh = libusb_open_device_with_vid_pid(NULL, VENDOR_ID, PRODUCT_ID);
-    if (!devh) {
-        fprintf(stderr, "Error finding USB device\n");
-        goto out;
+    libusb_set_option(NULL, LIBUSB_OPTION_NO_DEVICE_DISCOVERY);
+    rc = libusb_init(&ctx);
+    if (rc < 0) {
+        fprintf(stderr, "Error initializing libusb: %s\n", 
libusb_error_name(rc));
+        exit(1);
     }
 
-    /* As we are dealing with a CDC-ACM device, it's highly probable that
-     * Linux already attached the cdc-acm driver to this device.
-     * We need to detach the drivers from all the USB interfaces. The CDC-ACM
-     * Class defines two interfaces: the Control interface and the
-     * Data interface.
+    /* Look for a specific device and open it.
      */
+    int fd;
+    rc = sscanf(argv[1], "%d", &fd);
+    if (rc != 1) {
+        fprintf(stderr, "Failed to read fd: %d\n", rc);
+        exit(1);
+    }
+    rc = libusb_wrap_sys_device(ctx, (intptr_t) fd, &devh);
+    if (rc != 0) {
+        fprintf(stderr, "Failed to wrap fd %d: %s\n", fd, 
libusb_error_name(rc));
+        exit(1);
+    }
+
     for (int if_num = 0; if_num < 2; if_num++) {
         if (libusb_kernel_driver_active(devh, if_num)) {
             libusb_detach_kernel_driver(devh, if_num);
@@ -111,6 +115,7 @@ int main(int argc, char **argv)
     if (rc < 0) {
         fprintf(stderr, "Error during control transfer: %s\n",
                 libusb_error_name(rc));
+        goto out;
     }
 
     /* - set line encoding: here 9600 8N1
@@ -122,19 +127,34 @@ int main(int argc, char **argv)
     if (rc < 0) {
         fprintf(stderr, "Error during control transfer: %s\n",
                 libusb_error_name(rc));
+        goto out;
     }
 
     /* We can now start sending or receiving data to the device
      */
     unsigned char buf[65];
-    int len;
-    
+    int len, inputlen;
+
+    fcntl(0, F_SETFL, fcntl(0, F_GETFL) | O_NONBLOCK);
+
+    fprintf(stderr, "Connected.\n");
+
     while(1) {
-        write_char('t');
+        while ((inputlen = read(0, buf, 1)) == 1) {
+            if (write_char(buf[0])) {
+                break;
+            }
+        }
+        if (inputlen < 0 && errno != EAGAIN) {
+            perror("read");
+            break;
+        }
         len = read_chars(buf, 64);
+        if (len == -1) { fprintf(stderr, "failed read chars\n"); break; }
+        if (len == 0) { usleep(150000); continue; }
         buf[len] = 0;
-        fprintf(stdout, "Received: \"%s\"\n", buf);
-        sleep(1);
+        fprintf(stdout, "%s", buf);
+        fflush(stdout);
     }
 
     libusb_release_interface(devh, 0);
@@ -142,6 +162,6 @@ int main(int argc, char **argv)
 out:
     if (devh)
             libusb_close(devh);
-    libusb_exit(NULL);
+    libusb_exit(ctx);
     return rc;
 }

Reply via email to