Discussion:
Ping Frank! C code enclosed.
(too old to reply)
Öldman©
2004-07-21 11:26:39 UTC
Permalink
Sorry I haven't got back to you for a while regarding C program.

I met with my client and discussed the issue.

They are considering using more up to date hardware, as I think
I told you earlier, this was originally put together in 94-95.
***************************************************************

Note to the casual reader of this post - have a look at the
C code in this post, it's what makes our 'toys' tick.

***************************************************************
I am confident after reviewing the C code enclosed that I am
able to change the register assignments for the updated BIOS.

I would like you to have a hard look at this to see if you
are able to improve the RPM data output of the progy.

A bit like Windoze 95, all things were not exactly what my
client wanted at the time but trade offs were made between
speed (sample rate), size and cost.

I have been researching different PLC's that are on the
market and the one that looks interesting runs Windoze CE
services or C++ or ladder logic. More on that another time.

Are you familiar with the term "moving window averaging"?

Our RPM counters need to run two different sample rates,
the first at 100 RPM and up - the second for 100 RPM and
down. The sample rate needs to be higher for the lower
RPM values to sense 'stall' on the motor under test.
The data is used to plot torque curves and stall happens
within 2 seconds from approx. 1200 RPM when load reaches
critical. We found a LOT of 'jitter' in our values due to
low sample rate and clock speed of the PLC presently used.
The 'work around' was to accumulate counts then average.
This issue was never fully resolved - I think partly due
to the programers level of expertize and partly due to
the clock speed of the PLC.

I proposed that the program be set up to accumulate counts
for X clock cycles as a 'snap shot' then average as many of
these 'snap shots' as practical due to jiffy timer to
obtain readings quickly enough. This worked well for the
higher RPM values but not for the low end (not enough plot
points to draw the curve properly).

Possible that you know a better way?
Is there a way to 'split' clock cycles (jiffies) with
software? Can we 'roll our own' timer somehow?

This issue will determine whether we keep using the
present unit or 'upgrade' the hardware!

The library:
1 vol - ANSI C Constructs and Libraries
1 vol - MCCM77 Documentation set.
1 vol - Telepace C Tools
1 vol - Telesafe Micro 16 SCADA Controller
1 vol - Smartwire System Manual

I have permission to copy required info from these manuals but I
think maybe scanning the important pages and either email or
post the scans (although you may not need them). Email has
limits for binary attachments (you will end up with a 'plugged'
in box and all other mail 'bounces'.
Had this problem when I tried to send my client all of the
AutoCad drawings for a project once.

Spec:
Processor - M37702 16 bit 14.7456 MHz clock with integrated watchdog timer.
Memory - 128 kBytes (expanded to 1 MBytes) CMOS RAM
- 64 kBytes to 2 MBytes EPROM
- 1 kBytes EEPROM (holds port configuration data)
Baud - 300 to 38400 (9600 used)
Word - 7 or 8 bits
Counter Hz- 5 kHz max. (prox. sensor used for input-1800 RPM max with 15 pulses
per revolution (used for higher resolution of motor speed which seldom hits 500
RPM)) Counters are 32 bits wide. *Configured to clear on being read by program?

Assembly language code may be included directly within C programs.
Library routines are called from operating system ROM.

The controller provides 32 software timers individually programmable for
tick rates from 10 per second (1 jiffy) to once every 25.5 seconds. All
timers operate in the background from a hardware interrupt generated from the
main system clock.

Watchdog timer trigger pulses may be generated by the user program or
by the system clock. If watchdog times out CPU is reset. Used for error
detection in system. *Check code to see if it is incorporated!

The C Tools library is an enhancement of the ANSI C in that it has
functions dedicated to this controller for IO register assignment.
eg. read_counter

Timer functions:
interval - set the tick interval in tenths of seconds
settimer - set a timer. Timers count down from set value to zero.
time - read the time period remaining in a timer.
pulse, pulse_train and timeout not used for application.

*Jiffy Clock:
setjiffy - set the jiffy clock.
jiffy - read the jiffy clock.

*resets when power applied to the controller and rolls over after 24 hours to
zero. It is real time clock.

The original programmer only used one timer. Would it not be better
if multiple timers were used?

stall = readcounter
if counter < # settimer_1 ###
if counter > # settimer_2 ###? (pardon my syntax, C programmer I'm not.

8888888888888888888888888888888888 start 8888888888888888888888888888888888888
/*****************************************************************************/
/* C language source code file for Control Microsystems MICRO16 PLC */
/* */
/* Written by Programmer */
/* Written for Customer */
/* */
/* This program below monitors a drill motor test stand, and must be compiled*/
/* along with the file FILENAME.H with the Microtech Research MCCM77 compiler*/
/*****************************************************************************/

/*****************************************************************************/
/* Conditional compilation directives */
/*****************************************************************************/

/* define DEBUG */

/*****************************************************************************/
/* global variables */
/*****************************************************************************/

struct clock now; /* real time clock structure */
struct sensors readings; /* structure containing all the sensor values */
struct scale_vals scale; /* scale values for unit conversions */

/*****************************************************************************/
/* Include files */
/*****************************************************************************/

#include "filename.h" /* #define statements for this file */
#include <stdio.h> /* Microtec compiler standard I/O header */
#include <database.h> /* TelePACE I/O database functions */
#include <iohw.h> /* TelePACE I/O hardware functions */
#include <primitiv.h> /* Real Time Operating System functions */
#include <protocol.h> /* More I/O database related functions */
#include <rtc.h> /* Real time clock functions */
#include <serial.h> /* TelePACE RS232 I/O header */

/*****************************************************************************/
/* Function Prototypes */
/*****************************************************************************/

void main (void);
void read_inputs(unsigned motorsize,unsigned timeout);
void write_dbase(int dataptr,int lasttime);
void init_serial(void);
void print_data(void);
int stalled(void);
void line_printer(void);
void write_panel_meters(void);
unsigned which_motor(void);
void flash_led(void);
void init_scale(void);

/*****************************************************************************/
/* begin function MAIN */
/*****************************************************************************/

void main (void) {

unsigned int motorsize; /* determines which motor (if any)is running */
unsigned dataptr; /* offset from start of A/O to BEGINDATA */
/* is 42000-40000= 2000 */
unsigned lasttime; /* for keeping track of loop timing */
unsigned timeout; /* equals 60/60 seconds or 1 second timing */
unsigned numloops; /* number of iterations of main loop */

/*****************************************************************************/
/* Initialization */
/*****************************************************************************/

init_scale(); /* Initialize scaling factors */
init_serial(); /* Com 1 = PRN, Com 2 = MODBUS */

fprintf(com1, "Customer Oil Drill Motor Test Stand Data\r\n");
fprintf(com1, "----------------------------------------\r\n");


/*****************************************************************************/
/* Beginning of main run time loop, 1 second or 0.1 during stall */
/*****************************************************************************/

while (TRUE) { /* run-time loop never stops */

while (!(motorsize=which_motor())) { /* Wait here for motor to start */

read_inputs(motorsize,timeout); /* read and scale input data */
write_panel_meters();
flash_led(); /* Run LED flashs if both motors stopped */
}

request_resource(IO_SYSTEM);
setdbase(MODBUS,INPROGRESS,1); /* Flag for LabVIEW indicates test on */
release_resource(IO_SYSTEM);

setjiffy(0UL); /* start 1/60 resolution clock for timing, */
lasttime=0; /* as one of the motors is now moving. */

dataptr=BEGINDATA-BEGINAOUT; /* offset from start of A/O to BEGINDATA */
/* is 42000-40000= 2000 */
timeout=60;
numloops=0;

do {
read_inputs(motorsize,timeout); /* read and scale input data */
write_dbase(dataptr,lasttime); /* write to I/O modbus database */
dataptr+=5;
if ((BEGINAOUT+dataptr)>ENDDATA) dataptr=BEGINDATA-BEGINAOUT;
/* wrap dataptr if overflow */

if (stalled()){ /* if stalled, loop time is 1/10 seconds */
timeout=12;
if (!(numloops%5)) {
line_printer(); /* only print and write meters on 5th passes */
write_panel_meters();
}
}
else {
timeout=60; /* if not stalled, loop time is 1 second */
line_printer(); /* so print every second (if required */
write_panel_meters();
}
lasttime=lasttime+timeout; /* time to wait to is advanced */
numloops++;

while (((jiffy()-lasttime)/timeout)>0)
; /* wait till timeout for cycle, 0.2 or 1.0 seconds */
}
while(readings.rpm > STOPPED); /* must be at least moving to read data */

request_resource(IO_SYSTEM);
setdbase(MODBUS,INPROGRESS,0); /* Flag for LabVIEW indicates test off */
release_resource(IO_SYSTEM);

} /* Drop out at end of test (motor stopped) , main loop never stops */


} /* end main (never exits) */

/*****************************************************************************/
/* init_scale <Customer.C> */
/* */
/* SYNTAX: init_scale (void); */
/* */
/* DESCRIPTION: Loads default values to I/O database only if examining */
/* the optionswitch 1 is true. This prevents LabVIEW from updating constant
*/
/* values and then having them reset to defaults. */
/* */
/* RETURN VALUE: None. */
/* */
/* */
/*****************************************************************************/

void init_scale(void) {

if (optionSwitch(OPEN)) { /* if switch is open copy default values */

scale.flow=FLOWSCALE; /* FLOW scale from counts - numeric val */
scale.rpmlarge=RPMLARGESCALE/1000.0;
scale.rpmsmall=RPMSMALLSCALE/1000.0; /* " "
*/
scale.pressure=PRESSURESCALE/1000.0;
scale.torquelarge=TORQUELARGESCALE/1000.0;
scale.torquesmall=TORQUESMALLSCALE/1000.0;
scale.stallrpm=STALLRPM;
}

else { /* if switch 1 is off, copy values from I/O database */

request_resource(IO_SYSTEM);
scale.flow=dbase(MODBUS,FLOWSCALEADDRESS);
scale.rpmlarge=dbase(MODBUS,RPMLARGESCALEADDRESS)/1000.0;
scale.rpmsmall=dbase(MODBUS,RPMSMALLSCALEADDRESS)/1000.0;
scale.pressure=dbase(MODBUS,PRESSURESCALEADDRESS)/1000.0;
scale.torquelarge=dbase(MODBUS,TORQUELARGESCALEADDRESS)/1000.0;
scale.torquesmall=dbase(MODBUS,TORQUESMALLSCALEADDRESS)/1000.0;
scale.stallrpm=dbase(MODBUS,STALLRPMADDRESS);
release_resource(IO_SYSTEM);
}
}
/*****************************************************************************/
/* read_inputs <Customer.C> */
/* */
/* SYNTAX: read_inputs(unsigned in motorsize); */
/* */
/* DESCRIPTION: This function reads and scales inputs to standard units */
/* */
/* */
/* RETURN VALUE: None. */
/* */
/* */
/*****************************************************************************/

void read_inputs(unsigned motorsize,unsigned etime){

request_resource(IO_SYSTEM);

readings.flow=readCounter(INFLOW,READCOUNTER) * scale.flow * 60 / etime;
readCounter(INFLOW,CLEARCOUNTER);

readings.pressure=ain(INPRESSURE) * scale.pressure;

if (motorsize==LARGEON){ /* read torque/rpm depending on motor */
readings.torque=ain(INTORQUELARGE) * scale.torquelarge;
readings.rpm=readCounter(INRPMLARGE,READCOUNTER) * scale.rpmlarge * 60 /
etime;
readCounter(INRPMLARGE,CLEARCOUNTER);
}

else {
readings.torque=ain(INTORQUESMALL) * scale.torquesmall;
readings.rpm=readCounter(INRPMSMALL,READCOUNTER) * scale.rpmsmall * 60 /
etime;
readCounter(INRPMSMALL,CLEARCOUNTER);
}

release_resource(IO_SYSTEM);


} /* end read_inputs */

/*****************************************************************************/
/* which_motor <Customer.C> */
/* */
/* SYNTAX: unsigned which_motor(void); */
/* */
/* DESCRIPTION: This function is used to detect which motor is running by */
/* reading the RPM counters. This function executes in one second. This */
/* time is required to allow counters to accumulate */
/* */
/* RETURN VALUE: OFF = No motors running */
/* LARGEON = Large motor running */
/* SMALLON = Small motor running */
/* */
/*****************************************************************************/
unsigned which_motor(void) {

interval(0,1); /* set timer 0 for 10 hz tick rate */

request_resource(IO_SYSTEM);

readCounter (INFLOW,CLEARCOUNTER); /* Clear counters to zero */
readCounter (INRPMLARGE,CLEARCOUNTER);
readCounter (INRPMSMALL,CLEARCOUNTER); /* Clear counters to zero */

release_resource(IO_SYSTEM);

settimer(0,10); /* set timer for 1 second */
while (timer(0))
; /* wait for 1 second timer to expire */

if (readCounter (INRPMLARGE,READCOUNTER) > 5) { /* large-16RPM,small-40RPM*/
/* request_resource(IO_SYSTEM);
dout(DOUT_START,LARGELAMP); -- 5409 digital output (not specified)--
release_resource(IO_SYSTEM); leave in in case later requested */
return (LARGEON) ;
}
if (readCounter (INRPMSMALL,READCOUNTER) > 5) {
/* request_resource(IO_SYSTEM);
dout(DOUT_START,SMALLLAMP);
release_resource(IO_SYSTEM); */
return (SMALLON) ;
}

else {
/* request_resource(IO_SYSTEM);
dout(DOUT_START,NOLAMP);
release_resource(IO_SYSTEM); */
return (OFF);
}

} /* end which_motor */


/*****************************************************************************/
/* write_dbase <Customer.C> */
/* */
/* SYNTAX: void write_dbase(dataptr); */
/* */
/* DESCRIPTION: write out data to the I/o MODBUS accessible database. */
/* Data is inserted at address offset dataptr, and the offset */
/* address is written to address LASTVALUE in IO database so */
/* that LabVIEW program can query PLC on where data is. */
/* */
/* RETURN VALUE: None. */
/* */
/*****************************************************************************/

void write_dbase(int dataptr,int lasttime) {

request_resource(IO_SYSTEM);

setdbase(MODBUS,BEGINAOUT+dataptr,readings.rpm); /* write sensor vals */
setdbase(MODBUS,BEGINAOUT+dataptr+1,readings.torque);
setdbase(MODBUS,BEGINAOUT+dataptr+2,readings.flow);
setdbase(MODBUS,BEGINAOUT+dataptr+3,readings.pressure);
setdbase(MODBUS,BEGINAOUT+dataptr+4,lasttime/6); /* write time in .1 sec */
setdbase(MODBUS,LASTVALUE,dataptr); /* update lastvalue register */

release_resource(IO_SYSTEM);

}


/*****************************************************************************/
/* flash_led <Customer.C> */
/* */
/* SYNTAX: void flash_led(void); */
/* */
/* DESCRIPTION: flashes an LED to indicate the PLC is waiting for a motor */
/* to start up */
/* */
/* RETURN VALUE: None. */
/* */
/*****************************************************************************/


void flash_led(void) {

request_resource(IO_SYSTEM);
now=getclock();
release_resource(IO_SYSTEM);

if (now.second%2) runLed(LED_ON);
else runLed(LED_OFF);

}



/*****************************************************************************/
/* stalled <Customer.C> */
/* */
/* SYNTAX: int stalled(void); */
/* */
/* DESCRIPTION: This function checks to see if motor is in stall condition */
/* */
/* */
/* RETURN VALUE: TRUE if stalled, else FALSE */
/* */
/* */
/*****************************************************************************/

int stalled (void){

if (readings.rpm < scale.stallrpm)
return (TRUE);

return(FALSE);

}


/*****************************************************************************/
/* write_panel_meters <Customer.C> */
/* */
/* SYNTAX: write_panel_meters(void); */
/* */
/* DESCRIPTION: Write out to the four analog output meters via the model 5301*/
/* micro16 modules. The module is a 0-20mA output, requireing a 500 ohm */
/* load resistor to deliver 0-10 volt output. 10 volts reads 19999 on meter */
/* */
/* RETURN VALUE: none */
/* */
/* */
/*****************************************************************************/

void write_panel_meters(void) {


aout(OUTTORQUE,readings.torque);
aout(OUTPRESSURE,readings.pressure * 10.0);
aout(OUTFLOW,readings.flow *37.0 );
aout(OUTRPM,readings.rpm * scale.meter * 17.0);
}

/*****************************************************************************/
/* line_printer <Customer.C> */
/* */
/* SYNTAX: void line_printer(void); */
/* */
/* DESCRIPTION: Data is written to line printer on interrupt switch keypress */
/* or if the print switch has been depressed for three seconds (count 120 on */
/* the jiffy() clock plus 1 loop. Switch logic is performed in this function,*/
/* print_data is a separate function that does the printing, if necessary */
/* */
/* RETURN VALUE: none. */
/* */
/* */
/*****************************************************************************/

void line_printer(void){

static unsigned lockstate; /* is printing locked on via interrupt */
static unsigned long last_switchoff; /* last time in no_switch, no PRINTLOCK */
unsigned switchon; /* results of reading interrupt switch */


switchon=interruptInput(); /* read switch input */


if (!switchon) { /* if switch is OFF */
last_switchoff=jiffy(); /* mark the last time its off */
if (lockstate) print_data(); /* print if we are in lock state */
return;
}
else { /* if switch is ON */
print_data(); /* print the data */
if (!lockstate) { /* if we are not locked and */
if ((jiffy()-last_switchoff)>180) { /* if not recently off, lock on */
lockstate=TRUE;
return;
}
}

else { /* switch is ON, lockstate ON */
if ((jiffy()-last_switchoff)<180) /* if not recently off, lock off */
lockstate=FALSE;
}
}

} /* end line_printer */

/*****************************************************************************/
/* print_data <Customer.C> */
/* */
/* SYNTAX: void print_data(void); */
/* */
/* DESCRIPTION: This function writes an ascii string out to a line printer */
/* containing all the data scaled from sensors. Data format is: */
/* */
/* YEAR:MONTH:DAY:HOUR:MINUTE:SECOND :RPM:TORQUE:FLOW:PRESSURE <CR><LF> */
/* */
/* Note that real time clock must be reset if necessary by labVIEW (or */
/* remain in standard/daylight saving time) Clock handles leap-years. */
/* */
/* RETURN VALUE: none. */
/* */
/* */
/*****************************************************************************/

void print_data(void) {


now=getclock(); /* update structure "now" with real time clock values */

fprintf(com1, "%2d/%2d - ",now.month,now.day); /* print date */
fprintf(com1, "%2d:%02d:%02d ",now.hour,now.minute,now.second);/* and time
*/

fprintf(com1, "RPM:%4d TORQUE:%4d FLOW:%4d PRESSURE:%4d\r\n",readings.rpm,
readings.torque,readings.flow,readings.pressure);


}

/*****************************************************************************/
/* init_serial <Customer.C> */
/* */
/* SYNTAX: void init_serial(void); */
/* */
/* DESCRIPTION: Sets up conditions for writing straight ASCII to com1 and */
/* MODBUS to com2 */
/* */
/* RETURN VALUE: none. */
/* */
/* */
/*****************************************************************************/

void init_serial(void) {

struct prot_settings settings;
struct pconfig lineconfig;

lineconfig.baud=BAUD9600;
lineconfig.duplex=FULL;
lineconfig.parity=NONE;
lineconfig.data_bits=DATA8;
lineconfig.stop_bits=STOP1;
lineconfig.flow_rx=DISABLE;
lineconfig.flow_tx=DISABLE;
lineconfig.type=RS232;
lineconfig.timeout=600;

set_port(com1,&lineconfig); /* set up printer port line config */


set_port(com2,&lineconfig); /* set up labVIEW port */

/* Disable the protocol on serial port 1 -line printer output */
settings.type = NO_PROTOCOL;
set_protocol(com1, &settings);

/* Enable MODBUS protocol on serial port 2 -LabVIEW /download interface */
settings.type = MODBUS_RTU;
settings.station = 1; /* station address - BusVIEW calls slave address */
settings.priority = 3;
settings.SFMessaging = FALSE;
set_protocol(com2, &settings);
}



8888888888888888888888888888888888888 eof 888888888888888888888888888888888888

/*****************************************************************************/
/* Customer oil PLC program header file */
/* Contains constants and prototypes for functions in Customer.c */
/*****************************************************************************/

/*****************************************************************************/
/* Input signals from ANALOG INPUTS and COUNTERS */
/* */
/* Small motor RPM, counter 0, has I/O database address 10193 */
/* Large motor RPM, counter 1, has I/O database address 10194 */
/* Flow, counter 2, has I/O database address 10195 */
/* Small motor Torque, analog input 0, has I/O database address 30001 */
/* Large motor Torque, analog input 1, has I/O database address 30002 */
/* Pressure, analog input 2, has I/O database address 30003 */
/* */
/* Note that MODBUS accessible I/O database addresses above are raw values */
/* LabVIEW program should read the scaled output values in the I/O database */
/* */
/*****************************************************************************/

#define INRPMSMALL 0 /* COUNTER # 0 ON CPU BOARD */
#define INRPMLARGE 1 /* COUNTER # 1 ON CPU BOARD */
#define INFLOW 2 /* COUNTER # 2 ON CPU BOARD */
#define INTORQUESMALL 0 /* ANALOG INPUT 0 ON A/D BOARD */
#define INTORQUELARGE 1 /* ANALOG INPUT 1 ON A/D BOARD */
#define INPRESSURE 2 /* ANALOG INPUT 2 ON A/D BOARD */

/*****************************************************************************/
/* Output signals for PANEL METERS */
/* */
/* Scaled output torque, analog out 0, has I/O database address 40001 */
/* Scaled output pressure, analog out 1, has I/O database address 40002 */
/* Scaled output flow, analog out 2, has I/O database address 40003 */
/* Scaled output rpm, analog out 3, has I/O database address 40004 */
/* */
/* Note that MODBUS accessible I/O database addresses above are scaled for */
/* writing to 0-10 volt panel meters only. */
/* LabVIEW program should read the scaled output values in the I/O database */
/* */
/*****************************************************************************/

#define OUTTORQUE AOUT_START /* OUTPUT 0 OF ANALOG OUT BASE ADDRESS 0
*/
#define OUTPRESSURE AOUT_START+1 /* OUTPUT 1 OF ANALOG OUT BASE ADDRESS 0 */
#define OUTFLOW AOUT_START+2 /* OUTPUT 0 OF ANALOG OUT BASE ADDRESS 2 */
#define OUTRPM AOUT_START+3 /* OUTPUT 1 OF ANALOG OUT BASE ADDRESS 2
*/

/*****************************************************************************/
/* Digital outs are not being used; leave in in case added later */
/*****************************************************************************/

#define LARGELAMP 2 /* BIT 1 OF DIGITAL OUT BOARD BASE ADDRESS 0 */
#define SMALLLAMP 1 /* BIT 0 OF DIGITAL OUT BOARD " " " */
#define NOLAMP 0


/*****************************************************************************/
/* Output data for MODBUS (LabVIEW program addressable) */
/* These are scaled 16 bit unsigned values */
/* */
/*****************************************************************************/

#define INPROGRESS 41998 /* Address of "test running flag for LabVIEW */

#define LASTVALUE 41999 /* This location contains a pointer offset from*/
/* BEGINDATA to where the last data value has */
/* been written */

#define BEGINDATA 42000 /* BEGINNING OF LabVIEW data transfer area */
/* by moving a pointer, we can keep history. */
/* but this is not implemented yet. */

#define BEGINAOUT 40000 /* Analog output area starts at 40000, but the */
/* Modbus addresses this as relative address 0 */
/* NOTE: not documented in Micro16 manual. */

#define ENDDATA 49995 /* end of data transfer area */

#define BEGINSCALE 41712 /* BEGINNING OF scaling constant data xfer area*/
#define ENDSCALE BEGINSCALE+7

/*****************************************************************************/
/* Scaling constants - This may end up changing during install ... */
/* */
/* RPM: true rpm = counter output / PULSESPERREV (15) */
/* No calibration should ever be needed on RPM measurement */
/* Large motor prox. sensor is geared down by 750/450 = 1.67 RPM/count */
/* Small motor prox. sensor is geared down by 1800/450= 4 RPM/count */
/* Elapsed time will be .2 or 1.0 depending on if in stall */
/* These scaling factors have been fully tested */
/* Note: RPM wont go over 19999 so there is no risk of overflow */
/* */
/* FLOW: 12Hz. pulses = 446GPM = 1688LPM */
/* litres per second per pulse = 1688/12=141 litres/sec/pulse */
/* Calibration constant will be needed for liner size */
/* This liner_size constant can be updated by LabVIEW program through dbase */
/* Elapsed time will be .2 or 1.0 depending on if in stall */
/* These scaling factors have been fully tested */
/* Note: flow wont go over 19999 lps so there is no risk of overflow */
/* */
/* */
/* TORQUE: 0-20 mA signal -> 0 to 32768 binary */
/* Large motor full scale =37280 lbft * 1.356 = 50551 NM = 32768 binary */
/* Small motor full scale =4167 lbft * 1.356 = 5650 NM = 32768 " */
/* full a/d 12 bit binary output is 32768 */
/* Large motor scaling factor is 50551/32768=1.543 NM/bit */
/* Small " " " " 5650 /32768=0.1724 */
/* */
/* NOTE: THIS IS TESTED, BUT OVERFLOW WILL RESULT ON LARGE MOTOR TORQUE */
/* IF TORQUES OVER 19999 NM - THE SCALING MAY HAVE TO BE CHANGED BY 10 X IF */
/* LARGER TORQUES ARE GENERATED, AND A DIGIT DROPPED ON THE DISPLAY. */
/* */
/* PRESSURE: 4-20 mA signal -> 0 to 32768 binary */
/* full scale = 3000 PSI = 3000 * 6.8948 = 20684KPa */
/* full a/d 12 bit binary output is 32768 */
/* scaling factor = 20684/32768=.6312 KPa/bit */
/* */
/* NOTE: THIS IS TESTED, BUT OVERFLOW WILL RESULT IF PRESSURE EXCEEDS */
/* 19999 KPa - THE SCALING MAY HAVE TO BE CHANGED BY 10 x IF LARGER */
/* PRESSURES ARE GENERATED, AND A DIGIT DROPPED ON THE DISPLAY */
/* */
/* METER SCALING: */
/* Analog out is 0-20mA range. Use 500 ohm terminator to get 0-10 volts for */
/* the meter. (there is a 4-20mA switch - ensure it is set for 0-20mA) */
/* Scaling takes place in init_scale in customer.c */
/* */
/*****************************************************************************/

#define FLOWSCALE 141
#define RPMLARGESCALE 1667
#define RPMSMALLSCALE 4000
#define PRESSURESCALE 631
#define TORQUELARGESCALE 1543
#define TORQUESMALLSCALE 172

#define STALLRPM 100 /* stall speed */


/*****************************************************************************/
/* I/O database addresses of scaling constants */
/*****************************************************************************/

#define FLOWSCALEADDRESS BEGINSCALE + 0 /* I/O addresses of above */
#define RPMLARGESCALEADDRESS BEGINSCALE + 1
#define RPMSMALLSCALEADDRESS BEGINSCALE + 2
#define PRESSURESCALEADDRESS BEGINSCALE + 3
#define TORQUELARGESCALEADDRESS BEGINSCALE + 4
#define TORQUESMALLSCALEADDRESS BEGINSCALE + 5

#define STALLRPMADDRESS BEGINSCALE + 6
#define SCALETOMETERADDRESS BEGINSCALE + 7

#define WORKCONVERT 0.737 /* N-M to lb-ft CONVERSION FACTOR */
#define PRESSURECONVERT 0.145 /* KPA to PSI CONVERSION */
#define FLOWCONVERT 0.264 /* LPM to GPM CONVERSION */


/*****************************************************************************/
/* Other constants */
/*****************************************************************************/

#define TRUE 1
#define FALSE 0

#define LARGEON 2 /* motor selector */
#define SMALLON 1
#define OFF 0

#define CLEARCOUNTER 1 /* CLEAR COUNTER TO ZERO */
#define READCOUNTER 0 /* GET COUNTER READING */

#define STOPPED 0

#define PRINTLOCK 1 /* FLAG THAT PRINTER IS TO RUN CONTINUOUS */
#define PRINTUNLOCK 0 /* FLAG THAT PRINTER IS NOT TO RUN CONTINUOUS */


/*****************************************************************************/
/* templates */
/*****************************************************************************/

struct sensors {
unsigned rpm; /* RPM of the running motor */
unsigned torque; /* TORQUE of the running motor */
unsigned flow; /* FLOW (common to both motors) */
unsigned pressure; /* PRESSURE (common to both motors) */
};

struct scale_vals {

float flow; /* FLOW scaling from counts to numeric value */
float rpmlarge; /* we need variables, since the PLC has to read */
float rpmsmall; /* values from either default or LabVIEW program. */
float pressure; /* These scale values corrispond to the default */
float torquelarge; /* values listed above under scaling constants */
float torquesmall;
unsigned stallrpm;
float meter;
};










































8888888888888888888888888888 eof 888888888888888888888888888888888888888888
Error noted in Torque section of customer.h - should be 4-20 ma not 0-20.

rpm determination:

15 counts per revolution @ 1800 rpm/60 seconds per minute = 450 Hz full scale
(32768 binary)
Full scale = 10 vdc @ analog output module therefor 1 vdc = 45 Hz (3276.8
binary)

In addition we use a file called 'scaling.txt' which is loaded to the PLC
via Labview application to update scaling constants for each set up. These
over ride the defaults which are there so program doesn't crash initially.

Further - I think the stall RPM=100 is to high for the small motor.
I think we need:
#define small_stall=<50
#define large_stall=<100
???


So there it is. Give me a cost estimate to modify please.


_ _

Sometimes, something or someone - or maybe another person!
_________________________________
Frank McCoy
2004-07-21 23:44:09 UTC
Permalink
Post by Öldman©
Are you familiar with the term "moving window averaging"?
Quite familiar; having done similar things named "impossible" on the
old PTS with just one counter that worked somewhat like you described.
Of course, Windows complicated things a bit by being asynchronous; and
you having several free-running counters (as I see it).
Post by Öldman©
Our RPM counters need to run two different sample rates,
the first at 100 RPM and up - the second for 100 RPM and
down. The sample rate needs to be higher for the lower
RPM values to sense 'stall' on the motor under test.
The data is used to plot torque curves and stall happens
within 2 seconds from approx. 1200 RPM when load reaches
critical. We found a LOT of 'jitter' in our values due to
low sample rate and clock speed of the PLC presently used.
The 'work around' was to accumulate counts then average.
This issue was never fully resolved - I think partly due
to the programers level of expertize and partly due to
the clock speed of the PLC.
If done *right* then the low speed becomes an *advantage* not a
disadvantage; and can make for greater accuracy. The trick is to
count both clock-ticks and rpm pulses close to the limit of the time
you have; the lower-frequency of the two being used as the thing-timed
and methods used to ensure it's accuracy; while the faster-counting
tick is used to measure the slower; then dividing the two.

In a Windows environment, this often means doing a "no no" and halting
interrupts while the start of a tick is found and measured then
allowing them once the faster counter's position is known; then
repeating the process at the end of an interval. For true accuracy,
both counters should be free-running; NOT stopped and restarted; with
each successive measurement taking in the difference from the previous
count. If a high-frequency and fairly accurate clock-counter is
available, then the overall accuracy can be quite good, even measuring
only single snapshots. By doing things like running averages, even
more accuracy can be obtained; gaining somewhere around half the
totals averaged times the original.

That's: If one interval gives you accuracy of plus or minus ten
counts, then averaging ten intervals will give you an accuracy of
about plus or minus two counts for a single interval, or plus or minus
about 20 counts for the total: A five to one improvement. (Yeah, I
know ... It *should* work out to a ten-to-one improvement; but rarely
does.)

One trick many people often miss is scaling:
You scale the larger number to fit the smaller, or the smaller number
to fit the larger, until you get maximum accuracy for your upcoming
division; then adjusting the result back to compensate once the
division is done. If using floating-point, this isn't so important;
but when sticking to straight digits for speed, it can make enormous
differences in the accuracy. Oftentimes using floating-point for
divides takes up more time between measurements than you have
available.
Post by Öldman©
I proposed that the program be set up to accumulate counts
for X clock cycles as a 'snap shot' then average as many of
these 'snap shots' as practical due to jiffy timer to
obtain readings quickly enough. This worked well for the
higher RPM values but not for the low end (not enough plot
points to draw the curve properly).
Possible that you know a better way?
Is there a way to 'split' clock cycles (jiffies) with
software? Can we 'roll our own' timer somehow?
Generally, on a Windows System, the system clock is the best you've
got ... and it sucks rocks royally! I've used it though; and it does
work. Better, is if you can have an independent timer.

Seems to me, I remember Windows (and DOS) having available either one
or two timers on board the PC, that were (supposedly) available to the
programmer; and LEFT so. The problem being: Some *other* programmer
running a program on the PC might well have decided he/she needed them
already ... and thus interfering with your usage. ;-{

Best would be a free-running and readable clock on the hardware
itself, if possible. The higher the frequency of the counter, and the
longer the counter length, the better. Otherwise, we're stuck with
the system clock. ;-{
Post by Öldman©
This issue will determine whether we keep using the
present unit or 'upgrade' the hardware!
The only problem I see with doing this, is running tests on the actual
hardware so I could see what results I got when taking measurements.
The actual programming itself seems to be a minimal design problem.

On the program itself:
Um ... First, I'd need the "defines" or *.h files.

Mostly (I assume) because of the missing *.h files,
Compiling the source gives me the following errors:

Error counter.c 21: Undefined structure 'clock'
Error counter.c 21: Size of structure or array not known
Error counter.c 22: Undefined structure 'sensors'
Error counter.c 22: Size of structure or array not known
Error counter.c 23: Undefined structure 'scale_vals'
Error counter.c 23: Size of structure or array not known
Error counter.c 29: Unable to open include file 'filename.h'
Error counter.c 31: Unable to open include file 'database.h'
Error counter.c 32: Unable to open include file 'iohw.h'
Error counter.c 33: Unable to open include file 'primitiv.h'
Error counter.c 34: Unable to open include file 'protocol.h'
Error counter.c 35: Unable to open include file 'rtc.h'
Error counter.c 36: Unable to open include file 'serial.h'
Error counter.c 74: Undefined symbol 'com1' in function main
Warning counter.c 74: Non-portable pointer conversion in function main
Warning counter.c 75: Non-portable pointer conversion in function main
Error counter.c 82: Undefined symbol 'TRUE' in function main
Warning counter.c 84: Possibly incorrect assignment in function main
Warning counter.c 86: Possible use of 'timeout' before definition in
function main
Error counter.c 91: Undefined symbol 'IO_SYSTEM' in function main
Error counter.c 92: Undefined symbol 'MODBUS' in function main
Error counter.c 92: Undefined symbol 'INPROGRESS' in function main
Error counter.c 98: Undefined symbol 'BEGINDATA' in function main
Error counter.c 98: Undefined symbol 'BEGINAOUT' in function main
Error counter.c 107: Undefined symbol 'ENDDATA' in function main
Error counter.c 128: Undefined symbol 'rpm' in function main
Error counter.c 128: Undefined symbol 'STOPPED' in function main
Error counter.c 156: Undefined symbol 'OPEN' in function init_scale
Error counter.c 158: Undefined symbol 'flow' in function init_scale
Error counter.c 158: Too many error or warning messages in function
init_scale
*** 25 errors in Compile ***

Available memory 396496
--
_____
/ ' / ™
,-/-, __ __. ____ /_
(_/ / (_(_/|_/ / <_/ <_
Öldman©
2004-07-22 13:22:08 UTC
Permalink
On Wed, 21 Jul 2004 18:44:09 -0500,Frank McCoy's cat ran across
the 'puter keyboard and out came...
} In alt.fan.frank.mccoy �ldman© <***@ld.is.best> wrote:
}
} >Are you familiar with the term "moving window averaging"?
} >
} Quite familiar; having done similar things named "impossible" on the
} old PTS with just one counter that worked somewhat like you described.
} Of course, Windows complicated things a bit by being asynchronous; and
} you having several free-running counters (as I see it).
}

<snip>

To avoid misunderstanding - the program is not running in a windoze environment.

Re: specs supplied for CPU

If you like I can give you the C Tools so you can play with the compiler.

Don't try to run the .cmd file output, windoze most likely will become
really upset with you and turn your PC into a paper wight.

Check the froup where I did the "test" post. I am unable to post even
attachments to this froup.
--
Sometimes, something or someone - maybe!
_________________________________
Frank McCoy
2004-07-22 17:35:56 UTC
Permalink
Post by Öldman©
On Wed, 21 Jul 2004 18:44:09 -0500,Frank McCoy's cat ran across
the 'puter keyboard and out came...
}
} >Are you familiar with the term "moving window averaging"?
} >
} Quite familiar; having done similar things named "impossible" on the
} old PTS with just one counter that worked somewhat like you described.
} Of course, Windows complicated things a bit by being asynchronous; and
} you having several free-running counters (as I see it).
}
<snip>
To avoid misunderstanding - the program is not running in a windoze environment.
Re: specs supplied for CPU
Oh ... Not DOS, either, I gather?.
From your wording, I figure somebody wrote a 'C' compiler for the
board itself; or used a standard compiler to run an 8086-type clone
(or upward-compatible) on the same board, with defines for the I/O?

Then will have to use available on-board timers, if that's the case.
Would need specs on timers on the board, I guess. Somehow I got the
impression that the "standard" PC clock of 14.7 mhz was available.

I'll have to look through the defines files I guess, and see what's
there to play with.
Post by Öldman©
If you like I can give you the C Tools so you can play with the compiler.
Don't try to run the .cmd file output, windoze most likely will become
really upset with you and turn your PC into a paper wight.
Not likely. Would most likely just not run and hang, waiting for
something to happen that never would.
Post by Öldman©
Check the froup where I did the "test" post. I am unable to post even
attachments to this froup.
I got it.
--
_____
/ ' / ™
,-/-, __ __. ____ /_
(_/ / (_(_/|_/ / <_/ <_
Frank McCoy
2004-07-23 01:21:45 UTC
Permalink
Post by Öldman©
On Wed, 21 Jul 2004 18:44:09 -0500,Frank McCoy's cat ran across
the 'puter keyboard and out came...
}
} >Are you familiar with the term "moving window averaging"?
} >
} Quite familiar; having done similar things named "impossible" on the
} old PTS with just one counter that worked somewhat like you described.
} Of course, Windows complicated things a bit by being asynchronous; and
} you having several free-running counters (as I see it).
}
<snip>
To avoid misunderstanding - the program is not running in a windoze environment.
Re: specs supplied for CPU
If you like I can give you the C Tools so you can play with the compiler.
Don't try to run the .cmd file output, windoze most likely will become
really upset with you and turn your PC into a paper wight.
Check the froup where I did the "test" post. I am unable to post even
attachments to this froup.
Um ... Tried compiling.
Still missing all the *.h include files for the 'C' source.
Well ... all the ones that aren't standard like stdio.h and such.
--
_____
/ ' / ™
,-/-, __ __. ____ /_
(_/ / (_(_/|_/ / <_/ <_
Öldman©
2004-07-23 06:01:09 UTC
Permalink
On Thu, 22 Jul 2004 20:21:45 -0500,Frank McCoy's cat ran across
the 'puter keyboard and out came...
} In alt.fan.frank.mccoy �ldman© <***@ld.is.best> wrote:
}
} >On Wed, 21 Jul 2004 18:44:09 -0500,Frank McCoy's cat ran across
} >the 'puter keyboard and out came...
} >} In alt.fan.frank.mccoy �?ldman�© <***@ld.is.best> wrote:
} >}
} >} >Are you familiar with the term "moving window averaging"?
} >} >
} >} Quite familiar; having done similar things named "impossible" on the
} >} old PTS with just one counter that worked somewhat like you described.
} >} Of course, Windows complicated things a bit by being asynchronous; and
} >} you having several free-running counters (as I see it).
} >}
} >
} ><snip>
} >
} >To avoid misunderstanding - the program is not running in a windoze environment.
} >
} >Re: specs supplied for CPU
} >
} >If you like I can give you the C Tools so you can play with the compiler.
} >
} >Don't try to run the .cmd file output, windoze most likely will become
} >really upset with you and turn your PC into a paper wight.
} >
} >Check the froup where I did the "test" post. I am unable to post even
} >attachments to this froup.
}
} Um ... Tried compiling.
} Still missing all the *.h include files for the 'C' source.
} Well ... all the ones that aren't standard like stdio.h and such.
}
}
There are 2 zips that I upped - one is 44k and the other
is 11k. the file that is 11k has the header files that are the
none standard dedicated for this CPU.
--
It is said that wisdom comes with age
--so why am I not very, very wise?
Öldman©
Frank McCoy
2004-07-23 16:31:47 UTC
Permalink
Post by Öldman©
There are 2 zips that I upped - one is 44k and the other
is 11k. the file that is 11k has the header files that are the
none standard dedicated for this CPU.
Um ... All I got was *one* BIG zip file that was some kind of
installer.
481K big.

BTW: You should warn a guy before sending executables!

I ran the installation (once I figured it had to be installed from a
directory labeled "DISK1" to keep from crashing); and it created a
bunch of stuff, including *most* of the needed *.h files.

However, still missing, is the "filename.h" file.
Encountered a slight difference in compilers, where structures were
being done before the call to the include file that defined them; and
that was a no-no to my compiler. However, that was an easy fix; just
moving the global definitions after the include files.

However, can't go any further without the filename.h definitions.
--
_____
/ ' / ™
,-/-, __ __. ____ /_
(_/ / (_(_/|_/ / <_/ <_
Öldman©
2004-07-23 17:40:58 UTC
Permalink
On Fri, 23 Jul 2004 11:31:47 -0500,Frank McCoy's cat ran across
the 'puter keyboard and out came...
} In alt.fan.frank.mccoy �ldman© <***@ld.is.best> wrote:
}
} >There are 2 zips that I upped - one is 44k and the other
} >is 11k. the file that is 11k has the header files that are the
} >none standard dedicated for this CPU.
}
} Um ... All I got was *one* BIG zip file that was some kind of
} installer.
} 481K big.
}
} BTW: You should warn a guy before sending executables!
}
} I ran the installation (once I figured it had to be installed from a
} directory labeled "DISK1" to keep from crashing); and it created a
} bunch of stuff, including *most* of the needed *.h files.
}
} However, still missing, is the "filename.h" file.
} Encountered a slight difference in compilers, where structures were
} being done before the call to the include file that defined them; and
} that was a no-no to my compiler. However, that was an easy fix; just
} moving the global definitions after the include files.
}
} However, can't go any further without the filename.h definitions.
}
}
the file you refer to was PART of the original post of
the C code.

I marked the two files with a comment bof and eof and a line of 8's

you need to copy them individually into notepad and create the TWO
files "customer.c" and "filename.h".

Which compiler are you using?

The included complier in the zipped file "Microtec C Tools" is the
only one that is going to work with these source files.

Look at my post of the C Tools again- both are on my server.
--
It is said that wisdom comes with age
--so why am I not very, very wise?
Öldman©
Frank McCoy
2004-07-24 03:34:39 UTC
Permalink
Post by Öldman©
On Fri, 23 Jul 2004 11:31:47 -0500,Frank McCoy's cat ran across
the 'puter keyboard and out came...
}
} >There are 2 zips that I upped - one is 44k and the other
} >is 11k. the file that is 11k has the header files that are the
} >none standard dedicated for this CPU.
}
} Um ... All I got was *one* BIG zip file that was some kind of
} installer.
} 481K big.
}
} BTW: You should warn a guy before sending executables!
}
} I ran the installation (once I figured it had to be installed from a
} directory labeled "DISK1" to keep from crashing); and it created a
} bunch of stuff, including *most* of the needed *.h files.
}
} However, still missing, is the "filename.h" file.
} Encountered a slight difference in compilers, where structures were
} being done before the call to the include file that defined them; and
} that was a no-no to my compiler. However, that was an easy fix; just
} moving the global definitions after the include files.
}
} However, can't go any further without the filename.h definitions.
}
}
the file you refer to was PART of the original post of
the C code.
I marked the two files with a comment bof and eof and a line of 8's
you need to copy them individually into notepad and create the TWO
files "customer.c" and "filename.h".
Oh ... Just did the customer.c (named it counter.c)
I'll check the split ... tomorrow.
Post by Öldman©
Which compiler are you using?
Borlund 2.0
Post by Öldman©
The included complier in the zipped file "Microtec C Tools" is the
only one that is going to work with these source files.
Look at my post of the C Tools again- both are on my server.
Like I said, I only got one zip file here.
It was labeled "C tools v2.29,zip"
--
_____
/ ' / ™
,-/-, __ __. ____ /_
(_/ / (_(_/|_/ / <_/ <_
Öldman©
2004-07-24 16:00:47 UTC
Permalink
On Fri, 23 Jul 2004 22:34:39 -0500,Frank McCoy's cat ran across
the 'puter keyboard and out came...
} In alt.fan.frank.mccoy �ldman© <***@ld.is.best> wrote:
}
} >On Fri, 23 Jul 2004 11:31:47 -0500,Frank McCoy's cat ran across
} >the 'puter keyboard and out came...
} >} In alt.fan.frank.mccoy �?ldman�© <***@ld.is.best> wrote:
} >}
} >} >There are 2 zips that I upped - one is 44k and the other
} >} >is 11k. the file that is 11k has the header files that are the
} >} >none standard dedicated for this CPU.
} >}
} >} Um ... All I got was *one* BIG zip file that was some kind of
} >} installer.
} >} 481K big.
} >}
} >} BTW: You should warn a guy before sending executables!
} >}
} >} I ran the installation (once I figured it had to be installed from a
} >} directory labeled "DISK1" to keep from crashing); and it created a
} >} bunch of stuff, including *most* of the needed *.h files.
} >}
} >} However, still missing, is the "filename.h" file.
} >} Encountered a slight difference in compilers, where structures were
} >} being done before the call to the include file that defined them; and
} >} that was a no-no to my compiler. However, that was an easy fix; just
} >} moving the global definitions after the include files.
} >}
} >} However, can't go any further without the filename.h definitions.
} >}
} >}
} >the file you refer to was PART of the original post of
} >the C code.
} >
} >I marked the two files with a comment bof and eof and a line of 8's
} >
} >you need to copy them individually into notepad and create the TWO
} >files "customer.c" and "filename.h".
} >
} Oh ... Just did the customer.c (named it counter.c)
} I'll check the split ... tomorrow.
}
} >Which compiler are you using?
} >
} Borlund 2.0
}
} >The included complier in the zipped file "Microtec C Tools" is the
} >only one that is going to work with these source files.
} >
} >Look at my post of the C Tools again- both are on my server.
}
} Like I said, I only got one zip file here.
} It was labeled "C tools v2.29,zip"
}
}
Microtec C Tools reposted in binary froup.
--
It is said that wisdom comes with age
--so why am I not very, very wise?
Öldman©
Frank McCoy
2004-07-24 16:19:02 UTC
Permalink
Post by Öldman©
} However, still missing, is the "filename.h" file.
} Encountered a slight difference in compilers, where structures were
} being done before the call to the include file that defined them; and
} that was a no-no to my compiler. However, that was an easy fix; just
} moving the global definitions after the include files.
}
} However, can't go any further without the filename.h definitions.
}
}
the file you refer to was PART of the original post of
the C code.
I marked the two files with a comment bof and eof and a line of 8's
you need to copy them individually into notepad and create the TWO
files "customer.c" and "filename.h".
Which compiler are you using?
The included complier in the zipped file "Microtec C Tools" is the
only one that is going to work with these source files.
Look at my post of the C Tools again- both are on my server.
Well ... It compiles a lot better now that I have the filename.h file.
Thouhg I don't have the Microtec compiler, it still checks out fairly
well, except for one missing definitin: _iob

I presume that's part of your standard stdio.h file ... Probably
because of a slight difference between your compiler and mine.
I suspect that if you could send me just a copy of the stdio.h file, I
could get it to compile so I could make changes and check them.

The stdio.h file comes with the compiler, unlike the other include
file. It's most likely in the "include" directory just above your
compiler.

Might need io.h too.
Sometimes stdio.h makes reference to that.
I *can* make it work without that though, just by defining _iob, which
is just a pointer to COM0-COM4. Still, it would probably be better to
use the same definition.
--
_____
/ ' / ™
,-/-, __ __. ____ /_
(_/ / (_(_/|_/ / <_/ <_
Öldman©
2004-07-24 17:08:10 UTC
Permalink
On Sat, 24 Jul 2004 11:19:02 -0500,Frank McCoy's cat ran across
the 'puter keyboard and out came...
} In alt.fan.frank.mccoy �ldman© <***@ld.is.best> wrote:
}
} >} However, still missing, is the "filename.h" file.
} >} Encountered a slight difference in compilers, where structures were
} >} being done before the call to the include file that defined them; and
} >} that was a no-no to my compiler. However, that was an easy fix; just
} >} moving the global definitions after the include files.
} >}
} >} However, can't go any further without the filename.h definitions.
} >}
} >}
} >the file you refer to was PART of the original post of
} >the C code.
} >
} >I marked the two files with a comment bof and eof and a line of 8's
} >
} >you need to copy them individually into notepad and create the TWO
} >files "customer.c" and "filename.h".
} >
} >Which compiler are you using?
} >
} >The included complier in the zipped file "Microtec C Tools" is the
} >only one that is going to work with these source files.
} >
} >Look at my post of the C Tools again- both are on my server.
}
} Well ... It compiles a lot better now that I have the filename.h file.
} Thouhg I don't have the Microtec compiler, it still checks out fairly
} well, except for one missing definitin: _iob
}
} I presume that's part of your standard stdio.h file ... Probably
} because of a slight difference between your compiler and mine.
} I suspect that if you could send me just a copy of the stdio.h file, I
} could get it to compile so I could make changes and check them.
}
} The stdio.h file comes with the compiler, unlike the other include
} file. It's most likely in the "include" directory just above your
} compiler.
}
} Might need io.h too.
} Sometimes stdio.h makes reference to that.
} I *can* make it work without that though, just by defining _iob, which
} is just a pointer to COM0-COM4. Still, it would probably be better to
} use the same definition.
}
}
Being that the output of the compiler is all important - machine code
that directly addresses the I/O registers of the CPU - Borland will
not work as it compiles for xxx386 processor.

The processor of the PLC is a RISC type - the same family of processors
used for video cards, sound cards, modems etc. These processors have
a greatly restricted command set as much of the work they do is a
function of the hardwired part of the board they live on. As a rule
they do not use a lot of memory 'mapping' as the RAM is hardwired to
the CPU. This particular CPU uses limited mapping as an array can be
defined for the data base. Every one of these CPUs has its own dedicated
compiler.

BTW - I thought that hard drives incorporate a similar processor. You
worked for Seagate? (I have two Seagate drives and a Western Digital in
my 'puter. Built the whole thing myself from components).
--
It is said that wisdom comes with age
--so why am I not very, very wise?
Öldman©
Frank McCoy
2004-07-25 23:56:05 UTC
Permalink
Post by Öldman©
On Sat, 24 Jul 2004 11:19:02 -0500,Frank McCoy's cat ran across
the 'puter keyboard and out came...
}
} >} However, still missing, is the "filename.h" file.
} >} Encountered a slight difference in compilers, where structures were
} >} being done before the call to the include file that defined them; and
} >} that was a no-no to my compiler. However, that was an easy fix; just
} >} moving the global definitions after the include files.
} >}
} >} However, can't go any further without the filename.h definitions.
} >}
} >}
} >the file you refer to was PART of the original post of
} >the C code.
} >
} >I marked the two files with a comment bof and eof and a line of 8's
} >
} >you need to copy them individually into notepad and create the TWO
} >files "customer.c" and "filename.h".
} >
} >Which compiler are you using?
} >
} >The included complier in the zipped file "Microtec C Tools" is the
} >only one that is going to work with these source files.
} >
} >Look at my post of the C Tools again- both are on my server.
}
} Well ... It compiles a lot better now that I have the filename.h file.
} Thouhg I don't have the Microtec compiler, it still checks out fairly
} well, except for one missing definitin: _iob
}
} I presume that's part of your standard stdio.h file ... Probably
} because of a slight difference between your compiler and mine.
} I suspect that if you could send me just a copy of the stdio.h file, I
} could get it to compile so I could make changes and check them.
}
} The stdio.h file comes with the compiler, unlike the other include
} file. It's most likely in the "include" directory just above your
} compiler.
}
} Might need io.h too.
} Sometimes stdio.h makes reference to that.
} I *can* make it work without that though, just by defining _iob, which
} is just a pointer to COM0-COM4. Still, it would probably be better to
} use the same definition.
}
}
Being that the output of the compiler is all important - machine code
that directly addresses the I/O registers of the CPU - Borland will
not work as it compiles for xxx386 processor.
I know that.
*BUT*, it should do just as good as an *error checker* for code I
write; since in neither case can I execute the code.

IOW, "Is it good 'C' code?"
Not, "Does it work?"

Without the target machine here to run it on, and an application to
run the target machine on, the best I can do HERE, is write what I
assume to be good code and check it for errors on a 'C' compiler
that's compatible.

From all indications, the compiler used for your machine is compatible
with Borlund C.
Post by Öldman©
The processor of the PLC is a RISC type - the same family of processors
used for video cards, sound cards, modems etc. These processors have
a greatly restricted command set as much of the work they do is a
function of the hardwired part of the board they live on. As a rule
they do not use a lot of memory 'mapping' as the RAM is hardwired to
the CPU. This particular CPU uses limited mapping as an array can be
defined for the data base. Every one of these CPUs has its own dedicated
compiler.
BTW - I thought that hard drives incorporate a similar processor. You
worked for Seagate? (I have two Seagate drives and a Western Digital in
my 'puter. Built the whole thing myself from components).
Huh? Damned near every drive I worked on (And I worked on hundreds of
different types) had different processors in them. They seemed to
pick new processors for each generation to get the mostest bang for
the buck; and damned little source-code made it from generation to
generation. Each generation having too many differences and added
"features" to make using older code and designs much of a deal in the
total cost of the design. Even the interface changed from each
generation. Of course, having (at least) three and sometimes as many
as six different departments designing the hardware for each drive,
many of the departments being originally whole company acquisitions
within a few years, had a lot to do with the large number of
processor-types.

That (as you might imagine) made it a little hard on ME; as I was
designing the software to TEST all these differing drives, to make
sure they met design specification. (That's Product Assurance, not
Quality Assurance. Quality Assurance made sure drives being shipped
ran properly. PA tested the WHOLE drive to make sure that as-designed
it would meet the specification ... MUCH harder, and about 1000 times
more rigorous.)

To test each drive to make sure each one could do all the things the
Product Specification *said* it could do, under all the conditions and
overlaps ....

Then, I had to do this on several different platforms, with one
program. ;-|

There area gazillion different ways to meet minimum ATA specs. Same
thing with SCSI specs. However, when you start adding in all the
special feeping creatures that each company, department, or manager
decides to put in or remove for each drive ....
--
_____
/ ' / ™
,-/-, __ __. ____ /_
(_/ / (_(_/|_/ / <_/ <_
Öldman©
2004-07-26 01:48:53 UTC
Permalink
On Sun, 25 Jul 2004 18:56:05 -0500,Frank McCoy's cat ran across
the 'puter keyboard and out came...
<snip>
Post by Frank McCoy
Post by Öldman©
On Sat, 24 Jul 2004 11:19:02 -0500,Frank McCoy's cat ran across
the 'puter keyboard and out came...
Huh? Damned near every drive I worked on (And I worked on hundreds of
different types) had different processors in them. They seemed to
pick new processors for each generation to get the mostest bang for
the buck; and damned little source-code made it from generation to
generation. Each generation having too many differences and added
"features" to make using older code and designs much of a deal in the
total cost of the design. Even the interface changed from each
generation. Of course, having (at least) three and sometimes as many
as six different departments designing the hardware for each drive,
many of the departments being originally whole company acquisitions
within a few years, had a lot to do with the large number of
processor-types.
Exactly the problem these days with PLCs.
I/O can be done only one way - a happens which causes b to
occur but each manufacturer has their own way via software
to handle things. It is a royal pain in the butt to learn
the ins and outs for so many. All I do is pick a few to
work with and try to learn the software. It seems as soon as
I get a handle on the programming they 'upgrade' and its
back to square one. No small wonder there's so much
'buggy' software out there, no one can keep up with
the hardware changes!
Post by Frank McCoy
That (as you might imagine) made it a little hard on ME; as I was
designing the software to TEST all these differing drives, to make
sure they met design specification. (That's Product Assurance, not
Quality Assurance. Quality Assurance made sure drives being shipped
ran properly. PA tested the WHOLE drive to make sure that as-designed
it would meet the specification ... MUCH harder, and about 1000 times
more rigorous.)
To test each drive to make sure each one could do all the things the
Product Specification *said* it could do, under all the conditions and
overlaps ....
Then, I had to do this on several different platforms, with one
program. ;-|
ouch!
Post by Frank McCoy
There area gazillion different ways to meet minimum ATA specs. Same
thing with SCSI specs. However, when you start adding in all the
special feeping creatures that each company, department, or manager
decides to put in or remove for each drive ....
I hear ya.
--
It is said that wisdom comes with age
--so why am I not very, very wise?
Öldman©
Loading...