Software system development procedure question

I am engineering a still controller that has a number of different I/O devices to operate. The procedure I intend to use is to build each I or O interface circuit and then write a sketch to operate it and to test it out. When done, I will have a bunch of sketches that I know work well with my hardware. My plan is to then put these I/O sketches in the form of functions that can be used in my over all system control sketch. Then I copy each separate I/O function sketch and paste it into the system control sketch.

Does this make sense as a strategy, or is there a better way?

Thanks,

Barry

This can make sense and is a good way to build up a system. However, you have limited resources (memory mostly) in the AVR processors, so you may need to tweak the overall process to make sure you are as efficient as possible at the end (ie, reduce duplication). This will depend on the application, but as we have no more details ...

What you are describing is essentially standard procedure. Further to Marco's you need to look at what you want to do. This sort of work can be categorised.

variety of devices

number of devices

local display

data recording

communication

I point this out as I took the usual path of getting a Uno but landed up needing a Mega. If you need to consider all of the above, the Uno is likely to have insufficient memory and you might as well get a Mega to start with.

Since I have no experience with the Arduino, I am worried about memory space. We are using the Mega. I don't think I will have trouble with the basic functions of running the still, but I am almost paranoid about using this device in an industrial environment so I do have a lot of error detection and diagnostic hardware and software in mind.
My boss also wants fancy data logging and the ability to do things from an attached computer, and while this is certainly possible, it will eat up Arduino memory if I'm not clever about it. Any suggestions would be appreciated, and we are prepared to add shields or even another (serial connected?) Arduino if we have to. I have the "Maker Plot" software in mind for running on the PC to do all the data logging and reporting and control he wants, but I have no idea at this point what Arduino resources this will eat up.

Some how I managed to get this post in the wrong forum. Can someone tell me how to move it to the software forum?

I don't think I will have trouble with the basic functions of running the still, but I am almost paranoid about using this device in an industrial environment so I do have a lot of error detection and diagnostic hardware and software in mind. My boss also wants fancy data logging and the ability to do things from an attached computer

Frequently in industrial environments people use Programmable Logic Controllers (Allen Bradley, Siemens etc.), along with a SCADA system on a PC/Server for mimics, reports etc. That approach will be a lot more expensive than an arduino but you might want to consider if it is appropriate for your application (e.g. value of process, future expansion etc.).

oldradio:
I have the "Maker Plot" software in mind for running on the PC to do all the data logging and reporting and control he wants, but I have no idea at this point what Arduino resources this will eat up.

I imagine not so many. If the Arduino is standing alone, it needs to be considered in the way I described, but a Mega can do a hell of a lot of work. If it is connected to a PC in the way you describe, it is simply an interface device passing the data along to the PC, where the real work gets done.

Some how I managed to get this post in the wrong forum. Can someone tell me how to move it to the software forum?

It seems in the right place. If it isn't, the moderator will move it.

Given that you're using a Mega, you've got loads of flash and RAM to play with. The reporting can simply be reporting the state of your I/O devices through serial to the PC - put any smarts you require there. Make use of program to store any text you're going to send to the PC.

How much I/O are you going to need?

One thing to look out for is that your test programs, and hence your functions, do not use the delay() function, as this will prevent anything else running until the delay() is finished. This may work for the test program but would be unacceptable in a program that reads many sensors and processes the data.

One thing I've learned over the years is that projects like this tend to be vulnerable to "feature creep" as they are developed. More and more requirements are heaped on to what starts out as the solution to a simple problem. My advice is to figure on this happening right from the outset and make sure you have much more capability in the hardware than you think you will need. Not really much of a restriction given the low prices of some pretty high end hardware today.

This is exactly the kind of system something like a PC running LabVIEW would work great for.

RoyK:
One thing I've learned over the years is that projects like this tend to be vulnerable to "feature creep" as they are developed.

Agreed. Freeze the (minimal) feature set for version 1.0 as early as you can. Any additional features they want, say "sure thing boss, that'll go right into version 2.0".

"sure thing boss, that'll go right into version 2.0"

To which my boss would have replied. "Fine. Skip straight to version 2 and take an extra day or two." :slight_smile:

To which my boss would have replied. "Fine. Skip straight to version 2 and take an extra day or two."

Lucky you. I never get extra time.

... write a sketch to operate it and to test it out. When done, I will have a bunch of sketches that I know work well with my hardware. My plan is to then put these I/O sketches in the form of functions ...

I would try to design and write the IO code as functions to start with, designing a "sensible API" from the beginning.
That is, instead of writing code like:

void setup() { 
   pinMode(12, OUTPUT); // clock line to thermometer
   // Blah blah
}
void loop() {
   digitalWrite(12, 1); // enable thermometer chip
   // blah, twiddle bits, etc.
   Serial.print(temperature);
   delay(10000);
}

Do this instead:

void thermometer_init(uint8_t pin) {
    pinMode(12, OUTPUT); // clock line to thermometer
   // Blah blah
}
int thermometer_read() {
   digitalWrite(12, 1); // enable thermometer chip
   // blah, twiddle bits, etc.
}
void setup() {
  thermometer_init(12);
}
void loop() {
  temp = thermometer_read();
   Serial.print(temperature);
   delay(10000);
}

Lucky you. I never get extra time.

I was on monthly salary and projects were often due end of day on a Friday. He'd give me until Monday morning sometimes.

void thermometer_init(uint8_t pin) {
    pinMode(12, OUTPUT); // clock line to thermometer
   // Blah blah
}

Pass in a pin number that gets ignored. Great idea. Not.

Thanks for all the helpful ideas. I should make one confession. My "boss" is my son who quit his lawyer job and is starting a distilling business. I am doing what I can to give him what he wants, but he makes the decisions.
I was the patent attorney for the Allen-Bradley company back in the 70s and 80s when the PLC was invented and developed. If it were my choice I would be using an AB PLC for this task! Instead, I am learning the Arduino.

There aren't that many I\O devices for the still itself: 3 temperature sensors, 2 solenoid valves, 1 servo valve, 1 pump, 1 limit switch, 12 or so front panel switches and lights, 6 7-segment 4 digit displays, and 8 25 watt heating element SSRs driven from a single Arduino pwm output using a separate phase angle control module.

I'm guessing at this point that the error detection and diagnostics stuff could add 50% more I/O points. If I can't have a PLC, I will load up on this.

Feature creep, and even basic function creep, is a given in my situation. That realization is what prompted my question. I can develop the hardware for each of the above devices and test each out with the Arduino. I then turn each piece of Arduino code into a function. The more devices added, the more functions I end up with to call in the "Loop" code that determines overall still operation.

One of the nice things about this project (other than working with my son) is that a still is a really slow process, so I can average analog signals, debounce the heck out of switches and the like. My only time concern is the 2 second watchdog timer. Nevertheless, where I need longer delays (e.g. the three digital thermometers need 750 ms ) I will use millis().

I will take a look at the "Labview" software.

Barry

If you take the finite state machine approach which you may be familiar with if not in name but method then you can "multitask" and be able to add or remove tasks with the least amount of fuss and mess.

That last part is not automatic but is not hard to achieve. The idea is to keep tasks separate; not have code for a light inside of code for a button for example (which leads to more and more spaghetti interleaving and indent levels as featurism progresses) but instead pass control through variables and bits-as-flags.

Start here for a good tutorial on:

How to do multiple things at once ... like cook bacon and eggs

That shows how to set up timed events that can be up to 49.71 days apart, if desired.

For Inputs, you just use a different if() or set of if's.

For memory there is a way to store constant text and/or tables to flash memory and use it through minimal or essentially no RAM. There's a macro for simpler text printing from flash, tables take a bit more.

Arduino is a development board. You can use it to program stand-alone AVR chips on boards, even breadboards. Thus if you need more than one chip to do everything it can be pretty cheap to add "cores". The 328P on an UNO has less resources than a 2560 on a MEGA but it's just as fast and has pins enough to do a good bit. You can program a wide range of AVR's from 8 to 16 pin ATtiny chips (under $2 ea) up to 1286's (about $7) that have twice the RAM of the MEGA's 2560. And if needed, a number of the bigger AVR's can connect to external RAM as direct-addressable up to 64k. Rugged Circuits makes shields to do that, their QuadRAM shield does bank switching to give 512k capability to a MEGA so I wouldn't get too worried about RAM if I were you. :smiley:
http://ruggedcircuits.com/html/quadram.html

You can use shift register chips (with external power) as pin-multipliers. Using the SPI-bus ones you can control literally 100's of pins with 4 MCU pins.

You can use SD card adapters for gigabytes of cheap mass storage. Just don't use them quite the same way as a hard drive or floppy, sorting is better done through link files than rearranging records or text since you have limited rewrite capability (10's of 1000's of rewrites which a processor can do in less time than is economic). If you need to do physical sorts, do those on a PC and load the finished file to SD card.

There are Finite State Machine tutorials out there, IIRC Majenko (a member here) has a good one aimed at Arduino. I have a simple example or two as well.

Tell your son to take time to do it right or learn to code himself! There's an old saying: Never Time To Do It Right, Always Time To Do It Over.

A mind fixated on deadlines will often miss the otherwise obvious simple and easy answers. If you need a break then take one, good code usually isn't a linear task.

GoForSmoke:
If you take the finite state machine approach which you may be familiar with if not in name but method then you can "multitask" and be able to add or remove tasks with the least amount of fuss and mess.

Yes indeed I recently discovered Finite State Machines (FSM) myself and am currently in love with them. I've actually got three nested FSMs in my current Arduino sketch and it's made things much easier to compartmentalize and keep things clean.

FYI I also discovered a library called "protothreading" (build hardware and write code for it: protothread, a powerfull library) which is FSM-like but specialized towards multitasking.

Just to be clear oldradio, you don't have to use an FSM (or protothreading) -- the idea you already proposed is entirely workable (and could indeed be considered a primitive form of FSM). But, formally adopting a FSM can help impose a greater degree of order/consistency to your code, which is generally a good thing.

An alternative if you are already familiar with PLCs is to use some of the small 'brick' type devices that are not much more expensive than an Arduino board but could provide more robust I/O isolation for your purposes. These are probably easier to network if you need more than one, and the I/O extensions are more automatic when you have to add remote I/O.

As a point of preference, I would move to the Due for speed and memory and implement an RTOS, say ChibiOS/RT for ARM. At least this removed many constraints at day-one.

Ray