Sciencemadness Discussion Board

Building a Chemputer

mc68k - 26-10-2023 at 13:07

I was inspired by a couple articles that described the mechanics of an automated organic synthesis system [1]. But the real gold is the supplementary data [2] which describes all the technical details of the system. The lead, L. Cronin and his lab published several papers on the system, it's "synthesis language", and various adaptations (Grignard reactions, automatic chemical discovery and characterization, etc).

They later named it "The Chemputer".

Since I'm interested in chemistry, robotics, automation, and software - this is right up my alley!

My goal is to replicate a portion of the system, enough to 'execute' one of their synthesis scripts. Although I'd be happy just automating the manufacture of any non-trivial material.

[1] Organic synthesis in a modular robotic system driven by a chemical programming language, L. Cronin (also attached)
[2] Supplemental report from [1]



Attachment: Organic synthesis in a modular robotic system driven by a chemical programming language.pdf (2.2MB)
This file has been downloaded 263 times

mc68k - 26-10-2023 at 13:54

Current progress:

I scrounged up some control components and ordered some parts to put together a simple liquid-transfer system, which will be the 'backbone' of the chemputer.

Arduino Uno (upper left)

This will be the main driver/controller, it currently drives the peristaltic pumps but will eventually also receive commands from the PC (eg. transfer 10 mL from container A to container B).

Geckodrive G540 (lower left)

This is a 4-axis stepper driver. I had it left over from another project.

Peristaltic Pumps (middle-right)

These will perform the liquid transfers between flasks.

Stream Selectors (top right)

I believe these are used in HPLC machines for sample injection? Found them for $35 on eBay. They are 6-port selectors, so I can address a total of 12 flasks using them. The have steppers, gearboxes, and optical rotation locators. Score!

Currently having some issues finding compatible fittings for it though. :(

Ender 2 Mainboard (bottom right)

From a mainboard upgrade on my 3D printer. This has another 4-axis of stepper control and already supports a control language (gcode).

Some_Parts_1.jpg - 137kB

fx-991ex - 26-10-2023 at 14:38

will be interesting, electronics(repairs, circuit/pcb design/assembly) and programming(website/microcontroller/software, usually all 3 together) been my main hobby for 20+ years. Am very good in this domain :).
Ill see if i can help.

[Edited on 26-10-2023 by fx-991ex]

[Edited on 26-10-2023 by fx-991ex]

j_sum1 - 26-10-2023 at 19:47

Wow. What an ambitious project. Really interesting and potentially very useful.
Keep us posted on how it goes.

Texium - 26-10-2023 at 20:08

Those HPLC injectors tend to have very tiny liquid capacities, typically designed for transferring only tens of microliters at a time. I’m not optimistic that they would be effective for routing mL scale volumes on a short timescale.

Overall though, interesting ideas. I think such a system would truly shine in programming slow additions of reagents. Nobody wants to sit around with a syringe adding things dropwise for an hour, and sure, syringe pumps exist, but they are very bulky and annoying to set up. Not even worth it most of the time.

mc68k - 27-10-2023 at 10:11

fx-991ex:

Yes! It's a neat mix of skills and interests.

I could use help with hardware selection (single-board computers, sensors, etc), since I'm unfamiliar with most of the components being used.

I think Arduino is a good starting point, but each board can only manage a few components due to the number of inputs/outputs required. For example, the selection valves require 6 pins: DIR, STEP, I1, I2, I3, I4 (optical position sensor inputs). This means each Arduino can really only control about two components.

The chemputer is built from modular single-board computer elements, each controlling just one of the lab components. This simplifies the scale-up since they just plug all of the computing elements into an ethernet switch and control the whole thing from one PC. Definitely the right direction, but out of my current scope (but if you wanted to look into that...) ;)

j_sum1:

Thanks! I hope to get far enough along to do some interesting chemistry, even if replicating their entire system is WAY out of scope.

Texium:

Sadly, I am aware of the discrepancy, but this was the best I could find for the moment. The chemputer valves are IDEX V-320 which use 1/8" OD tubing (easily transporting 10s of mL), while the ones I have are Rheodyne PD725-125 which use thick-wall 1/16" OD tubing and are designed for high-pressure sample injection (generally measured in uL as you mentioned).

Not too concerned since the valves I purchased also have steppers and sensors which could drive some other valve if the liquid throughput from these is too low.

Interesting note; in another paper [1], the same lab uses 1/16" tubing throughout in order to fit with and automate an HPLC alongside the chemputer.

More bits and Dr.Bobs:

Reading through the chemputer papers I noticed that they had to use several custom-designed glass components, specifically a jacketed filtration module and liquid-liquid separation module, in order to achieve automation control over the reactions.

While digging around for other information about their designs, I found a paper by some of the other lab members. One interesting methodology "adjacent" to the chemputer work is 3D-printed custom reaction vessels [2].

This solves the problem of how I will gain access to the specialized flask designs used in the chemputer! Printing reaction vessels using Polypropylene filament appears to work just fine for many solvents and reaction temperatures. However, it does limit the maximum temperature of reactions to 130 C, and even there only for short durations.

What I found particularly interesting in this paper is the use of glass frit filters and hydrophobic membranes installed during the 3D print cycle such that they are bonded into the reaction vessels.

Dr.Bob was able to supply some hydrophobic membranes that look like they might work for this purpose.

[1] Digitizing Chemical Discovery with a Bayesian Explorer for Interpreting Reactivity Data (see supplemental data)
[2] 3D designed and printed chemical generators for on demand reagent synthesis

mc68k - 30-10-2023 at 14:16

The chemputer is made up of a few physical modules, each of which performs one of the common bench synthesis steps.

- Liquid transfer
- Mixing under temperature control
- Liquid/liquid separation
- Filtration
- Solvent evaporation


Liquid Transfer

This is the 'backbone' of the system, transferring liquids from reagent jars into flasks, filters, and waste. The chemputer uses syringe pumps connected to multi-port selection valves. Both the syringe pump and selection valve modules are custom-designed by the lab.

Instead of syringe pumps I chose peristaltic pumps based on a few factors:

- they're cheap
- pump forward and backward
- pump precise amounts of fluid
- don't need to be primed
- can be used in future projects

Multi-port selection valves that are chemical resistant are not common components outside the lab. The industrial version would be a custom manifold of solenoid valves that are immensely more bulky.

I've looked for 3D-printable selection valves, but none are of acceptable quality for this project.

I'll have to continue searching eBay for additional valves as the project progresses. I currently have 3, which should be enough to get started.


Mixing under Temperature Control

In the papers, this module is called the Reactor. Early versions of the chemputer use a RBF on a custom aluminum block over a computer-controlled hotplate/stirrer. It has an air-cooled condenser for refluxing and a thermometer to control temperature.

Later versions are described as using an aluminum block with internal piping which circulates fluid from external heater/chiller to control reaction temperature. They switched to using an overhead stirrer, and the reflux column is a standard glass column fed from a water chiller.

I do have a computer-readable thermometer and a non-automated hotplate/stirrer. I could set the hotplate on "high" and use a on/off controller to pulse it to control temperature, but that would mean stirring is also pulsed.

Another option is to get a recirculating chiller/heater, then 3D print an equivalent reaction vessel with a water jacket. Adding computer control to the chiller/heater would enable precise reaction temperatures.


Liquid/liquid separation

The authors were not entirely happy with their liquid separator, a modified sep funnel with a conductivity sensor inline with the bottom port. It is less than ideal because it exposes stainless steel tubes to the reactants, but they did report good/precise separations.

I'm looking into continuous liquid-liquid separators using hydrophobic membranes[1]. This would significantly simplify the separation & washing steps and reduce the needed infrastructure.


Filtration

The filtration module is a complex one. It's a custom-jacketed Büchner funnel with a stirrer. This allows them to fill the funnel with the reaction mixture, cool it to crystalize the product, vacuum filter the liquid, wash with new solvents, and finally vacuum dry the final product.

I will likely just 3D print an equivalent module and install a glass fit in the bottom. If I do get a recirculating heater/chiller, this module will also benefit from it.


Solvent Evaporation

I'm unlikely to get around to automating a roto-vap, so the solvent evaporation step will have to be replaced with some kind of distillation.

Yet to be researched.


Current Progress:

- Got the peristaltic pumps working properly - not overheating or stuttering instead of pumping.
- Ordered fittings for the selection valves
- Wrote Arduino program to control a pump and receive serial communications which sets the speed of the pump


[1] zaiput.com

sceptic - 1-11-2023 at 03:32

What kind of filament are you planning to use? I think it will be hard to find one that's commonly available but also resistant to acids, bases, oxidizers, etc.

mc68k - 2-11-2023 at 07:18

Quote: Originally posted by sceptic  
What kind of filament are you planning to use? I think it will be hard to find one that's commonly available but also resistant to acids, bases, oxidizers, etc.


sceptic, check out the paper I referenced above about 3D printed cartridges:

https://doi.org/10.1038/s41467-019-13328-6

Current Progress:
- Writing OpenSCAD scripts to generate various cartridge shapes/sizes
- Got PP filament to test
- Making permanent wiring harnesses for the peristaltic pumps


pp_filament.jpg - 123kB

sceptic - 2-11-2023 at 12:21

Oops! I didn't notice that section of your post.

Rainwater - 2-11-2023 at 15:42

I read, readed. @&>/. I hate english, we got 45000 words and i sware half are the same thing.

I red those papers.
Seams like a industry standard, simply reinvented.
They may not even know there, their.... they are redesigning the wheel.
Their using the standard top down design approach.
They want to use a specific programing language called X.
As a programmer, thats fancy talk for a script.
They want language X to translate via compiler into a maching/lower level languages.
Fancy talk for an interpreter.

They want to write something like
Code:
// NaOH + HCl = NaCl + H2O // list reagents and assign to dispencer // Reagents.add( name, molarity, container) Reagents.add("NaOH", 1, 0) Reagents.add("HCl", 12, 1) //set reaction conditions Reaction.mixSpeed( 300 ) //how long to take to add all of the reagents in seconds Reaction.stirring(100) //rpm Reaction.tempature(50) //hotplate temp //set Stoichiometry //Reaction.add(name, mols) Reaction.add("NaOH", 1) Reaction.add("HCl", 1) //start the procedures { Start() }(...){ print("we had an error") } print("its all good boss")


Using a moduler design you can develop a list of simple commands for each module.

Designing a single controller to run every module or designing modules that talk to the controller and run their self is a hardware decision.
Your programming should not care either way about how this functions.

From the code snippet above, you should have the reactor object do all the math us lazy amateurs dont want to do.
How many mL of this, to that, and how slowly to add each to the mix.
You should also set up limits and inventory. You dont want to add 100ml of solution into the reactor when you only have 6 left in the reagent bottle
Or worse, add 300ml to a flask thats only 100ml big.

All the simple stuff you may want to control should be listed

Draw up some block diagrams and move things around.
Section off task to different modules in your code.

Each modules job should be short and clear. For example.
The main controler should not worrie about starting and stopping a motor, measuring time to dispence just the right amount.
The main controler says, "dispence 2ml of reagent 0".
The dispencing module worries about the details of how to do that.

Your controller module shouldnt even care how it communicated with the dispencer module.
Either by setting a flag for another section of your code to execute, or sending a message by wire or across the world. Your controller should not care how output is handled.
Same thing for input. File, gui, ip/tcp or modbus connection. Shouldn't matter

Starting out with this mindset will make your programs much easier to manage as this project evolves.

Something like this, start writing doc files, explane how it works from a user prospective before you write the first line of code. Then, you have a template to build your programs around.

For the pumps an L298N based H bridge development module would be perfect for your driving any 5-32v dc motor @2 amps per channel.

Positive feedback could be added with some beam break sensors (ADA2167) for more accurate despencing.

An hiletgo STM8S103F3P6 dev board could run 2 L298n boards, with 4 feedback sensors for less than $15 bucks + the motors.
Setup uart for serial communication via usb and just plug everything into a usb hub.

There's you power supply for the controllers and all interconnections in 1 cable. From the factory.

Can control everything from a pc like that.
Edit. Sorry, just double checked the specs. Have to use a logic level shifter or a different mcu board. That one is 3.3v and the h bridge requires 5v logic.

[Edited on 3-11-2023 by Rainwater]

Nano Board V3.0 ATmega328P amazon has a 6 pack for 30 bucks. Same form factor, 5v output. Would be able to run 4 pumps or act as an interface between usb and the Rheodyne PD725-125. I could not find the model # listed, but all their controllers are "contact for pricing" which is never a good thing. They do provide a high resolution picture . Suckers
They are using they 3977sedt stepper motor but are missing reverse input protection to the chip and very weak Vcc ripple filtering.
Just means they sell more boards when one is connected wrong. Probley spec a high dollar psu to drive it that has all the filtering included. Datasheet attached

[Edited on 3-11-2023 by Rainwater]

Attachment: 3977.PDF (569kB)
This file has been downloaded 183 times


DXFlatline - 3-11-2023 at 15:13

IBM has RoboRXN. Infact you can feed it pretty standard synthesis procedure text like "1 mole of X was refluxed for 6 hours at 180C" and AI takes care of the rest

mc68k - 3-11-2023 at 20:26

DXFlatline,

That sounds similar to what they've done with the chemputer. They taught it to read published literature and compile the experimental section into a script that can reproduce the experiment using the chemputer.


Rainwater,

Yes! Sounds like we're on the same wavelength here. I'll probably use Javascript or Python as the scripting language on the PC side.

Thanks for the recommendations on driver boards, definitely something I'll check out as I expand. The G540 will be fine for now, but I do want to grow beyond 4 programmable components.

The USB hub is a good idea too - I was looking at stacking an Ethernet shield, PT100 temperature sensor shield, and stepper driver shield on top of the base Arduino. Ethernet is almost half the total price of that stack so if the USB hub works, that would be a significant savings.


Current Progress:
- Printed a box for the G540 and its mess of wiring
- Received the fittings for the valves
- Tested valve throughput using a 30 mL syringe, I could run all 30 mL through in less than 30 sec with just hand pressure. That's plenty of throughput for this project (I'm targeting reactor volumes in the 10s of mL).

Rainwater - 4-11-2023 at 00:24

pt100 can be read directly from any analog pin.
Simple circuit connects like so
Vcc > pt100 > 150ohm resistor > Gnd
Connect the analog pin to the node connecting the sensor to the resistor.
No coffee yet. Dont trust my math

Vout = (Vcc * Rtd) / (Rtd + R1)
Flip the math to solve for Rtd is
Rtd = -1 * [ (Vout * R1) / (Vout - Vcc) ]

Pt100 standard thermal coefficient is
3.85×10-3 /c

Getting a shield should include overcurrent protection and a strong low pass filter. For a 1off just buy it. When you go into mass production, print it
Remimber the self heating problem P=E²/R
Usually solved by using a resistor with 5-10 times the required thermal dissipation.
Read the datasheet for your pt100 and adjust R1 accordingly

Edit
I recommended the usb as a convenient source of power and coms.
Wanting more than 4 motors on 1 control unit, will increase expense and complexity
The price point is still $15bucks for 1 control board, 4 beam break and 4 h bridge channels.
If you want more, build 2 modules instead of one. (Another 15 bucks)
But then usb hub will become an issue.
These controllers come with uart, and using something like MAX485 will alow you to connect 128 devices with just normal wire using the rs485 hardware protocol.
Good for 128kbps at 1000ft.
Amazon has 10 for 10 right now.
So that basicly adds 1 dollar to the price.
But now you need a power supply

[Edited on 4-11-2023 by Rainwater]

Rainwater - 8-11-2023 at 13:02

Itchin for an update.

I hope to have a working prototype of a ModBus pump controller working by this weekend
designed it around the ATmega328P to match your arduino uno.
I set the goal of using arduino libraries for most of the code,
this seriously increased the firmware size.
The IP we use at work takes up about 3.8k, and the arduino library is 14k.
So theres a lot of room for improvement.

mc68k - 8-11-2023 at 20:50

Progress...

Pumps
Tested the peristaltic pumps, they are not very smooth and have a small retrograde phase. Should be fine, and I can add a one-way valve if needed

I calculated 6250 steps/mL for the pumps. The Arduino library recommends 1000 steps/s as the max rate, which limits me to about 10 mL/min. I may have to use PWM, or a faster Arduino. The valves seem to support about 60 mL/min.

Valves
I mapped out the valve selection steppers and optocoupler traces. I have the valve selection steppers working fine now, although they overheat after awhile, need to track that down.

A bit stuck on the optocouplers, I was expecting pretty clean signals but getting a lot of flickering, just touching the cable will set it off. A few things I tried so far:
- Several hysteresis methods
- Shielding the cable and grounding it
- Activating the internal pull-up resistors on the ATmega (this stops the flickering, but also eliminates any input)

Maybe it needs a support circuit? Capacitor across the power lines? There are no markings on the couplers so I have no way to track down the information sheet.

basic_wiring.jpg - 274kB

optocoupler_top.jpg - 85kB

optocoupler_bottom.jpg - 81kB

Synthesis
Also working on a first synthesis to try that doesn't need much more than heating and mixing.

Current target looks something like this:

- Urea + Glycine -> Hydantoin
- Hydantoin + Benzaldehyde -> (?)Benzalhydantoin
- Hydrolysis of Benzalhydantoin -> (?)Phenylalanine

I think the product is Phenylalanine, but with a double bond to the phenyl group, not sure what the name of that is.

All the steps are simple, the products are easy to isolate, and with a little manual filtering (ie: cheating) I think it should work with the components at hand - and I already have the chemicals, so that's a plus!

Hydantoin Condenstation.jpg - 44kB

Rainwater - 9-11-2023 at 03:43

Std-3 = flame spread/smoke rating.
94-0v voltage rating of the pcb material.
Cant make out the other numbers

The part number should be of the U1-U4 devices.
Sometimes they turn the part number in so it cant be seen just to be mean, or simplify pcb layout
edit:
Any clue where got it from, listing or title?

[Edited on 9-11-2023 by Rainwater]

mc68k - 9-11-2023 at 09:50

Quote: Originally posted by Rainwater  

Cant make out the other numbers


The third line has the digits "1913", if that is helpful.

Quote: Originally posted by Rainwater  

working prototype of a ModBus pump controller


Yes - ModBus sounds like a good direction. I have a lab scale and calibrated thermometer that support RS-485 too, so that would ease integration of all the parts.

Optocouplers

Scrounged around on Mouser and found two photo-interrupters that match the package dimensions and are visually similar to the components:

Omron EE-SX1103

ROHM RPI-243

Both of them show a schematic which suggests a pull-DOWN resistor on the output, which would answer the question of why the pull-UP resistor isn't working.

I also mapped out the PCB and the SMD resistor marked 151 is inline with the transmitter's cathode, so it's just a current-limiter for the always-on transmission LED.

That should solve the input problem! I'll try it later today.

Software

The Cronin lab released some of their software too. The Arduino command libraries look pretty good, so I'll probably give those a try instead of writing them anew.

Cronin Lab GitHub


[Edited on 9-11-2023 by mc68k]

Rainwater - 9-11-2023 at 20:14

So I got a board in today,
ordered the nano, and they sent the micro. $4 vs $16
So win for me
It's an atmega32u4 instead of the atmega328p
Almost the same.
a little more ram
a few less gpio pins,
but the mcu core, clock speed, and peripheral interface is all the same

First test of the software,
still got some debugging to do and have to add a way to configure it.
Im thinging a 8pole dip switch

Test duration was 10 seconds per step
With the motor output fixed to 150ms duration "on" time each second
I compared the PCInt pulse rate to motor control timing errors and incorrect pulse counts
Pulse per second / timing error / missed counts
Code:
0 / 0.04% / 0% 1k / 0.19% / 0% 2k / 0.60% / 0% 5k / 1.73% / 0% 10k / 83.1% / 0% 25k / 400% / 0% 50k / $<"(ed/ 2%


So thats a good test.
I think between 2k would be the maxium feedback rate desirable.
Thats per second.
Without a lot of network traffic, under simulated conditions.

If the board was only controlling 1 device with feedback, we could get up to 1MHz
using a true Int pin and a 16bit hardware counter before we lose any precision.
Not revelent for a pump controller, but could be useful elsewhere
To control 4 feedback loops, i use the PCInt IRC routine which lags things alot.
I figure with the motors I got, the highest count rate will be about 6, maybe 8 per second.
Im hoping I can get together a BOM that doesnt require hand soldering or custom
boards. Just some jumpers to pins and she'll by hot to trot

Edit: that test used a function generator to make nice clean pulses

[Edited on 10-11-2023 by Rainwater]

mc68k - 10-11-2023 at 14:05

Hi Rainwater!

You lost me on this last post, let me see if I understand..

You got an Arduino equivalent board and wrote some software the controls a motor.

Quote: Originally posted by Rainwater  

Test duration was 10 seconds per step
With the motor output fixed to 150ms duration "on" time each second


I don't understand this part, it sounds like you are pulsing power to the motor for 0.15 seconds, then off for 0.85 seconds?

What kind of motor are you using, and what is the motor driver?

Quote: Originally posted by Rainwater  

I compared the PCInt pulse rate to motor control timing errors and incorrect pulse counts
Pulse per second / timing error / missed counts


Sounds like you are reading some data feed from the motor (hall sensor or photo-interrupter?), and triggering an interrupt on the ATmega. Then as you speed up the motor, the Arduino doesn't see some of those pulses because it can't process the interrupts that fast.

What is generating the data feed from the motor, and how many pulses per revolution are generated?

Quote: Originally posted by Rainwater  

If the board was only controlling 1 device with feedback, we could get up to 1MHz
using a true Int pin and a 16bit hardware counter before we lose any precision.


Agreed, attaching a hardware interrupt to a counter would reduce the need for system-level interrupts to read each pulse.

Does the ATmega support interrupt driven hardware counters?

I guess I should actually read the data sheet about the CPU I'm using!

Quote: Originally posted by Rainwater  

Im hoping I can get together a BOM that doesnt require hand soldering or custom boards. Just some jumpers to pins and she'll by hot to trot


Nice! That's quick work for sure.

Quote: Originally posted by Rainwater  

Edit: that test used a function generator to make nice clean pulses


Ah, ok now I think I'm tracking. So the feedback was not from a motor at all, but an external pulse generator?

Lack of Progress:

I tried a variety of resistors for the pull-down (47, 330, 1k, 10k, 1M, 7M). All of them pulled the outputs to zero, but showed no change when interrupting the beams.

I also pulled one of the other valve's optocoupler board, just in case I had fried the first one with my fidgeting. No difference.

So I'm back to stuck on that front.

One positive note is that the second board I pulled definitively IDs the photocopiers as ROHS brand.




RoHS.jpg - 226kB

Rainwater - 10-11-2023 at 17:07

If my stuff would get delivered I'd be able to finish this in a few hours but my area
is getting hit hard with USPS stealing anything of value. We made the news more than ones this year about it.

Using the Arduino library, its should be fully Modbus V1.1 complaint.
that means it will fit right in at any of the millions of industrial sites that use this protocol.

Here is some code not ready for hardware testing yet.

There is a paper I wrote in there when I was talking to myself trying to figure out
the how to, and why this stuff.
I used it as a map to write the .ino so if you get lost in one, refer to the other.
It may cause permanent hair loss, best to read it blindfolded.

Quote:

I don't understand this part, it sounds like you are pulsing power to the motor for 0.15 seconds, then off for 0.85 seconds?

I had the "motor" output pin, connected to an oscilloscope, No motor yet.
And one of the feedback pins, connected to a PWM signal 50% duty cycle function generator.
Just to speed test how fast I could drive the ISR before it started causing lag in the
motor control code. Also while in the ISR, all other code is paused.
Including the code that keeps track of time. any time in the ISR stops the clock and adds error.
Its the only way to make this work within the $20 price range I set for myself.

With a custom board, Each pump unit would have its own MCU and hardware counters all the way.
We'd be in the MHz range before any lag showed up.
I would like this to be something everyone could afford so im cutting corners here and there.

Quote:

Then as you speed up the motor, the Arduino doesn't see some of those pulses because it can't process the interrupts that fast.

correct. The Arduino has to get in and out of the ISR as fast as possible.
if another pulse comes in while still in the ISR, it will be missed.
Quote:

Does the ATmega support interrupt driven hardware counters?

depends on the flavor of chip you have. The uno, nano, and micro all have
2-5INT pins, and I think, 3 counters(16bit, 8bit, 16bit). Each counter can be set to a
different clock source. but their used for other things, like PWM output, millis() timing etc.

Quote:

I guess I should actually read the data sheet about the CPU I'm using!

took 4 years of collage before I could do that. youtube is cheaper.
I been building PLCs and custom hardware for factorys since about '98.

Edit:
those do not look like optical sensors to me, try a magnet or piece of iron.

Edit: normally i would use a TI SN74HC590 clocked by a CD74AC14E to obtain this type of feedback without losing pulses, but that requires custom boards

[Edited on 11-11-2023 by Rainwater]

Rainwater - 12-11-2023 at 05:45

Here is some code ready for hardware testing.
Fixed the feedback not working at each boot,
Previous speed test is invalid do to a miss configuration.
have not ran it again.
Wrote the pin out for Arduino Micro and Arduino Uno R3.
Busted my budget, 1 full working pump will be about $45. with a 2 amp driver.

gave up on alibaba express

Edit:
Only got 2 more features to add before I slap a GNU GPL v3 and toss it onto gethub
Price for 1 setup without pumps and motor driver will be about $40.
Half being the micro board or Uno
I will update the ino to work of more than the arduino micro, and Uno soon
Still looking for a cheap replacement.

parts list can be found on amazon
Unfortunately with amazon, quantitys are off, you cant by just the number of items needed.
I suggest shopping around to save $$$.

After I wrap the controller for the peristaltic pumps
lets talk more about the chemputer language and additional equipment you need to run

[Edited on 13-11-2023 by Rainwater]

mc68k - 14-11-2023 at 14:41

Rainwater,

Great docs, thanks!

I'll add your BoM to my components list.

The ModBus terminology reminds me of CNC machines. The controller (GUI, command parser, etc) is separated from the driver (motion control, e-stop, etc) and they use similar register blocks, each having a set of inputs and a set of outputs that get written to by address. In the case of gcode, all of the registers are full sized integers though.

"Coils" reminds me of an industrial lathe from the 70s I worked on that used relay coils for all of its PLC programming, you could hear the relays clicking as it computed the next machine state.

Pump Program:

Code looks good, no issues reading or understanding it. There are a few parts that dive below the Arduino wrappers, I'll just assume you know what you're doing there. ;-)

I did notice the function RunPump() is given an unsigned value labeled "on", but later that unsigned value is compared against a negative number. I'm guessing you want a signed value there instead? (line 215 in my copy)

Also, is ISR() valid for Arduino? Only docs I found are for attachInterrupt(), but I see people discussing the use of ISR(), such as this thread on arduino.cc

Progress:

Not much to report, I gave up on the opto-sensors for the moment, I can still control the valve by counting steps.

I setup a valve and pump to start testing the steps-per-revolution for the valve's stepper. The valve is suspended over a reservoir, the pump will pull from the reservoir and push water into the center inlet of the valve, which then drips out of the currently selected outlet back into the reservoir.

Working on the programming for this test now.



valve_test_1.jpg - 268kB

Rainwater - 14-11-2023 at 19:58

For the ATmega series of mcu,
the toolchain includes some predefined c headers, ISR() is a #define statement that makes it easy to
sets up a void*function() pointer and automatically stores it into the appropriate register for callback.
The PCICR = Pin Change Interrupt Control Register
When enabled and triggered. calls the ISR function.
Arduino didn't make this a standard option within their API because not every mcu can do this.
This allows me to catch the feedback state of multiple pins at once.
Without this, i would only have 2 pins to use for receiving feedback

Thanks for pointing that unsigned out, i noticed on the scope that the reverse had quit working, but have not looked into it yet.
Would have had to find that the hard way when my parts show up.

I prototyped this around a dc motor, just to get the basics done.
Currently adding support for servos and steppers.
Will be doing a lot of housekeeping aswell, spliting different sections into different files,
just to clean up the mess and make porting easier.

Personal I hate having 1 box for this gadget and one for that gadget.
Im trying to make this thing run as many different motor types as I can squeeze
into the 2k of ram available
Im hoping i can get a max of 4k steps per second running a stepper.

And im already dreaming about how I can use a pump to pressurize the receiving flask in my reflux still to control takeoff ratios.

Rainwater - 17-11-2023 at 18:28

So just got home from work and some parts came in,
nano board, and max485,
still missing h-bridge, ir sensor, stepper motor

found all sorts of simple mistakes i made, got those fixed.
Found a heap stack collision hiding within the code. Fixed that
Switched to a less functional, less ram hungry, ultra fast modbus libary.
Still very compatible and functional but no longer iso standard.
Added servo and stepper motor support.
Servos work and tested over modbus,
still a few glitches needing a workout with stray pulses lasting too long.
(Likly the feedback isr blocking the stepper isr)

I haven't got the LN289 driver or stepper motor yet.
So no new observations there
but hoooked it up to the scope and got about 3-7k steps per second,
way too fast.
Have to hack the arduino stepper library and make it non blocking so speed control wont be an issue

Back to chemistry.
edit:

Link updated
still no stepper motor but with all the debug removed from the motor driver
its now capable of 28-32k steps per second on the scope
with speed control incorporated to slow it down to something reasonable
motors should be delivered this weekend, if not i can rip some out of other completed projects.
few more improvements needed.
-large amounts (>65k units) needs addressing
small amounts (<1 units) needs addressing
feedback, timer error re calculated (properly this time)
Servo position was effected with feedback above 1.8k
stepper speed begin reducing around the same feedback rate.
noted that feedback pulses occurring within a sweet spot of 5us~20us apart are
missed regardless of pulses per second. this is the ISR locked-out period.
feedback pulses have to be 20us or longer to trigger properly.

Code:
pps / time error / count error 0 / 0.001% / 0% 500 / 0.3% / 0% 1k / 0.6% / 0% 5k / 4.1% / 0% 10k / 600% / ~0.1%


Edit:
wiring diagram

PCM_drawing_schem.jpg - 309kB

[Edited on 18-11-2023 by Rainwater]

Rainwater - 18-11-2023 at 16:14

Last major update until parts come in.
A setup a structer to write custom driver code.
I included a driver for the G540 op is using..
pinout is in the _use_g540.h file.
demo sketch is setup to drive your servo at 1 rotation per second for 50 seconds.
let me know if it sets your controller on fire

mc68k - 19-11-2023 at 20:39

Rainwater - Nice progress! Can't wait to see your hardware vision realized.

I've ordered some parts off your BoM, so we will have some equivalent hardware to test with.

What are the IR sensors for? I don't see that mentioned anywhere. Looks like they are send/receive boards, so maybe wireless comms?

I'll look through the new code, sounds like you added support for steppers too.

[EDIT: Did the link change? I don't see the files you reference in the previous reply (_use_g540.h).]

Progress:

- Fixed the overheating valve stepper
- Successfully ran the valve selection test, shifting to each position in turn and pumping water through it
- Started a manual synthesis of the target molecule to test the experimental

Experimental:

Glycine + Urea -> Hydantoin:
----------------------------
1.00 g (13.32 mmol) Glycine
0.85 g (14.00 mmol) Urea

beaker.jpg - 178kB

Glycine and Urea were placed in a 10 mL beaker.
Approximately 6 mL water added and stirred until everything dissolved.
Heated in microwave (on low) for 1 minute, then stir.
Heating/stirring repeated for 10 minutes, never allowing the beaker to boil.
Beaker left overnight to cool and complete reaction.
Acidify to pH 2 by drop-wise addition of aqueous HCl 37%.
Acidified mixture poured into evaporation dish and warmed on hotplate.

acidify.jpg - 189kB

After crystals formed spontaneously the dish was left to evaporate at room temperature for 24 hours.
Crystals (still wet) were scraped together and 2 mL fresh water added to the dish, stirring the wet crystals into the fresh water to wash them.
Crystals were scraped to one side of the dish and the liquid left to evaporate again.

hydantoin_crystals.jpg - 350kB

Still waiting for the crystals to dry so I can weigh them.


[Edited on 20-11-2023 by mc68k]

Rainwater - 20-11-2023 at 04:58

Sorry,i broke the code yesterday and
im horrible about keeping backup files.
I post gethub link as soon as its fixed.

Rainwater - 21-11-2023 at 17:14

Permanent home - https://github.com/Adivinedude/PCM_Modbus
1 uno with the hardware I linked can run
4 dc motors (2amp 7-32v)
4 5v logic servos
2 stepper motors, in full steps, 2 amps, 7-32 volt, at 1.5k steps per second
4 pulse step drivers.

not all at once, but many workable combinations.

this is just version 0.1 there is a lot of room to grow.

added a pulse step mode for your G540 per their datasheet
clocked her at 5.6k steps per second.
20231121_194528.jpg - 66kB
That is a really nice driver by the way. out of my price range.
That will most likely rip the gears our of your pump if you drive it that fast.
I will add a some bits to control acceleration but will be after the holidays.

as for your overheating issue.
be sure to use the proper current setting resistor. that driver works like a current
source, at slow speeds it uses less voltage, but as speeds increases, the
impedance of the motor coils goes up, requiring more voltage to drive the load at
full current/power.
Without the proper resistor, it will overvolte the motor at lower rpm and holding states

Using my little setup, torque will be lower at high speed because an h-bridge is not
a good way to drive a stepper. it works but there are better options.
None which can operate this wide variety of motors for this price point.

Was reading though github,
they did a professional job.
https://github.com/croningp/ChemputerSoftware/tree/master

Thinking of using this little toy to mod a broken hotplate stirrer to digital controls.
Knobs keep melting off, i've put this one through a lot.

mc68k - 22-11-2023 at 11:49

Quote: Originally posted by Rainwater  
4 dc motors (2amp 7-32v)
4 5v logic servos
2 stepper motors, in full steps, 2 amps, 7-32 volt, at 1.5k steps per second
4 pulse step drivers


Perfect! I'll read the code over the holiday, looks like a lot of changes. Also, my parts have shipped, so I can replicate the setup next week-ish.


Quote: Originally posted by Rainwater  
Was reading though github, they did a professional job.
https://github.com/croningp/ChemputerSoftware/tree/master


Yes, they've been at it for many years and have published a lot of good hardware and software designs. I've only perused their code briefly, still have a few bits and pieces to work out before I can try integrating with their platform.


Quote: Originally posted by Rainwater  
Thinking of using this little toy to mod a broken hotplate stirrer to digital controls.
Knobs keep melting off, i've put this one through a lot.


I recently dismantled my manual heat plate/stirrer to see what it would take to control it using the Arduino. Not quite done with the reverse-engineering for that though, but it looks like we're both going in the same direction.


Progress:

- Splitting off the experimental thread so it won't dilute the hardware design work being done here (link).

- Got the basic 'liquid handling backbone' working, equivalent to the chemputer's use of syringe pumps:


Sensor Testing:

Totally pulling my hair out on these photo-interrupters. Does anyone see where I may have gone wrong?

I've attached a reverse-engineered wiring for the sensor board, a breadboard test circuit, and the wiring diagrams from the documentation of the photo-interrupters.

If I understand the circuit correctly, it should work like this:
- When powered with 5V, the photo-interrupter's LED (labeled A,K) will illuminate continuously.
- This will allow current to flow across the photo-interrupter's detector (labeled C,E).
- Since the collector is tied to 5V, the emitter will pass 5V until the LED is blocked.
- The output pin will read HIGH.

- Once the LED is blocked, the collector stops passing current, leaving the emitter to float.
- The floating emitter is tied to ground by a high-resistance path.
- Thus the output will read LOW.

I've tested various pull-down resistors, specifically 1K, 20K, and 1M, which I've seen mentioned in some hardware threads for similar circuits.

sensor_wiring_check.jpg - 418kB

[Edited on 22-11-2023 by mc68k]

Rainwater - 22-11-2023 at 17:45

On your drawing you have
"Input" > resistor > 'A'. Assuming "input" is Vcc to power the led, then your wiring is backwards
You have "purple wire" Gnd > resistor >anode

It doesn't matters but is convention to place resistors before the anode on leds.

Got a good meter?
1. Ohm out each channel of the resistor array. (black chip labled 151) make sure they are all equal +/- 10%
2. Switch to diode test and ring out the leds, verify orientation (cathode and anode), and record the voltage drop.

These 2 test and measurements will tell you everything you need to know to about
this circuit
For example, if the K/A voltage drop is ~2.0V and the resistor is 150ohms,
assuming a current of 10-20ma(standard current for this type of device) we can say

Vcc = resistance * current + diode voltage drop
Vcc = 150ohms * 20×10^-3 + 2v = 5v
Or 150ohms * 10ma + 2v = 3.5V.

A cool way to test an IR led is to power it, turn off all lights, and view it through a cell
phone camera. It will show up as a redish purple. Great for tv remotes.

Edit: 20k pull down resisters are kinda big and will limit the output reaction speed.
The emmitor collector capacitance will form large RC time constance.
Also, shield the device from all light sources when testing. Just in case ambient
light is an issue

[Edited on 23-11-2023 by Rainwater]

[Edited on 23-11-2023 by Rainwater]

mc68k - 24-11-2023 at 14:43

Ok.. you shamed me into getting a real ohmmeter. Had an old one that died awhile back and I've been limping along with a household voltmeter since.

Checked the resistor: 149, 149, 150, 148

Checked the diodes: You're correct they are reversed - the data sheets I found are not compatible with the parts on the board.

Verified this using my cellphone camera by powering the circuit and reversing the connections (purple = +5v, red = Gnd).

Finally wired it all back up with the Arduino and tested the inputs with a 10K resistor.

It works!

ir_success.jpg - 190kB

PCM_Modbus:

I got some time to read through the code and compile it.

When compiling using the Arduino IDE, there is a multi-definition conflict for PCINT0_vect, which is being used by the Serial library, and also for the feedback interrupts. I poked around and could get the feedback system to use the Arduino attach/detach interrupt API. Not sure if this is valid for your use case, but it got me through the compilation.

Checking the wiring diagram, the only thing I noticed was the MOSI pin seems to be used twice (ICSP MOSI -> MAX485 pins 2,3) and (D11 PWM/MOSI -> L298 U3 pin 11). I think these are the same pin?

Perhaps this is already documented, but the ModBus commands to setup various kinds of motors, and start/stop them, etc. I see one example in the debug code, but I'm not sure what combinations are valid. Ie: does a DC motor need the feedback turned on or off?


Rainwater - 24-11-2023 at 18:46

Im building it with arduino ide 2.2.1. On windows.

It will build stright from the zip file now.

D11 on the left going to the MAX485. Is labled wrong.
That is a drawing error.
For some reason they dont show A4 on the drawing and i
didnt catch that.

If you read "pins.h" lines #41-#66, it list each and every pin clearly

I will update the usage.txt with more details about how motor types can be
configured in the next few days.
In short, dc motors, servos, pulse step, each use 1 pump channel. And can be
applied in any combination.

While stepper motors use 2 pump channels and can only be configured on pump 1 and pump 3
If pump1 is configured as a stepper, you lose pump2,
if pump3 is configured as a stepper, you lose pump4

Feedback inputs are completely optional.
With feedback set to 0, Dc motors use milliseconds, pulse step and steppers use
steps. And servos currently dont do nothing with them because I haven't
implemented that as a pump yet.

If you have a flow meter, it will ether produce a pulse per unit of flow or an analog
voltage. This unit only has 1 unused pin, and its an analog, so if its needed its there.
1 analog voltage as feedback could be used, but its not currently in the program.

adjustable voltage to frequency converters are cheap, and can take that type of output and convert it into pulses.

Flow meters are so expensive, i made this bit optional because most people will not
have one.

Currently working on a console program to run all this. Will likly wire a esp32 as a
wifi modbuxTCP to modbusRTU gateway so i can watch tv and monitor reactions on
my phone.

[Edited on 25-11-2023 by Rainwater]

[Edited on 25-11-2023 by Rainwater]

mc68k - 27-11-2023 at 12:40

Stuff arrived! I'll get on the breadboard construction and test out the new code.

Rather than one controller controlling 4 pumps of various types, I'm thinking of packaging each Arduino with parts such that it can control:
- Valve (stepper + inputs)
- Stirring (DC motor)
- Hotplate (PWM)
- Thermometer
- Pump (stepper)

This would simplify my setup because I can design one box containing all the components needed (resistors, knobs, plugs) to run any piece of equipment. Then deploying new equipment (valve, hotplate, etc) is just plugging it in to the appropriate free port on one of the control boxes and adjusting the config files to describe what equipment is connected.



some_hardware.jpg - 411kB

mc68k - 30-11-2023 at 18:36

It lives!

Excellent work Rainwater, the latest code ran right out of the box. Had a bad motor driver (L298), did a bit of code debugging only to discover it's a bad board, ugh!

Haven't attached the ModBus board yet, the pins are labeled differently from your schematic.

Pins on board: DI, DE, RE, RO

I'm assuming the pins are RO->RX, DI->TX, and DE/RE tied together, but to which pin? Still using MOSI?

Also, do all ModBus devices tie their pin 'A's together and all the pin 'B's tied together (like a bus), or are they plugged in serially (like pin A of device1 goes to pin B of device2, etc)?

Thanks, this will accelerate the project nicely!

breadboard.jpg - 386kB

Rainwater - 1-12-2023 at 02:36

Quote: Originally posted by mc68k  
It lives!I'm assuming the pins are
RO->RX, DI->TX, and DE/RE tied together, but to which pin?

https://github.com/Adivinedude/PCM_Modbus/blob/main/sketch_P...
Code:
for the ATmega328p RS485_TX 1 // PD1 RS485_RX 0 // PD0 RS485_DERE 18 // A4 PC4

Pinout-NANO_latest.png - 271kB

Quote:
Also, do all ModBus devices tie their pin 'A's together and all the pin 'B's tied
together
yes
Be sure to use a common ground between your controller and devices. Earth ground
should work. Ensure ground resistance between all devices is less than 100 ohms.
This will prevent common mode offsets that will damage the MAX485 above
15v/-15v and eliminates a lot of transmission noise.
If earth ground is unacceptable, using a 3 wire communication cable to carry the
ground will fix this.

[Edited on 1-12-2023 by Rainwater]

Rainwater - 8-12-2023 at 19:13

Its just a shell right now, gonna start adding communication functionality here soon.
I been working on the PCM_Modbus code by hand writing request, not fun.
I slapped this together while I recovered from the flu. should be working soon.

Currently taking request for features
    ToDo List:
  1. Translate modbus addresses into readable names
  2. Spotlight Changed Values
  3. Implement Command Passthrough
  4. Pick better colors


PCM_Modbus Demo app.jpg - 136kB

mc68k - 9-12-2023 at 11:54


Chemputer Hardware:

chemputer_9_dec_23_marked.jpg - 467kB

Code:
Red (center) : Arduino Nano microcontroller Orange (top) : G540 stepper driver Yellow (left): L298 DC motor driver board (top) + peristaltic pump (bottom) Green (right): Liquid port selector valve (top) + peristaltic pump (bottom) Blue (bottom): PWM to A/C dimmer board to control a hotplate Purple (ctr) : MAC485 ModBus port for communication and rotary knob for address selection


Chemputer Progress:

- Rainwater's code controls all the pumps and ModBus communications.
- My valve control code is separate, not yet integrated with Rainwater's state machine.
- I added a simple serial command parser to turn on/off the various components.
- I replaced the POT with a rotary knob, which is more precise, and has a button for selection.
- The board on the bottom (blue) is new and hasn't been tested yet. It should allow the Arduino to control a hotplate using a single PWM pin! (https://www.amazon.com/dp/B06Y1DT1WP)
- I reserved the I2C pins for a few peripheral boards that should round out the package: LCD display, data logger, and balanced PT100 temperature sensor board.

So this tangle of wires represents an almost-complete controller module! It's only missing the temperature sensor.

The expectation is that a chemputer would consist of several of these controllers, each controlling a reaction vessel (with hotplate, stirring, temperature sensor) and add additional capacity to the liquid handling backbone (6 ports and a pump).

My target is 3 of these modules - that will enable control of the main reactor, filter module, and liquid/liquid separator. It also allows selection among (6*3=18) ports. Although some ports are reserved, and some ports are used to connect the valves to each other.

The main valve has water, gas, vacuum, and waste connected to four of its ports. The last two ports connect to the other two valves. This means there's really only 12 ports available.

Destination modules:
- Reactor
- Filter
- Separator

The remaining 9 ports are available for reagents.


Rainwater,

I like the colors! Very cool and soothing.

The console app looks great, that will be very useful for testing and debugging. The changed-value highlighting would be especially amazing.

I agree that sending ModBus commands "by hand" is aggravating. I resorted to writing individual test functions and invoking them through the Arduino serial port. For example, typing "+0" turns on pump 0, while "-0" turns it off, and "S0100" where 'S' means 'set speed', the first 0 is the pump number, and the last 3 digits is the desired speed.


Rainwater - 19-12-2023 at 17:28

Ive got the console app about 95% complete.
Its turned into a small scall project all its own.
Almost 3k lines of code.

But i have discovered limitations in the PCM which i have gotten on my nerves.
When using a dc motor, setting calibration to 1000
the maxium time the motor can run is 65 seconds.
If you attempt to run it longer, the controller sets the error flag because the highest
it can count is 216 or 65536.
Im going to make changes to the addresses to that the PCM can report back a 32bit value.
This will extended the run time with 1ms resolution up to 49 days.

Second nerve twitching thing I noticed, after keeping my head in the console app,
the Arduino firmware is harder to read and follow.
Gonna rewrite all that to make it easier.
Im not sure how well the arduino compiler will optimize class resources.
Given its an incomplete instruction set. We will see. Normally with mcu's
The overhead of managing an object structure with vtables is not worth it.

Once thats done, speed control and a script interpreter are next on the list.

[Edited on 20-12-2023 by Rainwater]

Rainwater - 20-12-2023 at 17:47

Finally, that was a real pain in the ass. just under 32 hundred lines, but i'm pleased with it.
https://github.com/Adivinedude/Modbus_Client
Merry Christmas, let me know if you have trouble building it.
Quick Video

[Edited on 22-12-2023 by Rainwater]

Rainwater - 29-12-2023 at 18:39

Quote: Originally posted by mc68k  
.
- My valve control code is separate, not yet integrated with Rainwater's state machine.

Just posted a major revision to the PCM firmware. It is a lot easier to read now.
Adding drivers is much simpler to.
Let me know what you need it to do, and i'll get a driver wrote up.

VincenzoTheGreat - 13-11-2024 at 16:47

what make/model is the valve selector? $35 on ebay sounds like a steal, I wouldn't mind grabbing one or two myself.