151 lines
4.6 KiB
C
151 lines
4.6 KiB
C
#include <stdlib.h>
|
|
#include <stdio.h>
|
|
#include <stdint.h>
|
|
#include <math.h>
|
|
|
|
struct packet_s {
|
|
char range;
|
|
char digits[5];
|
|
char function;
|
|
char status;
|
|
char options[4];
|
|
char eol[2];
|
|
};
|
|
|
|
enum unit_e {
|
|
U_UNKNOWN = 0,
|
|
U_VOLTAGE,
|
|
U_CURRENT,
|
|
U_RESISTANCE,
|
|
U_FREQUENCY,
|
|
U_CAPACITANCE,
|
|
U_ADP // ???
|
|
};
|
|
|
|
struct range_entry_s {
|
|
uint8_t divider; // Where to place the decimal point
|
|
int8_t exponent; // 0->Unit 3->KUnit 6->MUnit -3->mUnit -6->uUnit ...
|
|
};
|
|
|
|
char *units[] = { "?", "V", "A", "Ohm", "Hz", "F", "?" };
|
|
|
|
enum unit_e function_unit[] = {
|
|
U_CURRENT, // 22A
|
|
U_VOLTAGE, // Diode
|
|
U_FREQUENCY,
|
|
U_RESISTANCE,
|
|
U_UNKNOWN, // Temperature
|
|
U_RESISTANCE, // Continuity
|
|
U_CAPACITANCE,
|
|
U_UNKNOWN,
|
|
U_UNKNOWN,
|
|
U_CURRENT, // Manual current
|
|
U_UNKNOWN,
|
|
U_VOLTAGE,
|
|
U_UNKNOWN,
|
|
U_CURRENT, // Auto uA
|
|
U_UNKNOWN, // ADP
|
|
U_CURRENT // Auto mA
|
|
};
|
|
|
|
struct range_entry_s ranges[8][16] = {
|
|
// 22A Diode Freq Resist Temp Cont Capac ? ? Man A ? V ? Auto uA ADP Auto mA
|
|
{ { 3, 0 }, { 4, 0 }, { 2, 0 }, { 2, 0 }, { 0, 0 }, { 2, 0 }, { 3, -9}, { 0, 0 }, { 0, 0 }, { 4, 0 }, { 0, 0 }, { 4, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 } },
|
|
{ { 0, 0 }, { 0, 0 }, { 1, 0 }, { 4, 3 }, { 0, 0 }, { 0, 0 }, { 2, -9}, { 0, 0 }, { 0, 0 }, { 3, 0 }, { 0, 0 }, { 3, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 } },
|
|
{ { 0, 0 }, { 0, 0 }, { 0, 0 }, { 3, 3 }, { 0, 0 }, { 0, 0 }, { 4, -6}, { 0, 0 }, { 0, 0 }, { 2, 0 }, { 0, 0 }, { 2, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 } },
|
|
{ { 0, 0 }, { 0, 0 }, { 3, 3 }, { 2, 3 }, { 0, 0 }, { 0, 0 }, { 3, -6}, { 0, 0 }, { 0, 0 }, { 1, 0 }, { 0, 0 }, { 1, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 } },
|
|
{ { 0, 0 }, { 0, 0 }, { 2, 3 }, { 4, 6 }, { 0, 0 }, { 0, 0 }, { 2, -6}, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 2, -3}, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 } },
|
|
{ { 0, 0 }, { 0, 0 }, { 4, 6 }, { 3, 6 }, { 0, 0 }, { 0, 0 }, { 4, -3}, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 } },
|
|
{ { 0, 0 }, { 0, 0 }, { 3, 6 }, { 2, 6 }, { 0, 0 }, { 0, 0 }, { 3, -3}, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 } },
|
|
{ { 0, 0 }, { 0, 0 }, { 2, 6 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 2, -3}, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 } }
|
|
};
|
|
|
|
int parse_packet(struct packet_s *packet) {
|
|
int32_t number;
|
|
double reading;
|
|
int i;
|
|
int range, function;
|
|
struct range_entry_s re;
|
|
|
|
for (number = 0, i = 0; i < sizeof(packet->digits); i++) {
|
|
number *= 10;
|
|
number += packet->digits[i] & 0x0f;
|
|
}
|
|
|
|
printf("%6d <- %s", number, (char *)packet);
|
|
|
|
range = packet->range & 0x07;
|
|
function = packet->function & 0x0f;
|
|
|
|
re = ranges[range][function];
|
|
|
|
if ((re.divider == 0) && (re.exponent == 0)) {
|
|
printf("Invalid function/range combo: f=%x r=%x\n", function, range);
|
|
}
|
|
|
|
reading = number * pow(10.0, re.exponent - re.divider);
|
|
|
|
printf("Reading = %lf %s\n", reading, units[function_unit[function]]);
|
|
|
|
return 0;
|
|
}
|
|
|
|
void log_packet(struct packet_s *packet) {
|
|
int i;
|
|
char *c = (char *)packet;
|
|
|
|
for (i=0; i<sizeof(*packet); i++)
|
|
putc(c[i], stderr);
|
|
}
|
|
|
|
int read_packet(struct packet_s *packet) {
|
|
char ring[sizeof(*packet)];
|
|
char *p;
|
|
int ring_pos;
|
|
char c;
|
|
int ch;
|
|
int shift;
|
|
|
|
p = (char *)packet;
|
|
ring_pos = 0;
|
|
shift = sizeof(*packet);
|
|
for (;;) {
|
|
ch = getc(stdin);
|
|
if (ch == EOF)
|
|
return 0;
|
|
c = (char) ch;
|
|
ring[ring_pos] = c;
|
|
ring_pos = (ring_pos + 1) % sizeof(*packet);
|
|
if (((c & 0xf0) != 0x30) && (c != '\r') && (c != '\n')) {
|
|
shift = sizeof(*packet);
|
|
} else {
|
|
if ((c == '\r') && (shift != 2)) {
|
|
shift = sizeof(*packet);
|
|
continue;
|
|
}
|
|
if (c == '\n') {
|
|
if (shift == 1) {
|
|
for (int i=0; i<sizeof(ring); i++)
|
|
p[i] = ring[(ring_pos + i) % sizeof(*packet)];
|
|
log_packet(packet);
|
|
return 1;
|
|
}
|
|
shift = sizeof(*packet);
|
|
continue;
|
|
}
|
|
shift = (shift > 0) ? shift - 1 : 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
int main() {
|
|
struct packet_s packet;
|
|
|
|
while (read_packet(&packet)) {
|
|
parse_packet(&packet);
|
|
}
|
|
|
|
return EXIT_SUCCESS;
|
|
}
|
|
|