From d461365275c6290a2c936a4ea038cb9ed8ba242b Mon Sep 17 00:00:00 2001 From: zacharyc Date: Thu, 19 Mar 2009 22:19:05 +0000 Subject: [PATCH] Added better error recovery code. git-svn-id: https://bucket.mit.edu/svn/nilm/acquisition/ethstream@7314 ddd99763-3ecb-0310-9145-efcb8ce7c51f --- ethstream.c | 44 ++++++++++++++++++++++++-------------------- nerdjack.c | 35 ++++++++++++++++++++--------------- nerdjack.h | 1 + 3 files changed, 45 insertions(+), 35 deletions(-) diff --git a/ethstream.c b/ethstream.c index 089e5bf..f7ae18a 100644 --- a/ethstream.c +++ b/ethstream.c @@ -141,12 +141,12 @@ main (int argc, char *argv[]) tmp = strtol (optarg, &endp, 0); if (*endp != '\0' && *endp != ',') { - //|| tmp < 0 || tmp >= UE9_CHANNELS) { info ("bad channel number: %s\n", optarg); goto printhelp; } //We do not want to overflow channel_list, so we need the check here - //The rest of the sanity checking can come later after we know whether this is a + //The rest of the sanity checking can come later after we know + //whether this is a //LabJack or a NerdJack #if UE9_CHANNELS > NERDJACK_CHANNELS if (channel_count >= UE9_CHANNELS) @@ -225,8 +225,9 @@ main (int argc, char *argv[]) verb_count++; break; case 'V': - printf ("ljstream " VERSION "\n"); + printf ("etherstream " VERSION "\n"); printf ("Written by Jim Paris \n"); + printf ("and Zachary Clifford \n"); printf ("This program comes with no warranty and is " "provided under the GPLv2.\n"); return 0; @@ -315,7 +316,6 @@ doneparse: { info ("error: can't achieve requested scan rate (%lf Hz)\n", desired_rate); - //return 1; } } else @@ -325,7 +325,6 @@ doneparse: { info ("error: can't achieve requested scan rate (%lf Hz)\n", desired_rate); - //return 1; } } @@ -425,9 +424,9 @@ nerdDoStream (const char *address, int *channel_list, int channel_count, getPacket command; static unsigned short currentcount = 0; - //usleep(1000000); - - if (first_call) + //If this is the first time, set up acquisition + //Otherwise try to resume the previous one + if (started == 0) { if (nerd_generate_command (&command, channel_list, channel_count, precision, period) < 0) @@ -436,7 +435,6 @@ nerdDoStream (const char *address, int *channel_list, int channel_count, goto out; } - if (nerd_send_command (address, "STOP", 4) < 0) { if (first_call) @@ -445,28 +443,34 @@ nerdDoStream (const char *address, int *channel_list, int channel_count, goto out; } + //We've tried communicating, so this is not the first call anymore + first_call = 0; + if (nerd_send_command (address, &command, sizeof (command)) < 0) { info ("Failed to send GET command\n"); goto out; } - } - //We have sent the configuration commands. If we retry later, don't resend them. We would like - //to resume the interrupted transmission - first_call = 0; - + } else { //If we had a transmission in progress, send a command to resume from there - if (started == 1) - { char cmdbuf[10]; sprintf (cmdbuf, "SETC%05hd", currentcount); - if (nerd_send_command (address, cmdbuf, strlen (cmdbuf)) < 0) - { - info ("Failed to send SETC command\n"); - goto out; + retval = nerd_send_command (address, cmdbuf, strlen (cmdbuf)); + if(retval == -4) { + info("NerdJack was reset\n"); + //Assume we have not started yet, reset on this side. + //If this routine is retried, start over + printf("# NerdJack was reset here\n"); + currentcount = 0; + started = 0; + goto out; + } else if(retval < 0) { + info ("Failed to send SETC command\n"); + goto out; } } + //The transmission has begun started = 1; /* Open connection */ diff --git a/nerdjack.c b/nerdjack.c index e3d4c1d..1cc55bb 100644 --- a/nerdjack.c +++ b/nerdjack.c @@ -60,20 +60,20 @@ nerdjack_choose_scan (double desired_rate, double *actual_rate, info ("Cannot sample that slowly\n"); *actual_rate = (double) NERDJACK_CLOCK_RATE / (double) 0x0ffffe; *period = 0x0ffffe; - //info("Sampling at slowest rate:%f\n",*actual_rate); - return -1; } //Period holds the period register for the NerdJack, so it needs to be right *actual_rate = (double) NERDJACK_CLOCK_RATE / (double) *period; if (*actual_rate != desired_rate) { - //info("Sampling at nearest rate:%f\n",*actual_rate); return -1; } return 0; } +/* Perform autodetection. Returns 0 on success, -1 on error + * Sets ipAddress to the detected address + */ int nerdjack_detect (char *ipAddress) { @@ -163,6 +163,10 @@ nerdjack_detect (char *ipAddress) return 0; } +/* Send the given command to address. The command should be something + * of the specified length. This expects the NerdJack to reply with OK + * or NO + */ int nerd_send_command (const char *address, void *command, int length) { @@ -200,13 +204,15 @@ nerd_send_command (const char *address, void *command, int length) if (0 != strcmp ("OK", buf)) { verb ("Did not receive OK. Received %s\n", buf); - return -1; + return -4; } return 0; } -//Initialize the channel structure to distill how data should be displayed +/* + * Initialize the channel structure to distill how data should be displayed + */ static void nerd_init_channels (deststruct * destination, int numChannels, int numChannelsSampled, int *channel_list) @@ -238,8 +244,6 @@ nerd_init_channels (deststruct * destination, int numChannels, } } - - //If this channel is wanted, set it up. if (currentalign > 0) { @@ -283,7 +287,9 @@ nerd_data_stream (int data_fd, int numChannels, int *channel_list, int numgroups = 0; long double volts; - + + //The timeout should be the expected time plus two seconds + //This permits slower speeds to work properly unsigned int expectedtimeout = (period * NERDJACK_NUM_SAMPLES / NERDJACK_CLOCK_RATE) + 2; @@ -297,7 +303,8 @@ nerd_data_stream (int data_fd, int numChannels, int *channel_list, int numChannelsSampled = channel_list[0] + 1; - //The number sampled will be the highest channel requested plus 1 (i.e. channel 0 requested means 1 sampled) + //The number sampled will be the highest channel requested plus 1 + //(i.e. channel 0 requested means 1 sampled) for (i = 0; i < numChannels; i++) { if (channel_list[i] + 1 > numChannelsSampled) @@ -309,6 +316,7 @@ nerd_data_stream (int data_fd, int numChannels, int *channel_list, nerd_init_channels (destination, numChannels, numChannelsSampled, channel_list); + //If this is the first time called, warn the user if we're too fast if (linesdumped == 0) { if (period < (numChannelsSampled * 100 + 300)) @@ -320,7 +328,6 @@ nerd_data_stream (int data_fd, int numChannels, int *channel_list, //Now destination structure array is set as well as numDuplicates. - //int numChannelsSampled = numChannels - numDuplicates; int numGroups = NERDJACK_NUM_SAMPLES / numChannelsSampled; @@ -332,7 +339,6 @@ nerd_data_stream (int data_fd, int numChannels, int *channel_list, .tv_sec = expectedtimeout}))) { - //We want a complete packet, so take the chars so far and keep waiting if (charsread != NERDJACK_PACKET_SIZE) { //There was a problem getting data. Probably a closed @@ -350,7 +356,6 @@ nerd_data_stream (int data_fd, int numChannels, int *channel_list, //Check counter info to make sure not out of order tempshort = ntohs (buf.packetNumber); - //tempshort = (buf[2] << 8) | buf[3]; if (tempshort != *currentcount) { info ("Count wrong. Expected %hd but got %hd\n", *currentcount, @@ -425,6 +430,7 @@ nerd_data_stream (int data_fd, int numChannels, int *channel_list, //Since channel data is packed, we need to know when to insert a newline if (alignment == numChannelsSampled) { + //We want to dump the first line because it's usually spurious if (linesdumped != 0) { switch (convert) @@ -492,6 +498,7 @@ bad: } +/* Open a connection to the NerdJack */ int nerd_open (const char *address, int port) { @@ -560,7 +567,6 @@ nerd_generate_command (getPacket * command, int *channel_list, channelbit = channelbit | (0x1 << channel_list[i]); } - //command->word = "GETD"; command->word[0] = 'G'; command->word[1] = 'E'; command->word[2] = 'T'; @@ -570,8 +576,6 @@ nerd_generate_command (getPacket * command, int *channel_list, command->period = htonl (period); command->prescaler = 0; - //sprintf(command,"GETD%3.3X%d%5.5d", channelbit,precision,period); - return 0; } @@ -583,3 +587,4 @@ nerd_close_conn (int data_fd) close (data_fd); return 0; } + diff --git a/nerdjack.h b/nerdjack.h index 06fdada..ceaedc8 100644 --- a/nerdjack.h +++ b/nerdjack.h @@ -24,6 +24,7 @@ #define NERDJACK_PACKET_SIZE 1460 #define NERDJACK_NUM_SAMPLES 724 +/* Packet structure used in message to start sampling on NerdJack */ typedef struct __attribute__ ((__packed__)) { char word[4];