I am working on a device with an internal pump. Due to small differences in the pump's motor speed, I have to calibrate the pump. The result is a value between 0 and 1 (PWM duty cycle). The PWM is generated by an XMEGA32A4U, which I am programming in C++ with Atmel Studio 7.0 and I load the program with an AVRISP MK II. I also have an SD-card in the system to save data on.

My problem is now the following: I have several devices and I am trying to avoid to have to change the source code for every device before programming it. Not just because I am lazy, but it is also error-prone. And also because the remainder of the code is always the same and I don't want to save 10 times the same code containing only one differing number. What can I do? Things I thought of:

  • reading a unique device ID and thus determining which value to take. But this requires storing a unique ID -> chicken and egg problem. Except if it can be done at programming time with a script (?) or there is a serial number I can read out at boot. The device ID appears to be non-unique as far as I read.
  • Saving the values on the EEPROM in the microcontroller. I did some research and found that this is also not that simple, since you have to have again several source files to generate the several *.eep files which you have to manually select at programming. Although this is something I only need to do once, it is still 'manual'.
  • Save a config file on the SD card and read it in the beginning. Probably the easiest part, but the SD card is user accessible and in theory delete- and exchangeable. Checking the file against a device ID would help of course, but then I am back at square one.
  • Use serial communication to store a config value, which is then written to the EEPROM on the device. I could use LabView or a script to do this ("please enter serial number" -> checking against stored list -> output it via serial)

Does anyone have experience in this? What is the best path to take? Thanks!

  • 1
    \$\begingroup\$ Something to think about: What if you (or a customer) have 10 devices, but after a few years pump #3 wears out, and control board #7 burns out. You may want to be able to cannibalise spares. In which case config over serial would be handy. That's what I'd do, if you already have the serial port. If it means adding hardware, I might think about a special file on the SD card which causes the device to update the EEPROM then delete the file. Either or both of these could also be handy for flashing new firmware to fix bugs in the field. \$\endgroup\$ – Jack B Jan 4 '17 at 16:57
  • \$\begingroup\$ @Jack, I do have a serial port and I will go with your and other people's suggestion to use it. The option with the file is also neat, but at the moment the SD implementation is very crude and I don't want to rely on it for now. As I have access to the serial port from the outside, updating the EEPROM via serial is also not too hard in the field. \$\endgroup\$ – zorgmorg Jan 5 '17 at 8:40
  • \$\begingroup\$ Sounds like a good plan. One more thing to consider: Make sure the command for updating the eeprom is long and complicated enough that it can't be sent by accident if the customer connects to the wrong port and sends lots of garbage. \$\endgroup\$ – Jack B Jan 5 '17 at 11:50

You say that you already have to perform a calibration step in production, and load a different value into the processor as a result. Identifying different motor types, or adding a serial number, device ID, and the like, is no different.

This seems like a natural thing to keep in the EEPROM of the processor. In production, the test jig talks to the micro via a spare UART or something. It doesn't have to be fast, so even just a couple I/O lines with some primitive handshaking is good enough. If the device already has some kind of external connection, even better, just use that.

One way or another, the test jig determines the calibration value for the particular motor. At that point it can assign a type ID and serial number too. These are then communicated to the micro, which writes them to its EEPROM.

One trick that can be handy, especially when the test jig communicates over some customer data port, is to have the micro only accept this information if its serial number is FFFFFFFFh. That's the unprogrammed EEPROM value. The last thing the test jig does is send the actual serial number. After that, the micro won't accept any more changes to the serial number or the other static parameters. This way, no matter what babble the customer might subject the device to, this information can't be altered.

|improve this answer|||||
  • \$\begingroup\$ This does not solve a production problem where the pump is the thing required to be uniquely identified (since the pumps vary). In production you should be able to change the driver board or the pump and have it still work to the design accuracy. \$\endgroup\$ – Jack Creasey Jan 4 '17 at 18:13
  • \$\begingroup\$ @Jack: It's not clear that what you describe is exactly the problem the OP has. The pump and controller could be one unit after assembly, for example, and always replaced that way. Maybe the entire unit is intended to be replaced in the field. In any case, I think this gives the OP some options to think about. \$\endgroup\$ – Olin Lathrop Jan 4 '17 at 22:28
  • \$\begingroup\$ I think that is exactly what the OP described "My problem is now the following: I have several devices and I am trying to avoid to have to change the source code for every device before programming it. Not just because I am lazy, but it is also error-prone." He is having to incorporate the PWM factor for each and every pump directly in tot he code. This makes for hard pairing; hardly the way to do it even for small quantities. Even at the most crude end of the scale you could put a sticky label on the motor with the value and use UI to add it in, what I suggested is trouble free. \$\endgroup\$ – Jack Creasey Jan 4 '17 at 22:57
  • \$\begingroup\$ @Jack: He doesn't want to change the source code for each device. My answer fits that. I'm talking about storing calibration values in EEPROM. All the units still run the same code. Anyway, maybe this is a good solution for the OP, maybe not. I think it's still a useful thing to have described, and meets the OP's stated criteria. \$\endgroup\$ – Olin Lathrop Jan 4 '17 at 23:04
  • \$\begingroup\$ Let's agree to disagree. IMO anything that means the board is now paired with a single pump is dead in the water. Certainly you're way works if he always hard pairs motor/driver. \$\endgroup\$ – Jack Creasey Jan 4 '17 at 23:11

What you really want to do IMO is identify each pump, and keep your software identical for all your devices. In the past I've used Maxim 1-wire devices which provide a small amount of storage and a globally unique ID.
You could store your PWM value in a 1-Wire device and make it part of the pump or it's cable (the 1-Wire device needs no power supply). It means you have two extra wires running to the pump or you could even fit the 1-wire device into the pump connector and avoid extra wires.

Look at the DS28E07 device which has 1k of local Eprom storage and costs a $1 in TO92 form factor and 1 off qty.

The interface is a simple two wire (sense and ground) system.

enter image description here

|improve this answer|||||
  • \$\begingroup\$ Just for the OP's clarity, the Maxim DS28E07 is an EEPROM. But this IC is an excellent suggestion Jack, I'd not looked closely enough at these before :-) \$\endgroup\$ – TonyM Jan 4 '17 at 23:37
  • 1
    \$\begingroup\$ @TonyM. These are fantastic devices for unique ID's and storing calibration values. I always lay out MCU boards with at least one of these as an SMT for encrypted end user, warranty, age and runtime values associated with the serial number. The DS28xxx, but I've used DS24xxx since the early 90's. All at the cost of 1 pin. \$\endgroup\$ – Jack Creasey Jan 5 '17 at 0:18
  • \$\begingroup\$ @Jack, this is a very elegant solution! I did not know these existed. Right now I already designed my board and will go forward with what I have, but I will definitively look at these for a next version. \$\endgroup\$ – zorgmorg Jan 5 '17 at 8:32

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.