Fix ADC sampling
authorSam Moore <[email protected]>
Sun, 22 Sep 2013 04:03:38 +0000 (12:03 +0800)
committerSam Moore <[email protected]>
Sun, 22 Sep 2013 04:03:38 +0000 (12:03 +0800)
- Fixed ADC_Read function
- The path to the ADC data files is generally different (hooray)
- Modified run.sh to work it out and pass to the program
  - run.sh also loads kernel modules, etc

server/actuator.c
server/bbb_pin.c
server/bbb_pin.h
server/main.c
server/options.h
server/run.sh
server/sensor.c

index 50a27de..6d544f2 100644 (file)
@@ -32,6 +32,7 @@ void Actuator_Init()
        // Initialise pins used
        GPIO_Export(GPIO1_16);
        PWM_Export(EHRPWM0A);
+       PWM_Export(EHRPWM0B);
        
 }
 
index f8ba011..39f6f1f 100644 (file)
@@ -9,6 +9,8 @@
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <fcntl.h>
+#include <ctype.h>
+#include "options.h"
 
 /**
  * Structure to represent a GPIO pin
@@ -26,7 +28,7 @@ typedef struct
  */
 typedef struct
 {
-       FILE * file_value;
+       int fd_value;
 } ADC_Pin;
 
 /**
@@ -129,7 +131,7 @@ void PWM_Export(int pin)
        if (export == NULL)
                Fatal("Couldn't open %s to export PWM pin %d - %s", g_buffer, pin, strerror(errno));
        
-       fprintf(export, "%d", pin);
+       fprintf(export, "%d\n", pin);
        fclose(export);
 
        // Open file descriptors
@@ -194,22 +196,14 @@ void PWM_Unexport(int pin)
  */
 void ADC_Export()
 {
-       
-       FILE * export = fopen(ADC_EXPORT_PATH, "w");
-       if (export == NULL)
-               Fatal("Couldn't open %s to export ADCs - %s", ADC_EXPORT_PATH, strerror(errno));
-
-       fprintf(export, "cape-bone-iio");
-       fclose(export);
-
        for (int i = 0; i < ADC_NUM_PINS; ++i)
        {
-               sprintf(g_buffer, "%s/AIN%d", ADC_DEVICE_PATH, i);
-               g_adc[i].file_value = fopen(g_buffer, "r");
-               if (g_adc[i].file_value == NULL)
+               sprintf(g_buffer, "%s/AIN%d", g_options.adc_device_path, i);
+               g_adc[i].fd_value = open(g_buffer, O_RDONLY);
+               if (g_adc[i].fd_value < 0)
                        Fatal("Couldn't open ADC %d device file %s - %s", i, g_buffer, strerror(errno));
 
-               setbuf(g_adc[i].file_value, NULL);
+               //setbuf(g_adc[i].file_value, NULL);
 
        }
 }
@@ -220,7 +214,7 @@ void ADC_Export()
 void ADC_Unexport()
 {
        for (int i = 0; i < ADC_NUM_PINS; ++i)
-               fclose(g_adc[i].file_value);
+               close(g_adc[i].fd_value);
 }
 
 /**
@@ -229,11 +223,11 @@ void ADC_Unexport()
  */
 void GPIO_Set(int pin, bool value)
 {
-       if (pwrite(g_gpio[pin].fd_direction, "out", 3*sizeof(char), 0) != 3)
+       if (pwrite(g_gpio[pin].fd_direction, "out", 3, 0) != 3)
                Fatal("Couldn't set GPIO %d direction - %s", pin, strerror(errno));
 
        char c = '0' + (value);
-       if (pwrite(g_gpio[pin].fd_value, &c, 1*sizeof(char), 0) != 1)
+       if (pwrite(g_gpio[pin].fd_value, &c, 1, 0) != 1)
                Fatal("Couldn't read GPIO %d value - %s", pin, strerror(errno));
 
 }
@@ -244,10 +238,10 @@ void GPIO_Set(int pin, bool value)
  */
 bool GPIO_Read(int pin)
 {
-       if (pwrite(g_gpio[pin].fd_direction, "in", 2*sizeof(char), 0) != 2)
+       if (pwrite(g_gpio[pin].fd_direction, "in", 2, 0) != 2)
                Fatal("Couldn't set GPIO %d direction - %s", pin, strerror(errno)); 
        char c = '0';
-       if (pread(g_gpio[pin].fd_value, &c, 1*sizeof(char), 0) != 1)
+       if (pread(g_gpio[pin].fd_value, &c, 1, 0) != 1)
                Fatal("Couldn't read GPIO %d value - %s", pin, strerror(errno));
 
        return (c == '1');
@@ -264,11 +258,11 @@ bool GPIO_Read(int pin)
 void PWM_Set(int pin, bool polarity, long period, long duty)
 {
        // Have to stop PWM before changing it
-       if (pwrite(g_pwm[pin].fd_run, "0", 1*sizeof(char), 0) != 1)
+       if (pwrite(g_pwm[pin].fd_run, "0", 1, 0) != 1)
                Fatal("Couldn't stop PWM %d - %s", pin, strerror(errno));
 
        char c = '0' + polarity;
-       if (pwrite(g_pwm[pin].fd_polarity, &c, 1*sizeof(char), 0) != 1)
+       if (pwrite(g_pwm[pin].fd_polarity, &c, 1, 0) != 1)
                Fatal("Couldn't set PWM %d polarity - %s", pin, strerror(errno));
 
        
@@ -281,7 +275,7 @@ void PWM_Set(int pin, bool polarity, long period, long duty)
        if (fprintf(g_pwm[pin].file_period, "%lu", period) == 0)
                Fatal("Couldn't set period for PWM %d - %s", pin, strerror(errno));
        
-       if (pwrite(g_pwm[pin].fd_run, "1", 1*sizeof(char), 0) != 1)
+       if (pwrite(g_pwm[pin].fd_run, "1", 1, 0) != 1)
                Fatal("Couldn't start PWM %d - %s", pin, strerror(errno));
 
 }
@@ -292,7 +286,7 @@ void PWM_Set(int pin, bool polarity, long period, long duty)
  */
 void PWM_Stop(int pin)
 {
-       if (pwrite(g_pwm[pin].fd_run, "0", 1*sizeof(char), 0) != 1)
+       if (pwrite(g_pwm[pin].fd_run, "0", 1, 0) != 1)
                Fatal("Couldn't stop PWM %d - %s", pin, strerror(errno));
 
 }
@@ -302,25 +296,28 @@ void PWM_Stop(int pin)
  * @param id - The ID of the ADC pin to read
  * @returns - The reading of the ADC channel
  */
-long ADC_Read(int id)
+int ADC_Read(int id)
 {
-
-       //Log(LOGDEBUG, "Called for pin %d", id);
-       char adc_val[ADC_DIGITS] = "";
-       rewind(g_adc[id].file_value);
-       fgets(adc_val, sizeof(adc_val)/sizeof(char), g_adc[id].file_value);
-       for(int i = ADC_DIGITS-1; i > 0; --i)
+       char adc_str[ADC_DIGITS] = "";
+       lseek(g_adc[id].fd_value, 0, SEEK_SET);
+       
+       int i = 0;
+       for (i = 0; i < ADC_DIGITS-1; ++i)
        {
-               if (adc_val[i] == '\n')
-                       adc_val[i] = '\0';
+               if (read(g_adc[id].fd_value, adc_str+i, 1) != 1)
+                       break;
+               if (adc_str[i] == '\n')
+               {
+                       adc_str[i] = '\0';
+                       break;
+               }
        }
 
        char * end;
-       long val = strtol(adc_val, &end, 10);
+       int val = strtol(adc_str, &end, 10);
        if (*end != '\0')
        {
-               Log(LOGERR, "Reading ADC%d gives %s - invalid!", id, adc_val);
-       }
-       //Log(LOGDEBUG, "Returns %lu", val);
-       return val;
+               Log(LOGERR, "Read non integer from ADC %d - %s", id, adc_str);
+       }       
+       return val;     
 }
index 472a917..04c02b6 100644 (file)
@@ -24,7 +24,7 @@ extern void ADC_Unexport();
 extern bool GPIO_Read(int pin);
 extern void GPIO_Set(int pin, bool value);
 
-extern long ADC_Read(int pin);
+extern int ADC_Read(int pin);
 
 extern void PWM_Set(int pin, bool polarity, long period, long duty); // period and duty are in ns
 extern void PWM_Stop(int pin);
index c032eb1..930b8b0 100644 (file)
@@ -9,6 +9,7 @@
 #include "sensor.h"
 #include "actuator.h"
 #include "control.h"
+#include "bbb_pin_defines.h"
 
 // --- Standard headers --- //
 #include <syslog.h> // for system logging
@@ -29,7 +30,32 @@ void ParseArguments(int argc, char ** argv)
        g_options.program = argv[0]; // program name
        g_options.verbosity = LOGDEBUG; // default log level
        gettimeofday(&(g_options.start_time), NULL); // Start time
+       g_options.adc_device_path = ADC_DEVICE_PATH;
        Log(LOGDEBUG, "Called as %s with %d arguments.", g_options.program, argc);
+
+       for (int i = 1; i < argc; ++i)
+       {
+               if (argv[i][0] != '-')
+                       Fatal("Unexpected argv[%d] - %s", i, argv[i]);
+
+               if (i+1 >= argc || argv[i+1][0] == '-')
+                       Fatal("No argument following switch %s", argv[i]);
+               
+               if (strlen(argv[i]) > 2)
+                       Fatal("Human readable switches are not supported.");
+
+               switch (argv[i][1])
+               {
+                       case 'a':
+                               g_options.adc_device_path = argv[i+1];
+                               Log(LOGINFO, "ADC Device Path: %s", argv[i+1]);
+                               ++i;
+                               break;
+                       default:
+                               Fatal("Unrecognised switch %s", argv[i]);
+                               break;
+               }
+       }       
 }
 
 /**
@@ -67,11 +93,14 @@ void Cleanup()
  */
 int main(int argc, char ** argv)
 {
+       // Open log before calling ParseArguments (since ParseArguments may call the Log functions)
+       openlog("mctxserv", LOG_PID | LOG_PERROR, LOG_USER);
+       Log(LOGINFO, "Server started");
+
        ParseArguments(argc, argv);
 
        //Open the system log
-       openlog("mctxserv", LOG_PID | LOG_PERROR, LOG_USER);
-       Log(LOGINFO, "Server started");
+
        // signal handler
        //TODO: Make this work
        /*
index a20e0e1..0416dd5 100644 (file)
@@ -19,6 +19,9 @@ typedef struct
        /** Time at which program exits **/
        struct timeval end_time;
 
+       /** Path to ADC files **/
+       char * adc_device_path;
+
 } Options;
 
 /** The only instance of the Options struct **/
index aafc5d1..be6d4cf 100755 (executable)
@@ -3,4 +3,34 @@
 #spawn-fcgi -p9005 -n ./valgrind.sh
 # Use this to run the server normally
 #./stream &
-spawn-fcgi -p9005 -n ./server
+
+# Check running as root
+if [ "$(whoami)" != "root" ]; then
+       (echo "Run $0 as root.") 1>&2
+       exit 1
+fi
+
+# Check existence of program
+if [ ! -e "server" ]; then
+       (echo "Rebuild server.") 1>&2;
+       exit 1
+fi
+
+# Identify cape-manager slots
+slot=$(echo /sys/devices/bone_capemgr.*/slots | awk '{print $1}')
+
+# Load PWM module
+modprobe pwm_test
+(echo am33xx_pwm > $slot) 1>&2 >> /dev/null
+
+# Load ADCs
+(echo cape-bone-iio > $slot) 1>&2 >> /dev/null
+# Find adc_device_path
+# NOTE: This has to be passed as a parameter, because it is not always the same. For some unfathomable reason. Hooray.
+adc_device_path=$(dirname $(find /sys -name *AIN0))
+
+
+# Run the program with parameters
+# TODO: Can tell spawn-fcgi to run the program as an unprivelaged user?
+# But first will have to work out how to set PWM/GPIO as unprivelaged user
+spawn-fcgi -p9005 -n -- ./server -a "$adc_device_path"
index 9d0b33c..28c3f5e 100644 (file)
@@ -138,12 +138,12 @@ void Sensor_CheckData(SensorId id, double value)
 {
        if( value > thresholds[id].max_error || value < thresholds[id].min_error)
        {
-               Log(LOGERR, "Sensor %s is above or below its safety value of %f or %f\n", g_sensor_names[id],thresholds[id].max_error, thresholds[id].min_error);
+               Log(LOGERR, "Sensor %s at %f is above or below its safety value of %f or %f\n", value, g_sensor_names[id],thresholds[id].max_error, thresholds[id].min_error);
                //new function that stops actuators?
        }
        else if( value > thresholds[id].max_warn || value < thresholds[id].min_warn)
        {
-               Log(LOGWARN, "Sensor %s is above or below its warning value of %f or %f\n", g_sensor_names[id],thresholds[id].max_warn, thresholds[id].min_warn);       
+               Log(LOGWARN, "Sensor %s at %f is above or below its warning value of %f or %f\n", value, g_sensor_names[id],thresholds[id].max_warn, thresholds[id].min_warn);  
        }
 }
 
@@ -173,7 +173,7 @@ bool Sensor_Read(Sensor * s, DataPoint * d)
                        static bool set = false;
                        
                        GPIO_Set(GPIO0_30, true);
-                       d->value = (double)ADC_Read(ADC0);      //ADC #0 on the Beaglebone
+                       d->value = 0;//(double)ADC_Read(ADC0);  //ADC #0 on the Beaglebone
                        //Log(LOGDEBUG, "Got value %f from ADC0", d->value);
                        GPIO_Set(GPIO0_30, false);
                        set = !set;

UCC git Repository :: git.ucc.asn.au