Arduino programming

Mak'er Grow

Well-Known Member
I haven't looked through your code yet my head is splitting, but if you are using a device over SPI (serial peripheral interface) that has MOSI, MISO, SCK, , SS, GND, VCC on an Arduino Mega they use different pins then an Arduino Uno.

Specifically MISO=50, MOSI=51, SCK=52 and SS=53. You can also just connect it straight to the ICSP header but documentation is uh confusing if you're not a pro at all of this (I am not, I am telling you this from my own headaches in experience).

You never said what you're problem is though? Does your code actually work? If not where and what errors is it spitting out?

If it fits on the controller optimization isn't really that important, unless you're going to be like selling these or something. But if it works and fits thats all that matters.

I can PM you my gardener's microcontroller code if you want but TBH all you really need to know how to do is load the correct libraries into the arduino IDE and they all come with a bunch of example codes that you can just copy/paste and modify a few variable names, function calls etc.

If you are planning to use a camera module and save pictures onto an SD card I *highly* recomend that you get something like an adafruit data logging shield. I have tried to do it with just the parts (SD card reader and an RTC) but it is truly a PITA that requires you resoldering a point on the SD card reader because they're generally not wired to work out the box on SPI connected to an RTC.
I'm using a Mega 2650...started with an Uno, but ran out of space quickly when I got the LCD shield and upgradded to the Mega.

As for the ICSP header I'm using a few pins from it for other things...power to the I2C sensors and the reset pin for them too...instead of soldering lines on the mega directly.

The problem I'm having is I see long lists of similar lines and got to wondering if it possible to shorten them down in to some smaller routines of sorts. Also clean up any other things that could become problem(s).
Previously I was having a bit of trouble with loosing about 7 minutes a day on the clock for some reason until I added WTD and an hourly resync to the RTC...if it fails a resync 5 times the whole thing resets which brings back time properly and seems to work, but my mind wonders if theres a better way to do this...lol
The code does work as is tho...turns lights on and off...pumps...reads humidity and temps...reads info from files on the SD card for the data for timers or if not found then it defaults to what has been preset in the code...simple things.
I'm just working now on the touch screens and buttons to make changes of values and also figure out how to re-write the SD data that matches it.
Looking for a solution to keeping button screen(s) wait for some input...they just show now and then code goes back to main screen even without a button choice...think I have a solution...I'll be trying it later today/tonight. :)

I do that exact thing...using the examples and code for the net...alter things to figure out how it works and then implement it in to my code...so learning has been kind of slow here and there, but I'm getting better...I think...lol

As for the data logging shield...theLCD screen has a micro SD slot built into in and my RTC is another shield...I did get some data logging working before so I figured it should work basically the same for pics...the only trouble for the cams I see right now is I've read the ones I bought are non-fifo and need something extra to work as well as some lines converted from 5v to 3.3v or something like that, but I'll deal with all that after.:)
 

solakani

Well-Known Member
How about a switch construct?

switch (string(varname)){
case "b1PlantName": b1PlantName = varValue; break;
case "b1LightStart": L1_S = varValue.toInt(); break;
case "b1LightEnd": L1_E = varValue.toInt(); break;
case "b1PumpStart": P1_S = varValue.toInt(); break;
case "b1PumpRun": P1_R = varValue.toInt(); break;
case "b1PlantName": b2PlantName = varValue; break;
case "b2LightStart": L2_S = varValue.toInt(); break;
case "b2LightEnd": L2_E = varValue.toInt(); break;
case "b2PumpStart": P2_S = varValue.toInt(); break;
case "b2PumpRun": P2_R = varValue.toInt(); break;
case "b3PlantName": b3PlantName = varValue; break;
case "b3LightStart": L3_S = varValue.toInt(); break;
case "b3LightEnd": L3_E = varValue.toInt(); break;
case "b3PumpStart": P3_S = varValue.toInt(); break;
case "b3PumpRun": P3_R = varValue.toInt(); break;
case "b4PlantName": b4PlantName = varValue; break;
case "b4LightStart": L4_S = varValue.toInt(); break;
case "b4LightEnd": L4_E = varValue.toInt(); break;
case "b4PumpStart": P4_S = varValue.toInt(); break;
case "b4PumpRun": P4_R = varValue.toInt(); break;
}
 

solakani

Well-Known Member
This line sets up which pins to use on the LCD shields, ordered 2 the same, but seller did a swap on me...got refunded so no big prob...lol,, and I added the touch pins as well. This could/should be 2 lines...I just put it into 1 line for space really.
Is there a problem that can happen by doing this?
Do you have any sites that can help me understand more about using "OOP with classes"...don't want to waste time reading something useless...lol
I would look at UTFT.cpp to see how the classes are defined.
 

Mak'er Grow

Well-Known Member
How about a switch construct?

switch (string(varname)){
case "b1PlantName": b1PlantName = varValue; break;
case "b1LightStart": L1_S = varValue.toInt(); break;
case "b1LightEnd": L1_E = varValue.toInt(); break;
case "b1PumpStart": P1_S = varValue.toInt(); break;
case "b1PumpRun": P1_R = varValue.toInt(); break;
case "b1PlantName": b2PlantName = varValue; break;
case "b2LightStart": L2_S = varValue.toInt(); break;
case "b2LightEnd": L2_E = varValue.toInt(); break;
case "b2PumpStart": P2_S = varValue.toInt(); break;
case "b2PumpRun": P2_R = varValue.toInt(); break;
case "b3PlantName": b3PlantName = varValue; break;
case "b3LightStart": L3_S = varValue.toInt(); break;
case "b3LightEnd": L3_E = varValue.toInt(); break;
case "b3PumpStart": P3_S = varValue.toInt(); break;
case "b3PumpRun": P3_R = varValue.toInt(); break;
case "b4PlantName": b4PlantName = varValue; break;
case "b4LightStart": L4_S = varValue.toInt(); break;
case "b4LightEnd": L4_E = varValue.toInt(); break;
case "b4PumpStart": P4_S = varValue.toInt(); break;
case "b4PumpRun": P4_R = varValue.toInt(); break;
}
I like this command...just looked it up and I'm gonna try to implement it...thanks :)
If you look theres a pattern of sorts. This is an area I wondered if loops could be used. There are 4 tents/boxes being controlled hense it repeats 4 times and the number is the only different...20 lines down to like 10-ish...lol
 

Mak'er Grow

Well-Known Member
I would look at UTFT.cpp to see how the classes are defined.
I remember using this library awhile back...I think 1 of my LCDs wouldn't work with it,the now broken one, and the lib I use is a little smaller I think too and seems fairly simple to use, only issue is just 2 fonts, big or small...lol
 

solakani

Well-Known Member
I remember using this library awhile back...I think 1 of my LCDs wouldn't work with it,the now broken one, and the lib I use is a little smaller I think too and seems fairly simple to use, only issue is just 2 fonts, big or small...lol
You are still using UTFT. Look in UTFT.cpp for InitLCD. You will find that it is expecting one byte orientation. This is an example of OOP

myGLCD.InitLCD(0); //0=Portrait 1=Landscape (default) ??=Rotate 90' (90/180/270)
myGLCD.clrScr();
 

Mak'er Grow

Well-Known Member
You are still using UTFT. Look in UTFT.cpp for InitLCD. You will find that it is expecting one byte orientation. This is an example of OOP

myGLCD.InitLCD(0); //0=Portrait 1=Landscape (default) ??=Rotate 90' (90/180/270)
myGLCD.clrScr();
The 2 look and act the same really.....mine is prob a knock off...lol
Just started looking at ccp files and figure them out also...maybe I'll edit the one I'm using to use everything in the cpp rather then the sketch too and slim them down to basics I need for my sketch...ummm...lol
 
Last edited:

Mak'er Grow

Well-Known Member
I like this command...just looked it up and I'm gonna try to implement it...thanks :)
If you look theres a pattern of sorts. This is an area I wondered if loops could be used. There are 4 tents/boxes being controlled hense it repeats 4 times and the number is the only different...20 lines down to like 10-ish...lol
Just quickly threw this together, but I get error about string not declared...tried the String also same...get an error about switch quantity not being an integer...so more playing around I guess...my usual. :P
Heres the code btw...lol (with "String")

Code:
void readFile(int bNum) {
  while (myFile.available()) {
    char Rx = myFile.read();

    if (String(Rx) == "=") { ;} else {if (String(Rx) == "!") { ;} else {if (String(Rx) == " ") { ;} else {if (Rx == 10) { ;} else {if (Rx == 13) { ;} else {tempRx += Rx;}}}}}
    if (String(Rx) == "=") {rxName = tempRx; varName = "b" + String(bNum); varName = String(varName) + String(rxName); tempRx = ""; Rx = ""; Serial.print(".");}
    if (String(Rx) == "!") {rxValue = tempRx; varValue = rxValue; tempRx = ""; Rx = ""; Serial.print(".");}
    
    switch (String(varName)) {
      for (int x = 1; x = 4; x++) {
        serial.println(varName);
        case "b" && String(x) && "PlantName": b && String(x) && PlantName = varValue; break
        case "b" && String(x) && "LightStart": L && String(x) && _S = varValue.toint(); break
        case "b" && String(x) && "LightEnd": L && String(x) && _E = varValue.toint(); break
        case "b" && String(x) && "PimpStart": P && String(x) && _S = varValue.toint(); break
        case "b" && String(x) && "PumpRun": P && String(x) && _E = varValue.toint(); break
        serial.println(varName);
      }
    }
  }
}
 

solakani

Well-Known Member
Just quickly threw this together, but I get error about string not declared...tried the String also same...get an error about switch quantity not being an integer...so more playing around I guess...my usual. :P
Heres the code btw...lol (with "String")

Code:
void readFile(int bNum) {
  while (myFile.available()) {
    char Rx = myFile.read();

    if (String(Rx) == "=") { ;} else {if (String(Rx) == "!") { ;} else {if (String(Rx) == " ") { ;} else {if (Rx == 10) { ;} else {if (Rx == 13) { ;} else {tempRx += Rx;}}}}}
    if (String(Rx) == "=") {rxName = tempRx; varName = "b" + String(bNum); varName = String(varName) + String(rxName); tempRx = ""; Rx = ""; Serial.print(".");}
    if (String(Rx) == "!") {rxValue = tempRx; varValue = rxValue; tempRx = ""; Rx = ""; Serial.print(".");}
   
    switch (String(varName)) {
      for (int x = 1; x = 4; x++) {
        serial.println(varName);
        case "b" && String(x) && "PlantName": b && String(x) && PlantName = varValue; break
        case "b" && String(x) && "LightStart": L && String(x) && _S = varValue.toint(); break
        case "b" && String(x) && "LightEnd": L && String(x) && _E = varValue.toint(); break
        case "b" && String(x) && "PimpStart": P && String(x) && _S = varValue.toint(); break
        case "b" && String(x) && "PumpRun": P && String(x) && _E = varValue.toint(); break
        serial.println(varName);
      }
    }
  }
}
Does not compute. use a switch or a loop but not both. You are using c++ and need a reference manual to read about array. https://www.arduino.cc/reference/en/language/variables/data-types/array/
 

solakani

Well-Known Member
Ya I'm not very good yet at programming these silly arduinos...learning tho...lol
Thanks for the link. :)
I was just showing a basic example to show what I was thinking at the time...some times my words get garbled up. :P
I think the technical term is pseudocode. Please list the content of the input myFile
 

Mak'er Grow

Well-Known Member
I think the technical term is pseudocode. Please list the content of the input myFile
File titles =
BOX1.txt
BOX2.txt
BOX3.txt
BOX4.txt

Example of contents in file(s) =
PlantName=24xClones!
LightStart=7!
LightEnd=23!
PumpStart=1!
PumpRun=10!

Eventually there will be more info in this file, but for getting things started I just used a few simple things that could be easily altered. This also helped when I was trying to dial in the water pumps on my system...could alter times on the fly without having to reprogram the Arduino every change. :)
 

solakani

Well-Known Member
If you layout the input file like this and then store it in a struct.

24xClones 7 23 1 10
25xClones 7 25 1 10
26xClones 7 26 1 10
27xClones 7 27 1 10

struct GrowDetail {
String PlantName;
int LightStart;
int LightEnd;
int PumpStart;
int PumpRun;
} ;

void readFile(int BX) {
int index = 0;
GrowDetail myGrows[4];
while (myFile.available()) {
String line = myFile.readStringUntil('\n');
myGrows[index].PlantName = strtok(line," ");
myGrows[index].LightStart = strtok(NULL," ").toInt();
myGrows[index].LightEnd = strtok(NULL," ").toInt();
myGrows[index].PumpStart = strtok(NULL," ").toInt();
myGrows[index].PumpEnd = strtok(NULL," ").toInt();
index++;}
 

JonCreighton

Well-Known Member
can i ask u where u learned this stuff.... im about 20 deep into paul mcchorters youtube tutorials... just wondering how u did it?
 

Mak'er Grow

Well-Known Member
can i ask u where u learned this stuff.... im about 20 deep into paul mcchorters youtube tutorials... just wondering how u did it?
I used the example sketches...altered values and stuff to learn what parts did what and used online guides for better descriptions of commands etc.
 

Mak'er Grow

Well-Known Member
If you layout the input file like this and then store it in a struct.

24xClones 7 23 1 10
25xClones 7 25 1 10
26xClones 7 26 1 10
27xClones 7 27 1 10

struct GrowDetail {
String PlantName;
int LightStart;
int LightEnd;
int PumpStart;
int PumpRun;
} ;

void readFile(int BX) {
int index = 0;
GrowDetail myGrows[4];
while (myFile.available()) {
String line = myFile.readStringUntil('\n');
myGrows[index].PlantName = strtok(line," ");
myGrows[index].LightStart = strtok(NULL," ").toInt();
myGrows[index].LightEnd = strtok(NULL," ").toInt();
myGrows[index].PumpStart = strtok(NULL," ").toInt();
myGrows[index].PumpEnd = strtok(NULL," ").toInt();
index++;}
That works well, but its a little difficult for newbie users to edit the file(s) easily. Without names with the values things can get confused very easily.
I found some little problems with that area and going to work on it a little more later tonight...have a few ideas using an array and changing the names a bit...once I have it working better I'll post a newer version. I fixed up a few other places that needed it too.
 

Kervork

Well-Known Member
Dude.. Dude... Dude... Raspberry Pi, NodeRed, ESP8266 thingy maybe if you need it. Arduino is great if you need millisecond timing or you're gonna make 10,000 of them. Pi, NodeRed is the lazy way, ten times faster.

Unless you like writing code. Arduino is for situations like you are building as satellite controlled machine gun to whack an Iranian nuclear scientist and that extra 10 millisecond delay is totally screwing up your shot. Pi zero will run NodeRed and a mysql database at 0.2 load while it's snapping a picture of your grow with the onboard camera and texting it to you.

I originally started with a mega and arduino and as soon as I found nodered it went on the shelf and I never touched it again. Miserable environment screwing around uploading sketches and debugging cryptic ass code that never fit. Shit, nodered has Git built into it, 20 different dashboards and support for every javascript framework ever made as near as I can tell. You won't need a screen on the Pi because there's a web interface that will run on your phone.

You're gonna look at it and think... it's got a GUI, it's gotta be gay. But trust me it's not a fucking toy, it's a fucking digital chainsaw.

When you're done you can just say Alexa, grow my weed. Yeah, it talks to all them Ai bitches too.
 

Mak'er Grow

Well-Known Member
Dude.. Dude... Dude... Raspberry Pi, NodeRed, ESP8266 thingy maybe if you need it. Arduino is great if you need millisecond timing or you're gonna make 10,000 of them. Pi, NodeRed is the lazy way, ten times faster.

Unless you like writing code. Arduino is for situations like you are building as satellite controlled machine gun to whack an Iranian nuclear scientist and that extra 10 millisecond delay is totally screwing up your shot. Pi zero will run NodeRed and a mysql database at 0.2 load while it's snapping a picture of your grow with the onboard camera and texting it to you.

I originally started with a mega and arduino and as soon as I found nodered it went on the shelf and I never touched it again. Miserable environment screwing around uploading sketches and debugging cryptic ass code that never fit. Shit, nodered has Git built into it, 20 different dashboards and support for every javascript framework ever made as near as I can tell. You won't need a screen on the Pi because there's a web interface that will run on your phone.

You're gonna look at it and think... it's got a GUI, it's gotta be gay. But trust me it's not a fucking toy, it's a fucking digital chainsaw.

When you're done you can just say Alexa, grow my weed. Yeah, it talks to all them Ai bitches too.
I'm NOT switching now after spending a year or more building everything.
I'm very aware of the Pi and it capabilities and all, but I'm doing simple or trying to.
Thanks for the input tho.
 

Kervork

Well-Known Member
Year invested in simple. BTW there is a typo in your code. My guess is that results in the value being undefined and your error but what would I know.
 

Mak'er Grow

Well-Known Member
@Kervork if you want to troll a thread, please find another...thanks
Or contribute with useful information besides pointing out some error or typo and then don't back up anything.
Yes, a year or more now in building and making all my equipment myself...but some days my med condition doesn't allow me...for give my slowness...lol
 
Top