Skip to content

Instantly share code, notes, and snippets.

@mngyuan
Created April 21, 2022 22:21
Show Gist options
  • Save mngyuan/f7407d37b65deec2130c3e4d9979c8bd to your computer and use it in GitHub Desktop.
Save mngyuan/f7407d37b65deec2130c3e4d9979c8bd to your computer and use it in GitHub Desktop.
SD_Card_Sensors.ino merged with Motors_Radio_Controller.ino
// @mngyuan: below follows a list of what i did
// copied definitions from Motors_Radio_Controller to top section of file
// copied setup() from Motors_Radio_Controller into setup() function
// copied loop() from Motors_Radio_Controller into loop() function
// changed value of CURRENT_SEN_1 and EN_PIN_1 to not clash with SD card code
// commented extra Serial.begin() from SD card's setup()
// formatted code with clang-format set to Google config
//
// notes:
// * the sd card code hardcodes pin 53 as your SS pin, but it varies based on
// which arduino board you're using, so you may need to change it
// * MOSI and MOSI pins from the SD card code overlap pins with the
// MOTOR_CH_IN_PIN_* pins, but MISO and MOSI seem unused. i would
// recommend changing MOTOR_CH_IN_PIN_* to start at say 17 or
// something, wherever you have free pins if you have issues
// (the motor code doesnt explain what ch1,ch2, etc are for
// so i picked the best names i could)
// * any time you use a raw number for a pin in a complex sketch
// it's a bug waiting to happen, which is why i named most raw
// pin values. you can check by searching for pin usages
// (digitalWrite, pulseIn, pinMode) or after you've named them
// just by searching for "PIN"
/*
SD card read/write
This example shows how to read and write data to and from an SD card file
The circuit:
* SD card attached to SPI bus as follows:
** MOSI - pin 11
** MISO - pin 12
** CLK - pin 13
** CS - pin 4
created Nov 2010
by David A. Mellis
modified 9 Apr 2012
by Tom Igoe
This example code is in the public domain.
*/
#include <SD.h>
/* pH definitions */
#define SensorPin \
A2 // the pH meter Analog output is connected with the Arduino’s Analog
/* TDS definitions & variables */
#include "GravityTDS.h"
#include <DallasTemperature.h>
#include <EEPROM.h>
#include <LiquidCrystal.h>
#include <OneWire.h>
#define ONE_WIRE_BUS 7
#define TdsSensorPin A1
// @mngyuan: named this to avoid using raw numbers to make future pin clashing
// more obvious
#define SD_CLK_PIN 13
OneWire oneWire(ONE_WIRE_BUS);
GravityTDS gravityTds;
DallasTemperature sensors(&oneWire);
float tdsValue = 0;
/* Turbidity variables */
float voltage;
/* SD card file variable */
File myFile;
/* pH Test variables */
unsigned long int avgValue; // Store the average value of the sensor feedback
float b;
float phValue;
int buf[10], temp;
/* Time variables */
const unsigned long eventInterval = 3000;
unsigned long previousTime = 0;
/* Turbidity time variables */
unsigned long turbidityInitialMillis = 0;
unsigned long turbidityDelay = 500; // set to length of first interval.
/* pH time variables */
unsigned long phInitialMillis = 0;
unsigned long phDelay = 800; // set to length of first interval.
/**************************
* motor definitions
**************************/
/*
RC PulseIn Serial Read out
By: Nick Poole
SparkFun Electronics
Date: 5
License: CC-BY SA 3.0 - Creative commons share-alike 3.0
use this code however you'd like, just keep this license and
attribute. Let me know if you make hugely, awesome, great changes.
*/
// Radio controller variables
int ch1; // Here's where we'll keep our channel values
int ch2;
int ch3;
int ch4;
// monster motor shield variables
#define BRAKE 0
#define CW 1
#define CCW 2
#define CS_THRESHOLD \
15 // Definition of safety current (Check: "1.3 Monster Shield Example").
// MOTOR 1
#define MOTOR_A1_PIN 7
#define MOTOR_B1_PIN 8
#define PWM_MOTOR_1 5
#define CURRENT_SEN_1 A5
#define EN_PIN_1 A3
#define MOTOR_1 0
short usSpeed = 150; // default motor speed
unsigned short usMotor_Status = BRAKE;
// @mngyuan: named these so future clashes are more obvious if there are any
#define MOTOR_CH_IN_PIN_1 9
#define MOTOR_CH_IN_PIN_2 10
#define MOTOR_CH_IN_PIN_3 11
#define MOTOR_CH_IN_PIN_4 12
// monster motor shield functions
void Stop() {
Serial.println("Stop");
usMotor_Status = BRAKE;
motorGo(MOTOR_1, usMotor_Status, 0);
}
void Forward() {
Serial.println("Forward");
usMotor_Status = CW;
motorGo(MOTOR_1, usMotor_Status, usSpeed);
}
void Reverse() {
Serial.println("Reverse");
usMotor_Status = CCW;
motorGo(MOTOR_1, usMotor_Status, usSpeed);
}
void motorGo(uint8_t motor, uint8_t direct,
uint8_t pwm) // Function that controls the variables: motor(0 ou
// 1), direction (cw ou ccw) e pwm (entra 0 e 255);
{
if (motor == MOTOR_1) {
if (direct == CW) {
digitalWrite(MOTOR_A1_PIN, LOW);
digitalWrite(MOTOR_B1_PIN, HIGH);
} else if (direct == CCW) {
digitalWrite(MOTOR_A1_PIN, HIGH);
digitalWrite(MOTOR_B1_PIN, LOW);
} else {
digitalWrite(MOTOR_A1_PIN, LOW);
digitalWrite(MOTOR_B1_PIN, LOW);
}
analogWrite(PWM_MOTOR_1, pwm);
}
}
/**************************
* END motor definitions
**************************/
/* Sensor Functions */
int turbidityFunction() {
int sensorValue = analogRead(A0); // read the input on analog pin A0:
voltage =
sensorValue * (5.0 / 1024.0); // Convert the analog reading (which goes
// from 0 - 1023) to a voltage (0 - 5V):
Serial.println("Turbidity recorded");
unsigned long currentTurbidityMillis = millis();
if (currentTurbidityMillis - turbidityInitialMillis >= turbidityDelay) {
Serial.println("Returning voltage");
return voltage;
}
return voltage;
}
int tdsTempFunction() {
sensors.requestTemperatures();
gravityTds.setTemperature(sensors.getTempCByIndex(
0)); // set the temperature and execute temperature compensation
gravityTds.update(); // sample and calculate
tdsValue = gravityTds.getTdsValue(); // then get the value
Serial.println("TDS recorded");
return tdsValue;
}
int phReaderFunction() {
for (int i = 0; i < 10;
i++) // Get 10 sample value from the sensor for smooth the value
{
buf[i] = analogRead(SensorPin);
// delay(10);
}
for (int i = 0; i < 9; i++) // sort the analog from small to large
{
for (int j = i + 1; j < 10; j++) {
if (buf[i] > buf[j]) {
temp = buf[i];
buf[i] = buf[j];
buf[j] = temp;
}
}
}
avgValue = 0;
for (int i = 2; i < 8; i++) // take the average value of 6 center sample
avgValue += buf[i];
phValue =
(float)avgValue * 5.0 / 1024 / 6; // convert the analog into millivolt
phValue = 3.5 * phValue; // convert the millivolt into pH value
digitalWrite(SD_CLK_PIN, HIGH);
unsigned long currentPhMillis = millis();
if (currentPhMillis - phInitialMillis >= phDelay) {
Serial.println("Returning pH");
digitalWrite(SD_CLK_PIN, LOW);
return phValue;
}
}
void setup() {
/***************** BEGIN motor setup ******************/
// radio controller setup
pinMode(MOTOR_CH_IN_PIN_1, INPUT); // Set our input pins as such
pinMode(MOTOR_CH_IN_PIN_2, INPUT);
pinMode(MOTOR_CH_IN_PIN_3, INPUT);
pinMode(MOTOR_CH_IN_PIN_4, INPUT);
Serial.begin(9600);
// monster motor shield setup
pinMode(MOTOR_A1_PIN, OUTPUT);
pinMode(MOTOR_B1_PIN, OUTPUT);
pinMode(PWM_MOTOR_1, OUTPUT);
pinMode(CURRENT_SEN_1, OUTPUT);
pinMode(EN_PIN_1, OUTPUT);
Serial.println("Begin motor control");
/***************** END motor setup ******************/
/* SD card code setup */
// Open serial communications and wait for port to open:
// Serial.begin(9600);
while (!Serial) {
; // wait for serial port to connect. Needed for Leonardo only
}
Serial.print("Initializing SD card...");
// On the Ethernet Shield, CS is pin 4. It's set as an output by default.
// Note that even if it's not used as the CS pin, the hardware SS pin
// (10 on most Arduino boards, 53 on the Mega) must be left as an output
// or the SD library functions will not work.
pinMode(53, OUTPUT);
if (!SD.begin(53)) {
Serial.println("initialization failed!");
return;
}
Serial.println("initialization done.");
/* TDS code setup below */
sensors.begin();
gravityTds.setPin(TdsSensorPin);
gravityTds.setAref(
5.0); // reference voltage on ADC, default 5.0V on Arduino UNO
gravityTds.setAdcRange(1024); // 1024 for 10bit ADC;4096 for 12bit ADC
gravityTds.begin(); // initialization
}
void loop() {
/* Set the time at the start of the loop so that we can record the time of the
* recordings every 3000ms */
unsigned long currentTime = millis();
if (currentTime - previousTime >= eventInterval) {
/* TDS & Temperature Sensor Code Below */
tdsTempFunction();
/* pH Sensor Code Below */
phReaderFunction();
/* Turbidity Sensor Code Below */
turbidityFunction();
/* Write to SD card code below */
// open the file. note that only one file can be open at a time,
// so you have to close this one before opening another.
myFile = SD.open("test.txt", FILE_WRITE);
// if the file opened okay, write to it:
if (myFile) {
Serial.print("Writing to test.txt...");
// print sensor output to SD card
myFile.print("The time elapsed is: ");
myFile.println(currentTime);
myFile.print("TDS Value: ");
myFile.print(tdsValue, 0);
myFile.println("ppm");
myFile.print("Temperature is: ");
myFile.println(sensors.getTempCByIndex(0));
myFile.print("pH reading: ");
myFile.println(phValue, 2);
myFile.print("Turbidity value: ");
myFile.println(voltage);
myFile.println(" ");
// close the file:
myFile.close();
Serial.println("done.");
} else {
// if the file didn't open, print an error:
Serial.println("error opening test.txt");
}
/*
* If we need to read the SD card, use the below code:
// re-open the file for reading:
myFile = SD.open("test.txt");
if (myFile) {
Serial.println("test.txt:");
// read from the file until there's nothing else in it:
while (myFile.available()) {
Serial.write(myFile.read());
}
// close the file:
myFile.close();
} else {
// if the file didn't open, print an error:
Serial.println("error opening test.txt");
}
*/
/* Update the timing for the next time around */
previousTime = currentTime;
}
/***************** BEGIN motor loop ******************/
// this piece of code is imperative to making the motor work
digitalWrite(EN_PIN_1, HIGH);
// radio controller loop code
ch1 = pulseIn(MOTOR_CH_IN_PIN_1, HIGH); // Read the pulse width of
ch2 = pulseIn(MOTOR_CH_IN_PIN_2, HIGH); // each channel
ch3 = pulseIn(MOTOR_CH_IN_PIN_3, HIGH);
ch4 = pulseIn(MOTOR_CH_IN_PIN_4, HIGH);
// removed the below from the 3rd parameter of the above pulseIn functions
//, 2500000
// Printing the channel values to the Serial Monitor
Serial.print("Channel 1:"); // Print the value of
Serial.println(ch1); // each channel
Serial.print("Channel 2:");
Serial.println(ch2);
Serial.print("Channel 3:");
Serial.println(ch3);
Serial.print("Channel 4:");
Serial.println(ch4);
// monster motor shield loop code
if (ch3 == 0 && ch4 == 0) {
Stop();
} else if (ch3 != 0) {
Forward();
} else if (ch4 != 0) {
Reverse();
} else {
Serial.println("ch3 and ch4 are not receving input.");
}
/***************** END motor loop ******************/
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment