Atlas Scientific Hydroponic Barebones Kit w/ FireBeetle Covers - DFRobot DC Motor & Stepper Driver

Discuss garden automation systems and software here, including commercial products or Raspberry Pi and Arduino DIY setups.
Post Reply
GreenThumb
LED-Curious
LED-Curious
Reactions:
Posts: 13
Joined: Mon Oct 04, 2021 8:51 pm

Hey there! I had no idea there were all these people messing around with sensors
and stuff on a forum. So much win! Really excited I thought I was alone with all this.

I got this Atlas Scientific kit, with 2 PH and 1 EC sensors:
https://atlas-scientific.com/kits/bb-wi-fi-hkit/
Image

I managed to pretty easily get the sensors working and write my own sketch...
even got calibration working no problems!

Then I got this little bad boy motor control board
https://wiki.dfrobot.com/FireBeetle_Cov ... KU_DFR0508
Image

I was able to run the example sketch for this no issues...


Ok so to the meat and potatoes...
When I combine the code for both the motors don't work properly.
It seems to get stuck when the sketch sends the i2c command(s) to the motor board's
ST8 chip to "start the motor hardware" whatever the f that means. This motor1.init()
command I'm talking about is usually put into void setup()... kinda run once in the
sketch to "turn on" the motors.

Since the motor board has an ST8 chip, it's kind of like a small arduino-type device in itself.
Which I guess means it has it's own "sketch" as it were on it.... which I have no access
to because I'm not an employee of DFRobot.

Here's what I tried:
- Disabled each EZO sensor one by one, found that only the EC sensor is causing the issue with the motors.
- Moved the pump initialization command out of the setup loop and into a function, complete with shutdown commands after pump turns off. That helped, and even got me to an almost working system.
- Tried adding in an i2c bus clear function, have zero idea if it had any hope of working but it didn't seem to do anything,
- I tried to reorder the logic in my code until it worked better and better but eventually I couldn't get it to reliably turn on and off repeatedly.

I think, the next thing to try is to make a copy of the motor.init(); command from the DFRobot motor library into my sketch and modify it until I can find a combination of something that works.
Last edited by GreenThumb on Wed Oct 06, 2021 5:05 am, edited 1 time in total.
Shimbob
LED Wizard
LED Wizard
Reactions:
Posts: 642
Joined: Mon Nov 27, 2017 11:29 pm

I was wondering if the EC sensor was maybe sharing GPIO with the i2c bus, but it doesn't appear so.

I found this note:
"Note that the I2C pins do not have pullup resistors already! You must add them if you want to communicate with an I2C device"
https://learn.adafruit.com/adafruit-huz ... er/pinouts
Is your i2c pin pulled up? Probably a long shot.
GreenThumb
LED-Curious
LED-Curious
Reactions:
Posts: 13
Joined: Mon Oct 04, 2021 8:51 pm

Good catch, and thank you for trying but I already am using one of these so the pins are pulled up. I thought something like that as the ezo circuits use a pin:

Atlas Sensor Bridge I2c
https://atlas-scientific.com/carrier-b ... or-bridge/
Image


I tried again last night to extract the I2c commands from the library and run them manually but it gave the same results. Since the motor board has an ST8 chip controlling the motor chips I suspect that the ST8 has its own sketch on it that I can’t see since it came factory installed. Once dfrobot is back from Chinese New Year or whatever they are doing I’ll see what they can do.

In the meantime I ordered an I2c io breakout to deliver before end of day today. Long term I’ll work on getting that dfrobot shield working but for now I’ll settle for my own pwm wires.

It’s too bad I couldn’t make it work by using the I2c commands directly from the library function. I feel like the I2c bus is stuck on a step like asking for status on a motor or something. It’s so weird
GreenThumb
LED-Curious
LED-Curious
Reactions:
Posts: 13
Joined: Mon Oct 04, 2021 8:51 pm

I added a bunch of serial print commands to the library to figure out what it’s stuck on. It seemed to be stuck at that initialization command.

It sends the initial commands to startup the pump, and that should display Version: and Product: bytes from the motor board over I2c..... but instead of returning the values we expect it’s returning FF for both.

So that right away it can’t even initialize properly, then it gets stuck in a loop waiting for the motor board to return the read command that matches the initialization code but the code never comes. So it keep writing a byte over and over but never gets the return byte it needs.
GreenThumb
LED-Curious
LED-Curious
Reactions:
Posts: 13
Joined: Mon Oct 04, 2021 8:51 pm

Well so I disconnected the dfrobot drive for now and have this four channel mosfet board hooked up. Till try out the gpio expander later today with it and see. It’s essentially what I want just was trying to avoid the extra pwm wires but no big deal.

If it works I guess I’ll just not use the dfmotor board. I can use those for other projects like motorized blinds.
GreenThumb
LED-Curious
LED-Curious
Reactions:
Posts: 13
Joined: Mon Oct 04, 2021 8:51 pm

I wanted to do something quick, so I bought one of these from Amazon:
Image
https://www.amazon.ca/NUOYI-MCP23017-Ex ... s9dHJ1ZQ==

So it works flawlessly, just no speed control (PWM). So sort of like a silent relay board.
I'm using that blue four channel.
Here's the sketch I wrote, seems to work. Dunno if it's the smartest way to do it lol.

Code: Select all

#include <Ezo_i2c.h> //include the EZO I2C library from https://github.com/Atlas-Scientific/Ezo_I2c_lib
#include <Wire.h>    //include arduinos i2c library
#include <Ezo_i2c_util.h> //brings in common print statements
#include "MCP23017.h"

Ezo_board PH = Ezo_board(98, "PH");       //create a PH circuit object, who's address is 98 and name is "PH"
Ezo_board PH2 = Ezo_board(99, "PH2");       //create a PH circuit object, who's address is 99 and name is "PH2"
Ezo_board EC = Ezo_board(97, "EC");      //create an EC circuit object who's address is 97 and name is "EC"

//enable pins for each circuit
const int EN_PH = 13;
const int EN_EC = 12;
const int EN_PH2 = 27;

// i2c expander
MCP23017 mcp;
int magneticStirrers = 15;
int partApump = 14;
int partBpump = 13;
int pHPump = 12;

// dose variables
int pumpsActive = 1;
int slowPumps = 1;
float ECsetPoint = 10000;
float PHsetPoint = 5.8;
float PHval;
float PH2val;
float ECval;
int ECtoAdd;
int ADose;
int BDose;


void setup() {

  Serial.begin(9600);
    mcp.begin(7);
    mcp.pinMode(magneticStirrers, OUTPUT);
    mcp.pinMode(partApump, OUTPUT);
    mcp.pinMode(partBpump, OUTPUT);
    mcp.pinMode(pHPump, OUTPUT);
    mcp.digitalWrite(partApump, LOW);
    mcp.digitalWrite(partBpump, LOW);
    mcp.digitalWrite(pHPump, LOW);
    mcp.digitalWrite(magneticStirrers, LOW);
    
  pinMode(EN_PH, OUTPUT);                                                         //set enable pins as outputs
  pinMode(EN_EC, OUTPUT);
  pinMode(EN_PH2, OUTPUT);
  digitalWrite(EN_PH, LOW);                                                       //set enable pins to enable the circuits
  digitalWrite(EN_EC, LOW);
  digitalWrite(EN_PH2, LOW);
  delay(3000);
  Serial.println(" ");
  Serial.println(" ");
  Serial.println("  ");
  Serial.println("=======================================");
  Serial.println("|                                     |");
  Serial.println("|        Irrigation Controller        |");
  Serial.println("|                                     |");
}

void loop() {
  doseNutrients();
}

// ===== FUNCTIONS ===== //



void doseNutrients() {
  Serial.println("========Starting Dosing Program========");
  checkEC();
  checkPH();
  Serial.print("Current EC: "); Serial.println(ECval);
  Serial.print("Current pH: "); Serial.println(PHval);
  ECtoAdd = ECsetPoint - ECval;
  ADose = (ECtoAdd * .6) + ECval;

  if (ADose > ECval) {
    Serial.println("-------- >>> EC too low! <<< ----------");
    Serial.println(">> Beginning nutrient dosing routing - - - - - - Please Standby");
    Serial.print("EC to add: "); Serial.println(ECtoAdd);
    Serial.println("---------- Beginning A Dosing ---------");

  DosingA:
    if (pumpsActive > 0) {mcp.digitalWrite(partApump, HIGH);};
    if (slowPumps > 0) {delay(1000);mcp.digitalWrite(partApump, LOW);};
    checkEC();
    Serial.print("Add A until: "); Serial.print(ADose); Serial.print(" - Current EC: "); Serial.println(ECval);
    Serial.println("........................................");
    if (ADose > ECval) {
      goto DosingA;
    } else {
      if (pumpsActive > 0) {mcp.digitalWrite(partApump, LOW);};
      Serial.println("............ A dosing complete..........");
      Serial.println("---------- Beginning B Dosing ---------");

    DosingB:
      if (pumpsActive > 0) {mcp.digitalWrite(partBpump, HIGH);};
      if (slowPumps > 0) {delay(1000);mcp.digitalWrite(partBpump, LOW);};
      checkEC();
      Serial.print("Add B until: "); Serial.print(ECsetPoint); Serial.print(" - Current EC: "); Serial.println(ECval);
      Serial.println("........................................");

      if (ECsetPoint > ECval) {
        goto DosingB;
      } else {
        if (pumpsActive > 0) {mcp.digitalWrite(partBpump, LOW);};
        Serial.println("............ B dosing complete..........");
        Serial.println("---------- Beginning pH Dosing ---------");

      DosingPH:
        if (pumpsActive > 0) {mcp.digitalWrite(pHPump, HIGH);};
        if (slowPumps > 0) {delay(1000);mcp.digitalWrite(pHPump, LOW);};
        checkPH();
        Serial.print("Add pH down until: "); Serial.print(PHsetPoint); Serial.print(" - Current PH: "); Serial.println(PHval);
        Serial.println("........................................");

        if (PHval > PHsetPoint) {goto DosingPH;} 
        else {
          if (pumpsActive > 0) {mcp.digitalWrite(pHPump, LOW);};
          Serial.println("............ pH dosing complete..........");
          Serial.println("--------- Ending dosing routine ---------");
        }
      }
    }
  }
}

void checkEC() {
  delay(600);
  EC.send_read_cmd();
  delay(600);
  EC.receive_read_cmd();
  delay(600);
  ECval = EC.get_last_received_reading();
  delay(600);
}

void checkPH() {
  delay(600);
  PH.send_read_cmd();
  delay(900);
  PH.receive_read_cmd();
  delay(900);
  PHval = PH.get_last_received_reading();
  delay(900);
}

void calibratePH() {

}
GreenThumb
LED-Curious
LED-Curious
Reactions:
Posts: 13
Joined: Mon Oct 04, 2021 8:51 pm

Well it’s been working using that yellow/blue board without speed control. This is great.

That was an interesting learning experience.
Post Reply