Using Tinker with my own code - HELP!


#1

K, I have been setting up my core to work my pool system,and am having trouble integrating The Tinker code with my own.

I copied the tinker code directly from the website, and on it’s own it works fine. I wrote my own code to control it from a webpage, after going through the tutorials, and THAT works fine on it’s own as well.

However, when both are together ,the Tinker code works just fine, but the webpage keeps stating that the relevant function is not found.

Here is the code: (If there is a better way to format this, please let me know
@moors7: sure there is, check over here)

//  Pool Control Code
//
/*
 This is a simple code to control the Pump, Light, Spa Jets, and Heater of my
 pool.  Eventually it will also control the pump valves and read a temperature
 sensor
 */

//Tinker Variables

int tinkerDigitalRead(String pin);
int tinkerDigitalWrite(String command);
int tinkerAnalogRead(String pin);
int tinkerAnalogWrite(String command);

//My Variables
int heater = D0;
int spa = D1;
int light = D2;
int pump = D3;
int valve1 = D4;
int valve2 = D5;

int pumpToggle(String command);
int lightToggle(String command);
int spaToggle(String command);
int heaterToggle(String command);
int intakeToggle(String command);
int outflowToggle(String command);

int LED = D7;


void setup()
{

	Spark.function("digitalread", tinkerDigitalRead);
	Spark.function("digitalwrite", tinkerDigitalWrite);
	Spark.function("analogread", tinkerAnalogRead);
	Spark.function("analogwrite", tinkerAnalogWrite);

	//PUT YOUR SETUP CODE HERE
//setting up the pins here
  pinMode(heater, OUTPUT);
  pinMode(spa, OUTPUT);
  pinMode(light, OUTPUT);
  pinMode(pump, OUTPUT);
  pinMode(valve1, OUTPUT);
  pinMode(valve2, OUTPUT);

  pinMode(LED, OUTPUT);

//setting their default state here
  digitalWrite(heater, LOW);
  digitalWrite(spa, LOW);
  digitalWrite(light, LOW);
  digitalWrite(pump, LOW);
  digitalWrite(valve1, LOW);
  digitalWrite(valve2, LOW);

  digitalWrite(LED, LOW);

//Setting functions here
  Spark.function("filter",pumpToggle);
  Spark.function("lite",lightToggle);
  Spark.function("jets",spaToggle);
  Spark.function("heat",heaterToggle);
  Spark.function("intake",intakeToggle);
  Spark.function("outflow",outflowToggle);

}

void loop()
{
	//PUT YOUR LOOP CODE HERE
    digitalWrite(LED, HIGH);
    delay(1000);
    digitalWrite(LED, LOW);
    delay(1000);

}

int tinkerDigitalRead(String pin) {
	int pinNumber = pin.charAt(1) - '0';
	if (pinNumber< 0 || pinNumber >7) return -1;
	if(pin.startsWith("D")) {
		pinMode(pinNumber, INPUT_PULLDOWN);
		return digitalRead(pinNumber);}
	else if (pin.startsWith("A")){
		pinMode(pinNumber+10, INPUT_PULLDOWN);
		return digitalRead(pinNumber+10);}
	return -2;}

int tinkerDigitalWrite(String command){
	bool value = 0;
	int pinNumber = command.charAt(1) - '0';
	if (pinNumber< 0 || pinNumber >7) return -1;
	if(command.substring(3,7) == "HIGH") value = 1;
	else if(command.substring(3,6) == "LOW") value = 0;
	else return -2;
	if(command.startsWith("D")){
		pinMode(pinNumber, OUTPUT);
		digitalWrite(pinNumber, value);
		return 1;}
	else if(command.startsWith("A")){
		pinMode(pinNumber+10, OUTPUT);
		digitalWrite(pinNumber+10, value);
		return 1;}
	else return -3;}

int tinkerAnalogRead(String pin){
	int pinNumber = pin.charAt(1) - '0';
	if (pinNumber< 0 || pinNumber >7) return -1;
	if(pin.startsWith("D")){
		pinMode(pinNumber, INPUT);
		return analogRead(pinNumber);}
	else if (pin.startsWith("A")){
		pinMode(pinNumber+10, INPUT);
		return analogRead(pinNumber+10);}
	return -2;}

int tinkerAnalogWrite(String command){
	int pinNumber = command.charAt(1) - '0';
	if (pinNumber< 0 || pinNumber >7) return -1;
	String value = command.substring(3);
	if(command.startsWith("D")){
		pinMode(pinNumber, OUTPUT);
		analogWrite(pinNumber, value.toInt());
		return 1;}
	else if(command.startsWith("A")){
		pinMode(pinNumber+10, OUTPUT);
		analogWrite(pinNumber+10, value.toInt());
		return 1;}
	else return -2;}

//My Code
//Pump Control
int pumpToggle(String command) {
  if (command=="on") {
    digitalWrite(pump,HIGH);
  }
  else if (command=="off") {
    digitalWrite(pump,LOW);
  }
  else {
    return -1;
  }
}

//Light Control
int lightToggle(String command) {
  if (command=="on") {
    digitalWrite(light,HIGH);
  }
  else if (command=="off") {
    digitalWrite(light,LOW);
  }
  else {
    return -1;
  }
}

//Spa Control
int spaToggle(String command) {
  if (command=="on") {
    digitalWrite(spa,HIGH);
  }
  else if (command=="off") {
    digitalWrite(spa,LOW);
  }
  else {
    return -1;
  }
}

//Heater Control
int heaterToggle(String command) {
  if (command=="on") {
    digitalWrite(heater,HIGH);
  }
  else if (command=="off") {
    digitalWrite(heater,LOW);
  }
  else {
    return -1;
  }
}

//Intake Valve
int intakeToggle(String command) {
  if (command=="on") {
    digitalWrite(valve1,HIGH);
  }
  else if (command=="off") {
    digitalWrite(valve1,LOW);
  }
  else {
    return -1;
  }
}

//Outflow Control
int outflowToggle(String command) {
  if (command=="on") {
    digitalWrite(valve2,HIGH);
  }
  else if (command=="off") {
    digitalWrite(valve2,LOW);
  }
  else {
    return -1;
  }
}

#2

@jjaparsons, unfortunately the Core only supports a limited number of Spark.functions() as per the documentation:

Currently the application supports the creation of up to 4 different cloud functions.

The Tinker app uses all four of these! Do you need to have the Tinker functionality? The only way to fix this is to “aggregate” the commands into fewer Spark.functions() using compound commands and parsing those commands. For example, you could gather all your pool functions into a single one and pass it the command like pump=on or light=off.


#3

Thanks for the quick response - I hadn’t even thought of that. I really just needed it for troubleshooting and operating the Core till I got all of my coding up to snuff. I could combine mine into a single one, and then remove tinkerAnalogWrite and tinkerDigitalRead, as I don’t foresee needing them for any of my applications - I plan on adding in a automated heater/temperature monitor function to keep the spa at a given temp, so that would be the second custom function.


#4

@jjaparsons, will you be using the Tinker application on a mobile device? If not, there is no point keeping any of the Tinker functions. Just create your own. In most of my projects, I only use a single Spark.function() and I use a simple command structure. :smile:


#5

The desire is to control the whole system from a mobile device: a total of 6 relays and a temperature sensor. I have been using Tinker because it’s been enough for what we needed straight out of the box, but it’s not strictly a requirement, so long as I have something that we can both use on our mobile devices that is just as easy to use. I have been playing with the concept of an HTML file on our phones that would process the necessary requests, but am open to suggestions.


#6

@jjaparsons, search in the community and you’ll probably find some examples :smile:


#7

If you can host an HTML page somewhere, I’d go with that route. You’re going to need Internet regardless, and a webapp allows you to customize it to your needs.
This is good to start with:


You could also use the JavaScript library to make it easier to interact with your devices, should you wish to go this route.