Tutorial: Spark Variable and Function on One Web Page

If you’re not that into native apps, there’s also the ParticleJS library which allows you to interact with the API more easily, over the web.

2 Likes

I’ve been trying to open it in my phone and it does but doesn’t send the data to the core, and the problem I have is that I added the function that recieves the data to my code, but my code has a lot going on in the loop() and the web app never gets to the function, can you help me with this?

Hi @KarinaMendez

A bunch of folks here can help you if you post your code.

If you added a new Particle function to your firmware code, you also have to change the HTML/Javascript side to match.

This is the important part of my code:

void setup()
{
    uint32_t ms = millis();

    Serial.begin(9600);
    
    pinMode(buz, OUTPUT);
    pinMode(red, OUTPUT);  // declare LED as output
    pinMode(green, OUTPUT);
    pinMode(button, INPUT);    // declare pushbutton as input
    pinMode(sol, OUTPUT);
    
    pinMode(door, OUTPUT);
    myservo.attach(A0);  // attaches the servo on the A0 pin to the servo object
    Spark.function("setpos", setPosition);
    Spark.variable("getpos", &pos, INT);
    
    while(!Serial.available() && (millis() - ms < 10000));
    
    //Serial.println("initialization done.");
    //Serial.println("please wait ....");

    mySerial.begin(38400);
    delay(100);
    SendResetCmd();
    delay(2000);
    Spark.function("setPos", setPosition);
    Spark.function("led",ledToggle);
}

void loop()
{
    //digitalWrite(sol, HIGH);
    SendResetCmd();
    byte a[32];
    int ii;
    //TIMBRE
    
    val = digitalRead(button);  // read input value
    //digitalWrite(D7, HIGH);
    //val = HIGH;
    if (val == HIGH) {         // check if the input is HIGH (button pressed)
        digitalWrite(D7, HIGH);
        digitalWrite(green, LOW);  // turn LED OFF
        digitalWrite(red, HIGH);
        analogWrite(buz, 176400);
        delay(100);
        analogWrite(buz, 0);
        
        //start taking picture
        //Serial.println("gonna take pic");
        SendResetCmd();
        delay(2000);                            //Wait 2-3 second to send take picture command
        SendTakePhotoCmd();
        delay(1000);
        onOff = 0;
    
        while(mySerial.available()>0)
        {
            incomingbyte=mySerial.read();
        }
    
        while(!EndFlag)
        {
            j=0;
            k=0;
            count=0;
            //mySerial.flush();
            SendReadDataCmd();
            delay(20);
            while(mySerial.available()>0)
            {
                incomingbyte=mySerial.read();
                k++;
                delay(1); //250 for regular
                if((k>5)&&(j<32)&&(!EndFlag))
                {
                    a[j]=incomingbyte;
                    if((a[j-1]==0xFF)&&(a[j]==0xD9))     //tell if the picture is finished
                    {
                        EndFlag=1;
                    }
                    j++;
                    count++;
                }
            }
    
            for(j=0;j<count;j++)
            {
                digitalWrite(red, HIGH);  // turn LED ON
                digitalWrite(D7, HIGH);
                if(a[j]<0x10)  Serial.print("0");
                Serial.print(a[j],HEX);           // observe the image through serial port
                //Serial.print(" ");
            }
        }
        Serial.print("+");
        mySerial.flush();
        digitalWrite(red, HIGH);  // turn LED ON
        digitalWrite(green, HIGH);  // turn LED ON
        
        //Serial.println("Finished writing data to file");
    
    }else{
        //Serial.println("no press");
        digitalWrite(green, LOW);  // turn LED OFF
        digitalWrite(red, HIGH);
    }
    
}

int setPosition(String posValue) {
    pos = posValue.toInt();
    Serial.print(pos);
    if (pos > 4){
        digitalWrite(door, HIGH);
    }else{
        digitalWrite(door, LOW);
    }
    //myservo.write(pos);
    return 0;
}

Hi @KarinaMendez

There is a lot of code there–I would try to dramatically simply your code to debug just one thing at a time and not try to mix too many things together that might not be working.

  • You have Particle functions “setpos” and “setPos” that call the same firmware function. I would eliminate one of them.
  • You don’t show how mySerial is declared, so I will just say that software serial is to be avoided.
  • I don’t know what doing analogWrite(buz,176400); will do. Legal values would be 0-255 for PWM analog outputs and 0-4095 for true analog outputs. This just seems like a mistake.
  • It is not clear to me that your while() loops actually terminate and exit cleanly–you could easily have an infinite loop there. Better to have a timeout or other mechanism to avoid looping forever.

Also, try declaring your functions at the start of your setup, since I’ve seen cases where they didn’t register when there was a too long delay.

1 Like

Thank you so much for this tutorial. This was a great starting point for me. I tried to improve the html/javascript part a bit. My improvements:

  • Only make a get update request when the input bar is not hold by the mouse.
  • Start the 1s update time after a request was successful
  • Have a local state which will be update from the server side
  • Indicate if the server and client side state are not in sync

Here is my result:

<!DOCTYPE HTML>
<html>
  <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js" type="text/javascript" charset="utf-8"></script>
<body>
	<P>Set Servo Position:<br><br>
	<input type="range" name="degBox" id="degBoxId" min="0" max="180" step="1" value="90" list="myData" onmousedown="stopUpdating(this)" onmouseup="setValue(this)">
	<!-- This adds the tick marks to the range but does not in Safari -->
	<datalist id="myData">
	   <option value="0">
	   <option value="30">
	   <option value="60">
	   <option value="90">
	   <option value="120">
	   <option value="150">
	   <option value="180">
	</datalist>
	<br><br>
	<button id="minusbutton" onclick="fineAdjust(-5)">&lArr; -5 &deg;</button>
	<button id="plusbutton"  onclick="fineAdjust(+5)">+5 &deg; &rArr;</button>
	<br><br>
	<P>Current Position: <span id="curPos" style="font-size:28px;">90&deg;</span><br>
	
	<div id="pending" style="background-color:red;">Updates Pending</div>

	<script type="text/javascript">
	  var deviceID    = "<< device id >>";
	  var accessToken = "<< access token >>";
	  var setFunc = "setpos";
	  var getFunc = "getpos";
	  var pendingChanges = 0;
	  var curPos = 90;

	  function updateValues() {
			var requestURL = "https://api.spark.io/v1/devices/" + deviceID + "/" + getFunc +'/'; //+ "/?access_token=" + accessToken;
			$.get(requestURL,{'access_token':accessToken}, function(json, textStatus) {
			console.log(pendingChanges);
					if(pendingChanges==0) {
						curPos = parseInt(json.result);
						updateGui();
					}
					window.setTimeout(updateValues, 1000);
				},"json");
	  }
	  
	  function updateGui() {
						document.getElementById("curPos").innerHTML = curPos + "&deg;";
						document.getElementById("degBoxId").value = curPos;
						if(pendingChanges != 0)
							$('#pending').show();
						else
							$('#pending').hide();
	  }
	  
	  function stopUpdating(obj) {
			pendingChanges++;
	  }

	  function setValue(obj) {
		console.log(obj);
		curPos = obj.value;
		sparkSetPos(curPos);
	  }

	  function fineAdjust(value) {
	  pendingChanges++;
		curPos = value + curPos;
		sparkSetPos(curPos);
	  }

	  function sparkSetPos(newValue) {
		updateGui();
		var requestURL = "https://api.spark.io/v1/devices/" +deviceID + "/" + setFunc + "/";
		$.post( requestURL, { params: newValue, access_token: accessToken }, function() {
			pendingChanges--;
		});
	  }

	  updateValues();
	</script>
</body>
</html>
1 Like

i know this sounds really silly, but as a newbie
is it possible to connect using the USB?

if so how, and if not, do you have the parts / bits list for the 5v supply?

thanks
dave

Not entirely sure what you’re asking about? Can you plug the Photon into a computer over USB? Yes, you can. It will power it, allow a serial connection, and even a DFU connection. It all depends on what you’re trying to do with it. For a 5V supply, you can take pretty much any 5V USB adapter from a mobile phone for instance. Apple ones seem to be of good quality, but other should work too.
What exactly are you trying to achieve?

Also, this: https://docs.particle.io/guide/getting-started/connect/photon/

1 Like

hi there
thanks for the reply.
I mean to power the photon and the motor in the makers kit.
Can it be powered by just the USB (both devices), in which case how does the wiring work

As for the 5v puppy (in this tutorial plugged in to the top of the maker board, it was really what does it looks like/how is it split etc.
Is it just a normal USB cable with the end chopped off?

Sorry for newbie questions
Dave

That says a lot already, doesn't it ;)? You should be fine powering it from the same supply if they're not heavy-duty servos.

Hard to tell from the picture, and I assume @bko has a proper power supply. So no, I don't think it's a chopped off USB cable in this case. That said, a chopped off USB cable does work, since I'm currently using one for the exact same purpose. Might not be the prettiest solution, but hey, it works...

5V goes to Vin, and ground goes to ground. From those same cables, you can power your external thingies, whatever they may be, provided that you remain below the maximum current your supply can deliver.

ok understand that i think
right now I’ve got it hooked up to the same supply as the Photon (mini USB).
but not getting any movement though the web interface.
Is the wiring different at all using just the USB from the Photon?

I do appreciate the help

Dave

Could you show us a picture of your wiring, that’d make it easier. Also, are you sure the webpage, and code on your device is correct? You can use this page to check if the functions on your device are working correctly.

Just getting a picture uploaded.
the code is directly from the tutorial above replacing my device and token ID

Looks good to me. Have you tried the page I linked to, to check if the functions showed up like they should? Also, were you able to trigger them?

really silly question, how to i activate the functions from that page?
I have another device 0002 running that shows when i click on show me all.

trigger them you mean direct from the web address?
not tried that yet, need to work out the URL to use

Dave

Ok i understand it
If i hit setPos in that page to 140…
then hit the getPos under it, it will show 140 or whatever i enter, but the motor does not move at all

Dave

FOUND IT!
I ended up setting up the circuit myself, since there wasn’t anything obviously wrong. Turns out that the Photon doesn’t support the servo on A0, but rather on D0, D1, D2, D3, A4, A5, WKP, RX, and TX, as is documented over here. *note to self: read the docs!*
Change the code and pin to match any of the ones mentioned above, and it should work :smile:

so if i move the pin from A0 to D0 that should work?
Do we set D) in the code?

thanks for the help really appreciate it

Dave

Yup, and yup. Both are correct :slight_smile: