Massive cleanup and refactoring of data_stream function.
git-svn-id: https://bucket.mit.edu/svn/nilm/acquisition/ethstream@7431 ddd99763-3ecb-0310-9145-efcb8ce7c51f
This commit is contained in:
parent
2e3f2f4b23
commit
a57c0c22c2
55
ethstream.c
55
ethstream.c
|
@ -146,7 +146,7 @@ main (int argc, char *argv[])
|
|||
}
|
||||
//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
|
||||
//whether this is a
|
||||
//LabJack or a NerdJack
|
||||
#if UE9_CHANNELS > NERDJACK_CHANNELS
|
||||
if (channel_count >= UE9_CHANNELS)
|
||||
|
@ -227,7 +227,7 @@ main (int argc, char *argv[])
|
|||
case 'V':
|
||||
printf ("etherstream " VERSION "\n");
|
||||
printf ("Written by Jim Paris <jim@jtan.com>\n");
|
||||
printf ("and Zachary Clifford <zacharyc@mit.edu>\n");
|
||||
printf ("and Zachary Clifford <zacharyc@mit.edu>\n");
|
||||
printf ("This program comes with no warranty and is "
|
||||
"provided under the GPLv2.\n");
|
||||
return 0;
|
||||
|
@ -445,31 +445,34 @@ tryagain:
|
|||
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;
|
||||
}
|
||||
} else {
|
||||
//If we had a transmission in progress, send a command to resume from there
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
//If we had a transmission in progress, send a command to resume from there
|
||||
char cmdbuf[10];
|
||||
sprintf (cmdbuf, "SETC%05hd", currentcount);
|
||||
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;
|
||||
wasreset = 1;
|
||||
goto tryagain;
|
||||
} else if(retval < 0) {
|
||||
info ("Failed to send SETC command\n");
|
||||
goto out;
|
||||
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;
|
||||
wasreset = 1;
|
||||
goto tryagain;
|
||||
}
|
||||
else if (retval < 0)
|
||||
{
|
||||
info ("Failed to send SETC command\n");
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -485,14 +488,14 @@ tryagain:
|
|||
}
|
||||
|
||||
retval = nerd_data_stream
|
||||
(fd_data, channel_count, channel_list, precision, convert, lines,
|
||||
showmem, ¤tcount, period, wasreset);
|
||||
(fd_data, channel_count, channel_list, precision, convert, lines,
|
||||
showmem, ¤tcount, period, wasreset);
|
||||
wasreset = 0;
|
||||
if(retval == -3)
|
||||
{
|
||||
if (retval == -3)
|
||||
{
|
||||
retval = 0;
|
||||
}
|
||||
if(retval < 0)
|
||||
}
|
||||
if (retval < 0)
|
||||
{
|
||||
info ("Failed to open data stream\n");
|
||||
goto out1;
|
||||
|
@ -504,6 +507,8 @@ tryagain:
|
|||
out1:
|
||||
nerd_close_conn (fd_data);
|
||||
out:
|
||||
//We've tried communicating, so this is not the first call anymore
|
||||
first_call = 0;
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
|
268
nerdjack.c
268
nerdjack.c
|
@ -27,13 +27,6 @@
|
|||
|
||||
#define NERDJACK_TIMEOUT 5 /* Timeout for connect/send/recv, in seconds */
|
||||
|
||||
//Struct holding information about how channels should be reordered for output
|
||||
typedef struct
|
||||
{
|
||||
int numCopies;
|
||||
int *destlist;
|
||||
} deststruct;
|
||||
|
||||
#define NERD_HEADER_SIZE 8
|
||||
|
||||
typedef struct __attribute__ ((__packed__))
|
||||
|
@ -211,85 +204,45 @@ nerd_send_command (const char *address, void *command, int length)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* 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)
|
||||
{
|
||||
|
||||
int channelprocessing = 0;
|
||||
int currentalign = 0; //Index into sampled channels
|
||||
int i;
|
||||
int tempdestlist[NERDJACK_CHANNELS];
|
||||
|
||||
//Clear out destination stuff
|
||||
for (i = 0; i < numChannelsSampled; i++)
|
||||
{
|
||||
destination[i].numCopies = 0;
|
||||
}
|
||||
|
||||
|
||||
for (channelprocessing = 0; channelprocessing < numChannelsSampled;
|
||||
channelprocessing++)
|
||||
{
|
||||
//Find out how many copies of each channel so we malloc the right things
|
||||
currentalign = 0;
|
||||
for (i = 0; i < numChannels; i++)
|
||||
{
|
||||
if (channelprocessing == channel_list[i])
|
||||
{
|
||||
tempdestlist[currentalign] = i;
|
||||
currentalign++;
|
||||
}
|
||||
}
|
||||
|
||||
//If this channel is wanted, set it up.
|
||||
if (currentalign > 0)
|
||||
{
|
||||
destination[channelprocessing].numCopies = currentalign;
|
||||
destination[channelprocessing].destlist =
|
||||
malloc (destination[channelprocessing].numCopies * sizeof (int));
|
||||
memcpy (destination[channelprocessing].destlist, tempdestlist,
|
||||
destination[channelprocessing].numCopies * sizeof (int));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
int
|
||||
nerd_data_stream (int data_fd, int numChannels, int *channel_list,
|
||||
int precision, int convert, int lines, int showmem,
|
||||
unsigned short *currentcount, unsigned int period,
|
||||
int wasreset)
|
||||
int wasreset)
|
||||
{
|
||||
//Variables that should persist across retries
|
||||
static dataPacket buf;
|
||||
static int linesleft = 0;
|
||||
static int linesdumped = 0;
|
||||
|
||||
int index = 0;
|
||||
int charsprocessed = 0;
|
||||
int alignment = 0;
|
||||
//Variables essential to packet processing
|
||||
signed short datapoint = 0;
|
||||
unsigned short dataline[NERDJACK_CHANNELS];
|
||||
long double voltline[NERDJACK_CHANNELS];
|
||||
int i;
|
||||
|
||||
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)
|
||||
for (i = 0; i < numChannels; i++)
|
||||
{
|
||||
if (channel_list[i] + 1 > numChannelsSampled)
|
||||
numChannelsSampled = channel_list[i] + 1;
|
||||
}
|
||||
|
||||
|
||||
long double voltline[numChannels];
|
||||
|
||||
unsigned short dataline[numChannels];
|
||||
|
||||
//unsigned long memused = 0;
|
||||
unsigned short packetsready = 0;
|
||||
unsigned short adcused = 0;
|
||||
unsigned short tempshort = 0;
|
||||
int charsread = 0;
|
||||
|
||||
int numgroups = 0;
|
||||
int numgroupsProcessed = 0;
|
||||
long double volts;
|
||||
|
||||
|
||||
//The timeout should be the expected time plus two seconds
|
||||
//This permits slower speeds to work properly
|
||||
unsigned int expectedtimeout =
|
||||
|
@ -302,26 +255,12 @@ nerd_data_stream (int data_fd, int numChannels, int *channel_list,
|
|||
linesleft = lines;
|
||||
}
|
||||
|
||||
if(wasreset) {
|
||||
linesdumped = 0;
|
||||
}
|
||||
|
||||
|
||||
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)
|
||||
for (i = 0; i < numChannels; i++)
|
||||
//If there was a reset, we still need to dump a line because of faulty PDCA start
|
||||
if (wasreset)
|
||||
{
|
||||
if (channel_list[i] + 1 > numChannelsSampled)
|
||||
numChannelsSampled = channel_list[i] + 1;
|
||||
linesdumped = 0;
|
||||
}
|
||||
|
||||
deststruct destination[numChannelsSampled];
|
||||
|
||||
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)
|
||||
{
|
||||
|
@ -334,7 +273,7 @@ nerd_data_stream (int data_fd, int numChannels, int *channel_list,
|
|||
|
||||
//Now destination structure array is set as well as numDuplicates.
|
||||
|
||||
int numGroups = NERDJACK_NUM_SAMPLES / numChannelsSampled;
|
||||
int totalGroups = NERDJACK_NUM_SAMPLES / numChannelsSampled;
|
||||
|
||||
|
||||
//Loop forever to grab data
|
||||
|
@ -372,18 +311,9 @@ nerd_data_stream (int data_fd, int numChannels, int *channel_list,
|
|||
//Increment number of packets received
|
||||
*currentcount = *currentcount + 1;
|
||||
|
||||
//Process the rest of the header and update the index value to be pointing after it
|
||||
charsprocessed = NERD_HEADER_SIZE;
|
||||
//memused = ntohl (buf.lwipmemoryused);
|
||||
adcused = ntohs (buf.adcused);
|
||||
packetsready = ntohs (buf.packetsready);
|
||||
alignment = 0;
|
||||
numgroups = 0;
|
||||
|
||||
//if(memused) {
|
||||
// printf("#Packet lost\n");
|
||||
// continue;
|
||||
//}
|
||||
numgroupsProcessed = 0;
|
||||
|
||||
if (showmem)
|
||||
{
|
||||
|
@ -391,18 +321,35 @@ nerd_data_stream (int data_fd, int numChannels, int *channel_list,
|
|||
continue;
|
||||
}
|
||||
|
||||
index = 0;
|
||||
//While there is still more data in the packet, process it
|
||||
//use the destination structure to load the line before printing
|
||||
while (charsread > charsprocessed)
|
||||
while (numgroupsProcessed < totalGroups)
|
||||
{
|
||||
datapoint = ntohs (buf.data[index]);
|
||||
if (destination[alignment].numCopies != 0)
|
||||
//Poison the data structure
|
||||
switch (convert)
|
||||
{
|
||||
case CONVERT_VOLTS:
|
||||
memset (voltline, 0, numChannels * sizeof (long double));
|
||||
break;
|
||||
default:
|
||||
case CONVERT_HEX:
|
||||
case CONVERT_DEC:
|
||||
memset (dataline, 0, numChannels * sizeof (unsigned char));
|
||||
}
|
||||
|
||||
//Read in each group
|
||||
for (i = 0; i < numChannels; i++)
|
||||
{
|
||||
//Get the datapoint associated with the desired channel
|
||||
datapoint =
|
||||
ntohs (buf.
|
||||
data[channel_list[i] +
|
||||
numgroupsProcessed * numChannelsSampled]);
|
||||
|
||||
//Place it into the line
|
||||
switch (convert)
|
||||
{
|
||||
case CONVERT_VOLTS:
|
||||
if (alignment <= 5)
|
||||
if (channel_list[i] <= 5)
|
||||
{
|
||||
volts =
|
||||
(long double) (datapoint / 32767.0) *
|
||||
|
@ -414,74 +361,48 @@ nerd_data_stream (int data_fd, int numChannels, int *channel_list,
|
|||
(long double) (datapoint / 32767.0) *
|
||||
((precision & 0x02) ? 5.0 : 10.0);
|
||||
}
|
||||
for (i = 0; i < destination[alignment].numCopies; i++)
|
||||
{
|
||||
voltline[destination[alignment].destlist[i]] = volts;
|
||||
}
|
||||
voltline[i] = volts;
|
||||
break;
|
||||
default:
|
||||
case CONVERT_HEX:
|
||||
case CONVERT_DEC:
|
||||
for (i = 0; i < destination[alignment].numCopies; i++)
|
||||
dataline[i] = (unsigned short) (datapoint - INT16_MIN);
|
||||
break;
|
||||
}
|
||||
}
|
||||
//We want to dump the first line because it's usually spurious
|
||||
if (linesdumped != 0)
|
||||
{
|
||||
//Now print the group
|
||||
switch (convert)
|
||||
{
|
||||
case CONVERT_VOLTS:
|
||||
for (i = 0; i < numChannels; i++)
|
||||
{
|
||||
dataline[destination[alignment].destlist[i]] =
|
||||
(unsigned short) (datapoint - INT16_MIN);
|
||||
if (printf ("%Lf ", voltline[i]) < 0)
|
||||
goto bad;
|
||||
}
|
||||
break;
|
||||
case CONVERT_HEX:
|
||||
for (i = 0; i < numChannels; i++)
|
||||
{
|
||||
if (printf ("%04hX", dataline[i]) < 0)
|
||||
goto bad;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
case CONVERT_DEC:
|
||||
for (i = 0; i < numChannels; i++)
|
||||
{
|
||||
if (printf ("%hu ", dataline[i]) < 0)
|
||||
goto bad;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (printf ("\n") < 0)
|
||||
goto bad;
|
||||
|
||||
}
|
||||
|
||||
//Each point is two bytes, so increment index and total bytes read
|
||||
charsprocessed++;
|
||||
charsprocessed++;
|
||||
index++;
|
||||
alignment++;
|
||||
|
||||
//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)
|
||||
{
|
||||
case CONVERT_VOLTS:
|
||||
for (i = 0; i < numChannels; i++)
|
||||
{
|
||||
if (printf ("%Lf ", voltline[i]) < 0)
|
||||
goto bad;
|
||||
}
|
||||
break;
|
||||
case CONVERT_HEX:
|
||||
for (i = 0; i < numChannels; i++)
|
||||
{
|
||||
if (printf ("%04hX", dataline[i]) < 0)
|
||||
goto bad;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
case CONVERT_DEC:
|
||||
for (i = 0; i < numChannels; i++)
|
||||
{
|
||||
if (printf ("%hu ", dataline[i]) < 0)
|
||||
goto bad;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (printf ("\n") < 0)
|
||||
goto bad;
|
||||
}
|
||||
else
|
||||
{
|
||||
linesdumped = linesdumped + 1;
|
||||
if (lines != 0)
|
||||
{
|
||||
linesleft++;
|
||||
}
|
||||
}
|
||||
alignment = 0;
|
||||
numgroups++;
|
||||
//If we're counting lines, decrement them
|
||||
if (lines != 0)
|
||||
{
|
||||
linesleft--;
|
||||
|
@ -490,15 +411,17 @@ nerd_data_stream (int data_fd, int numChannels, int *channel_list,
|
|||
return 0;
|
||||
}
|
||||
}
|
||||
//If numgroups so far is equal to the numGroups in a packet, this packet is done
|
||||
if (numgroups == numGroups)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
linesdumped = linesdumped + 1;
|
||||
}
|
||||
|
||||
//We've processed this group, so advance the counter
|
||||
numgroupsProcessed++;
|
||||
|
||||
}
|
||||
index = 0;
|
||||
charsprocessed = 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -576,15 +499,17 @@ nerd_generate_command (getPacket * command, int *channel_list,
|
|||
|
||||
for (i = 0; i < channel_count; i++)
|
||||
{
|
||||
if (channel_list[i] > highestchannel) {
|
||||
highestchannel = channel_list[i];
|
||||
}
|
||||
if (channel_list[i] > highestchannel)
|
||||
{
|
||||
highestchannel = channel_list[i];
|
||||
}
|
||||
//channelbit = channelbit | (0x1 << channel_list[i]);
|
||||
}
|
||||
|
||||
for( i = 0; i <= highestchannel; i++) {
|
||||
channelbit = channelbit | (0x01 << i);
|
||||
}
|
||||
for (i = 0; i <= highestchannel; i++)
|
||||
{
|
||||
channelbit = channelbit | (0x01 << i);
|
||||
}
|
||||
|
||||
command->word[0] = 'G';
|
||||
command->word[1] = 'E';
|
||||
|
@ -606,4 +531,3 @@ nerd_close_conn (int data_fd)
|
|||
close (data_fd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -50,7 +50,7 @@ int nerd_send_command (const char *address, void *command, int length);
|
|||
int nerd_data_stream (int data_fd, int numChannels, int *channel_list,
|
||||
int precision, int convert, int lines, int showmem,
|
||||
unsigned short *currentcount, unsigned int period,
|
||||
int wasreset);
|
||||
int wasreset);
|
||||
|
||||
/* Detect the IP Address of the NerdJack and return in ipAddress */
|
||||
int nerdjack_detect (char *ipAddress);
|
||||
|
|
Loading…
Reference in New Issue
Block a user