'param' was not declared in this scope

Hoping some can point out what I’m doing wrong with my code.
Hopefully this is my last error
Thanks

bull.ino:307:20: ‘param’ was not declared in this scope

BLYNK_WRITE(V0);
{
//Recieved command to control relay 1.
int value = param.asInt();
Serial.printf(“Blynk virtual write pin %i with param %i \n”, V0, value);
switch(value){
case 1:
relayController.turnOnRelay(1);
break;
case 0:
relayController.turnOffRelay(1);
break;
}
}

Hi,

I haven’t worked with Blink, but a quick glance has me wondering where “param” comes from. Can you post more of your code? This seems to be a very small snippet

Yes, if you could provide the full code that would be helpful.

@Trey param is being defined in Blynk’s library. Its a C file so that’s why there’s no way of telling where it’s coming from.

Sorry, new users can only put 2 links in a post.

I’m trying to post my code but keep getting this.

Sorry, new users can only put 2 links in a post.

Heres code.

// while a pump is running. Very Important to data usage for an ELECTRON. Start with 180000 after initial bench testing..
int minCurrent =                1;                 //  MUST MULTIPLY BY A FACTOR OF 10.  Example: using 20 will eleminate any AMP Reading that is less than 2 AMPS to avoid noise on the Graph.
int spikeCurrent =             500;                 //  MUST MULTIPLY BY A FACTOR OF 10.  Example: using 500 will eleminate any AMP Reading that is OVER 50 AMPS. This doesn't show Startup SPIKES for large Inductive Loads, true running amps will be read 10 seconds later.
                                                    //  If you dont want the minCurrent and spikeCurrent Functionality, set to 1 and 1500 respectively
//ThingSpeak Channel Info                           //  
//const char * myWriteAPIKey = "XXXXXXXXXXXXXXXX";    //  From your ThinkSpeak Account Info (API KEYS tab)
//////////////////////////////////////////////////////

// There is no need to change anything else if you are just getting started. 









// This #include statement was automatically added by the Particle IDE.
#include <NCD4Relay.h>

// This #include statement was automatically added by the Particle IDE.
#include <blynk.h>

#include  <spark_wiring_i2c.h>
#include <application.h>
#define AddrCurrent 0x2A    // I²C  Address for Current Monitor
#define CT_delay 10000      //  10,000 = 10 seconds.  The CT Current Monitor Data Sheet suggests only reading the Board every 8-10 seconds

SYSTEM_THREAD(ENABLED);   

char msg[256];

unsigned long now = millis();           // Used as Time to compare the Ellapsed time for various readings
unsigned int lastPublish = 0;          
unsigned long nowCT = millis();         // Latest CT Current-Monitor Reading
unsigned int lastCT = millis();         // Previous CT Current-Monitor Reading

//  Variables Req'd for I²C  CT Current-Monitor Board
int msb1 = 0, msb = 0, lsb = 0;
unsigned int data[36];  
int typeOfSensor = 0;
int maxCurrent = 0;
int noOfChannel = 0;

int CH1trueamps = 0;
int CH2trueamps = 0;

double current = 0;
double amps = 0;

//  These 4 Floats will hold the values to send to ThinkSpeak.com for data logging to the Cloud :
float CH1, CH2, CH3, CH4;      // Pump/Motor AMPS    


// Arrays 
static int oldVal[5] = {0,0,0,0,0}; // Previous Sensor Values to Compare if Run State has Changed - equality checks are safer with Integers, so we will multiply by 10 for all sensor values, But divide by 10 before publishing each value
static int nowVal[5] = {0,0,0,0,0}; // Most Recent Sensor Values * 10    
static int Flag[3] = {0,0,0};       // A "0" Value means nothing to update.  Flag[1] = 1 requests to Publish AMPS after the Publish Delay, Flag[2] = 1 requests an immediate Publish (no Delay - used for Pump Start/Stop Events)
       

//  Remote Reset Function, used to RE-SET the Photon/Electron using
#define DELAY_BEFORE_REBOOT 2000
unsigned int rebootDelayMillis = DELAY_BEFORE_REBOOT;
unsigned long rebootSync = millis();
bool resetFlag = false;


NCD4Relay relayController;

SYSTEM_MODE(AUTOMATIC);



bool tripped[4];

int debugTrips[4];

int minTrips = 5;
#define AddrRelay 0x20





 
 
 

#define BLYNK_PRINT Serial  // Set serial output for debug prints
//#define BLYNK_DEBUG       // Uncomment this to see detailed prints

// Uncomment this, if you want to set network credentials
//#include "cellular_hal.h"
//STARTUP(cellular_credentials_set("broadband", "", "", NULL));

// Run "ping blynk-cloud.com", and set Blynk IP to the shown address
#define BLYNK_IP        IPAddress(45,55,130,102)

// Set Blynk hertbeat interval.
// Each heartbeat uses ~90 bytes of data.
#define BLYNK_HEARTBEAT 60

// Set Particle keep-alive ping interval.
// Each ping uses 121 bytes of data.
#define PARTICLE_KEEPALIVE 20

#include <blynk.h>

// You should get Auth Token in the Blynk App.
// Go to the Project Settings (nut icon).
char auth[] = "32d9fea8c1e842879bcf4e9a557be833";        // ANDY2  "2f7b99a1190949928b59f5a11a357edf";
 



void setup() {
    
    
      // Register Particle Function to allow user to remotely Change the Publish Delay.   
//  Particle.function("setDelay", setPublishDelay);

  // Set I²C  Current Monitor Board  variable
  Particle.variable("i2cdevice", "PECMAC125A");
  Particle.variable("typeOfSensor", typeOfSensor);
  Particle.variable("maxCurrent", maxCurrent);
  Particle.variable("noOfChannel", noOfChannel);
  Particle.variable("OUTPUT1", CH1trueamps);
  Particle.variable("OUTPUT2", CH2trueamps);

//  Remote Reset Function    
//  Particle.function("reset",cloudResetFunction);

  // I²C  setup for the CT Current-Monitor Motherboard
  // Initialise I²C  communication as MASTER
  Wire.begin();
  // Initialise Serial Communication, set baud rate = 9600
  Serial.begin(9600);

  // Setup the Current Monitor 
  // Start I²C  transmission
  Wire.beginTransmission(AddrCurrent);
  // Command header byte-1
  Wire.write(0x92);
  // Command header byte-2
  Wire.write(0x6A);
  // Command 2 is used to read no of sensor type, Max current, No. of channel
  Wire.write(0x02);
  // Reserved
  Wire.write(0x00);
  // Reserved
  Wire.write(0x00);
  // Reserved
  Wire.write(0x00);
  // Reserved
  Wire.write(0x00);
  // CheckSum
  Wire.write(0xFE);
  // Stop I²C  transmission
  Wire.endTransmission();
  // Request 6 bytes of data
   Wire.requestFrom(AddrCurrent, 6);
  // Read 6 bytes of data
  if (Wire.available() == 6){
    data[0] = Wire.read();
    data[1] = Wire.read();
    data[2] = Wire.read();
    data[3] = Wire.read();
    data[4] = Wire.read();
    data[5] = Wire.read();
   }
  typeOfSensor = data[0];
  maxCurrent = data[1];
  noOfChannel = data[2];
  delay(200);  
  
    
  Serial.begin(9600);
  Particle.keepAlive(PARTICLE_KEEPALIVE);
  Blynk.begin(auth, BLYNK_IP);
}
 
 

/* This function loops forever --------------------------------------------*/ 
 void loop(){ 
  
     //Perform Housekeeping of Blynk connection 
     Blynk.run();
     
     nowCT = millis();

 if (abs(nowCT - lastCT) > CT_delay)  {    // The intention is to only read the Current Monitor every 10 seconds, per the Specs.  
     for (int j = 1; j < noOfChannel + 1; j++) {
     // Start I²C  Transmission
     Wire.beginTransmission(AddrCurrent);
     // Command header byte-1
     Wire.write(0x92);
     // Command header byte-2
     Wire.write(0x6A);
     // Command 1
     Wire.write(0x01);
     // Start Channel No.
     Wire.write(j);
     // End Channel No.
     Wire.write(j);
     // Reserved
     Wire.write(0x00);
     // Reserved
     Wire.write(0x00);
     // CheckSum
     Wire.write((0x92 + 0x6A + 0x01 + j + j + 0x00 + 0x00) & 0xFF);
    // Stop I²C  Transmission
     Wire.endTransmission();
     delay(1000);
     // Request 3 bytes of data
     Wire.requestFrom(AddrCurrent, 3);
     // Read 3 bytes of data
     // msb1, msb, lsb
     msb1 = Wire.read();
     msb = Wire.read();
     lsb = Wire.read();
     current = (msb1 * 65536) + (msb * 256) + lsb;
     // Convert the data to ampere
     amps = current / 1000;
    
     // the For Loop cycles through each Channel of the CT Board.  Store each AMP reading next. 
     nowVal[j] = round(amps * 10) ;  // Multiply the AMPS * 10 and store the value in the Array for that particular Channel (CH1 - CH4).  This converts the AMP reading to an integer, we will "recover" the decimal place later. 

     if (nowVal[j]  > spikeCurrent){ //  Want to eleminate the SPIKE during Startup.  The CT will recognize the TRUE Running Amps 10 seconds (CT_Delay) later during the next read and store that value instead.  
         nowVal[j] = 0;              // set to 0 and read the True Running Amps on the Next read in 10 seconds.
     }
     if (nowVal[j]  < minCurrent) {  //The CT's may bounch around 0-2 amps during "No-Load".  
         nowVal[j] = 0;              //  Dont want to send 0.XX - 2.00 Amps to  so delete these low values, or "noise". 
         
         if (oldVal[j]  > minCurrent) {   // If the previous AMP reading showed the Pump to be Running, but Now it is NOT Running- So the PUMP just "STOPPED".
             Particle.publish("PUMP", "Pump # " + String(j) + " Stopped"   , PRIVATE);   // Comment Out this line if you do Not Want Start/Stop Notifications.  Use IFTTT.com if you do.  
             Flag[2]  = 1;           // Will REQUEST an immediate full publish - with no publish Delay Check for Flag[2] == 1.  
         }
     }    
     //  Same as above, but checking to see if the Pump JUST "STARTED".
     if (nowVal[j]  > minCurrent) {  //The CT's bounch around 0 amps.  Dont want to send 0.XX - 2.00 Amps to ThingSpeak
         Flag[1]  = 1;               // Flag[1] is used for ANY CT measurement above the minimum threshold - Requests a Full Publish after the Publish Delay Is Met.  This is to log normal runtime AMPS at the interval publish_delay.
         
             if (oldVal[j]  < minCurrent)   { // a PUMP is running now but wasn't on previous check, then it just "STARTED".
                 Particle.publish("PUMP", "Pump # " + String(j) + " Started "    , PRIVATE);   // Comment Out this line if you do Not Want Start/Stop Notifications.  Use IFTTT.com if you do.
                // Flag[2]  = 1;       // Will REQUEST an immediate full publish - with no publish Delay Check for Flag[2] == 1
             }
             
   
     }    
     oldVal[j] =  nowVal[j];         // Set the Old Value to the most recent Value for the Next Comparison to determine if the Pump is Starting or Stopping. 
     }
     lastCT = nowCT;                 // Since we've sucessfully read all the Channels of the CT Current Monitor Board, update the TIME for the Last Read.  We want to wait 10 seconds before another CT Current Monitor Board Read.  
 

 //  ALL READINGS ARE COMPLETE, SO UPDATE THE CHANNEL Float Values used for logging data to 
 CH1 = (nowVal[1] / 10.0) * 120;           //  Divide each Integer Value by 10 to recover the 1 Decimal Place precision
 CH2 = (nowVal[2] / 10.0) * 120;
 CH3 = (nowVal[3] / 10.0);
 CH4 = (nowVal[4] / 10.0);

 CH1trueamps = CH1;
 CH2trueamps = CH2; 

     //Check Blynk publish interval for temperature reading so we only publish every 1 second. 
//    // if(millis() > lastTempPub + tempPubInt){ 
  //       lastTempPub = millis(); 
    //     tempF = tempSensor.temperatureF(); 
      //   char temp[8]; 
//         sprintf(temp, "%.2fº", tempF); 
  //       Serial.println(temp); 
    ///     //Publish the current temperature reading to the Blynk app. 
       //  Blynk.virtualWrite(V8, temp); 
//     } 
     //Read inputs on relay board: 
     updateInputs(false); 
 	 
  
 
 
   BLYNK_WRITE(V0);{
       //Recieved command to control relay 1. 
       int value = param.asInt(); 
       Serial.printf("Blynk virtual write pin %i with param %i \n", V0, value); 
       switch(value){ 
           case 1: 
               relayController.turnOnRelay(1); 
                 break; 
           case 0: 
               relayController.turnOffRelay(1); 
               break; 
       } 
   }
   BLYNK_WRITE(V1) 
    {   //Recieved command to control relay 2. 
       int value = param.asInt(); 
       Serial.printf("Blynk virtual write pin %i with param %i \n", V1, value); 
       switch(value){ 
           case 1: 
               relayController.turnOnRelay(2); 
               break; 
           case 0: 
               relayController.turnOffRelay(2); 
               break; 
       } 
   } 
 
 
   void updateInputs(bool startup){ 
       //Read and debounce digital inputs on relay board. 
    	int status = relayController.readAllInputs(); 
    	int a = 0; 
      	for(int i = 1; i < 33; i*=2){ 
 		if(status & i){ 
 			debugTrips[a]++; 
 			if(debugTrips[a] >= minTrips || startup){ 
 				if(!tripped[a] || startup){ 
 				    //Input is closed 
 				    Serial.println("Input Closed"); 
 					tripped[a] = true; 
 					//Publish high status to LED indicator in Blynk app notifying user that input is closed. 
 				//	led[a].on(); 
 					if(a == 3){ 
 					    //If this is input 4 on the relay board then push notification to user's phone. 
 					    Blynk.notify("You're really pushing my buttons"); 
 					} 
 				} 
 			} 
 		}else{ 
 			debugTrips[a] = 0; 
 			if(tripped[a] || startup){ 
 			    Serial.println("Input Open"); 
 			    //Input is open 
 				tripped[a] = false; 
 				//Publish low status to LED indicator in Blynk app notifying user that input is open. 
 			//	led[a].off(); 
 			} 
 		} 
 		a++; 
 	} 
  } 
}

List of errors

bull.ino:285:20: ‘param’ was not declared in this scope
error
bull.ino:297:5: a function-definition is not allowed here before ‘{’ token
error
bull.ino:344:1: expected ‘}’ at end of input
error
bull.ino:344:1: expected ‘}’ at end of input

Trey removing the semi-colon on this line:

With line 283 like this:

BLYNK_WRITE(V0){

I get this error

bull.ino:283:19: a function-definition is not allowed here before ‘{’ token

Hi,

Looks like some closing brackets were lost and you need to remove that semi colon Trey mentioned. Try this:

// while a pump is running. Very Important to data usage for an ELECTRON. Start with 180000 after initial bench testing..
int minCurrent =                1;                 //  MUST MULTIPLY BY A FACTOR OF 10.  Example: using 20 will eleminate any AMP Reading that is less than 2 AMPS to avoid noise on the Graph.
int spikeCurrent =             500;                 //  MUST MULTIPLY BY A FACTOR OF 10.  Example: using 500 will eleminate any AMP Reading that is OVER 50 AMPS. This doesn't show Startup SPIKES for large Inductive Loads, true running amps will be read 10 seconds later.
                                                    //  If you dont want the minCurrent and spikeCurrent Functionality, set to 1 and 1500 respectively
//ThingSpeak Channel Info                           //  
//const char * myWriteAPIKey = "XXXXXXXXXXXXXXXX";    //  From your ThinkSpeak Account Info (API KEYS tab)
//////////////////////////////////////////////////////

// There is no need to change anything else if you are just getting started. 









// This #include statement was automatically added by the Particle IDE.
#include <NCD4Relay.h>

// This #include statement was automatically added by the Particle IDE.
#include <blynk.h>

#include  <spark_wiring_i2c.h>
#include <application.h>
#define AddrCurrent 0x2A    // I²C  Address for Current Monitor
#define CT_delay 10000      //  10,000 = 10 seconds.  The CT Current Monitor Data Sheet suggests only reading the Board every 8-10 seconds

SYSTEM_THREAD(ENABLED);   

char msg[256];

unsigned long now = millis();           // Used as Time to compare the Ellapsed time for various readings
unsigned int lastPublish = 0;          
unsigned long nowCT = millis();         // Latest CT Current-Monitor Reading
unsigned int lastCT = millis();         // Previous CT Current-Monitor Reading

//  Variables Req'd for I²C  CT Current-Monitor Board
int msb1 = 0, msb = 0, lsb = 0;
unsigned int data[36];  
int typeOfSensor = 0;
int maxCurrent = 0;
int noOfChannel = 0;

int CH1trueamps = 0;
int CH2trueamps = 0;

double current = 0;
double amps = 0;

//  These 4 Floats will hold the values to send to ThinkSpeak.com for data logging to the Cloud :
float CH1, CH2, CH3, CH4;      // Pump/Motor AMPS    


// Arrays 
static int oldVal[5] = {0,0,0,0,0}; // Previous Sensor Values to Compare if Run State has Changed - equality checks are safer with Integers, so we will multiply by 10 for all sensor values, But divide by 10 before publishing each value
static int nowVal[5] = {0,0,0,0,0}; // Most Recent Sensor Values * 10    
static int Flag[3] = {0,0,0};       // A "0" Value means nothing to update.  Flag[1] = 1 requests to Publish AMPS after the Publish Delay, Flag[2] = 1 requests an immediate Publish (no Delay - used for Pump Start/Stop Events)
       

//  Remote Reset Function, used to RE-SET the Photon/Electron using
#define DELAY_BEFORE_REBOOT 2000
unsigned int rebootDelayMillis = DELAY_BEFORE_REBOOT;
unsigned long rebootSync = millis();
bool resetFlag = false;


NCD4Relay relayController;

SYSTEM_MODE(AUTOMATIC);



bool tripped[4];

int debugTrips[4];

int minTrips = 5;
#define AddrRelay 0x20





 
 
 

#define BLYNK_PRINT Serial  // Set serial output for debug prints
//#define BLYNK_DEBUG       // Uncomment this to see detailed prints

// Uncomment this, if you want to set network credentials
//#include "cellular_hal.h"
//STARTUP(cellular_credentials_set("broadband", "", "", NULL));

// Run "ping blynk-cloud.com", and set Blynk IP to the shown address
#define BLYNK_IP        IPAddress(45,55,130,102)

// Set Blynk hertbeat interval.
// Each heartbeat uses ~90 bytes of data.
#define BLYNK_HEARTBEAT 60

// Set Particle keep-alive ping interval.
// Each ping uses 121 bytes of data.
#define PARTICLE_KEEPALIVE 20

#include <blynk.h>

// You should get Auth Token in the Blynk App.
// Go to the Project Settings (nut icon).
char auth[] = "32d9fea8c1e842879bcf4e9a557be833";        // ANDY2  "2f7b99a1190949928b59f5a11a357edf";
 



void setup() {
    
    
      // Register Particle Function to allow user to remotely Change the Publish Delay.   
//  Particle.function("setDelay", setPublishDelay);

  // Set I²C  Current Monitor Board  variable
  Particle.variable("i2cdevice", "PECMAC125A");
  Particle.variable("typeOfSensor", typeOfSensor);
  Particle.variable("maxCurrent", maxCurrent);
  Particle.variable("noOfChannel", noOfChannel);
  Particle.variable("OUTPUT1", CH1trueamps);
  Particle.variable("OUTPUT2", CH2trueamps);

//  Remote Reset Function    
//  Particle.function("reset",cloudResetFunction);

  // I²C  setup for the CT Current-Monitor Motherboard
  // Initialise I²C  communication as MASTER
  Wire.begin();
  // Initialise Serial Communication, set baud rate = 9600
  Serial.begin(9600);

  // Setup the Current Monitor 
  // Start I²C  transmission
  Wire.beginTransmission(AddrCurrent);
  // Command header byte-1
  Wire.write(0x92);
  // Command header byte-2
  Wire.write(0x6A);
  // Command 2 is used to read no of sensor type, Max current, No. of channel
  Wire.write(0x02);
  // Reserved
  Wire.write(0x00);
  // Reserved
  Wire.write(0x00);
  // Reserved
  Wire.write(0x00);
  // Reserved
  Wire.write(0x00);
  // CheckSum
  Wire.write(0xFE);
  // Stop I²C  transmission
  Wire.endTransmission();
  // Request 6 bytes of data
   Wire.requestFrom(AddrCurrent, 6);
  // Read 6 bytes of data
  if (Wire.available() == 6){
    data[0] = Wire.read();
    data[1] = Wire.read();
    data[2] = Wire.read();
    data[3] = Wire.read();
    data[4] = Wire.read();
    data[5] = Wire.read();
   }
  typeOfSensor = data[0];
  maxCurrent = data[1];
  noOfChannel = data[2];
  delay(200);  
  
    
  Serial.begin(9600);
  Particle.keepAlive(PARTICLE_KEEPALIVE);
  Blynk.begin(auth, BLYNK_IP);
}
 
 

/* This function loops forever --------------------------------------------*/ 
 void loop(){ 
  
     //Perform Housekeeping of Blynk connection 
     Blynk.run();
     
     nowCT = millis();

 if (abs(nowCT - lastCT) > CT_delay)  {    // The intention is to only read the Current Monitor every 10 seconds, per the Specs.  
     for (int j = 1; j < noOfChannel + 1; j++) {
     // Start I²C  Transmission
     Wire.beginTransmission(AddrCurrent);
     // Command header byte-1
     Wire.write(0x92);
     // Command header byte-2
     Wire.write(0x6A);
     // Command 1
     Wire.write(0x01);
     // Start Channel No.
     Wire.write(j);
     // End Channel No.
     Wire.write(j);
     // Reserved
     Wire.write(0x00);
     // Reserved
     Wire.write(0x00);
     // CheckSum
     Wire.write((0x92 + 0x6A + 0x01 + j + j + 0x00 + 0x00) & 0xFF);
    // Stop I²C  Transmission
     Wire.endTransmission();
     delay(1000);
     // Request 3 bytes of data
     Wire.requestFrom(AddrCurrent, 3);
     // Read 3 bytes of data
     // msb1, msb, lsb
     msb1 = Wire.read();
     msb = Wire.read();
     lsb = Wire.read();
     current = (msb1 * 65536) + (msb * 256) + lsb;
     // Convert the data to ampere
     amps = current / 1000;
    
     // the For Loop cycles through each Channel of the CT Board.  Store each AMP reading next. 
     nowVal[j] = round(amps * 10) ;  // Multiply the AMPS * 10 and store the value in the Array for that particular Channel (CH1 - CH4).  This converts the AMP reading to an integer, we will "recover" the decimal place later. 

     if (nowVal[j]  > spikeCurrent){ //  Want to eleminate the SPIKE during Startup.  The CT will recognize the TRUE Running Amps 10 seconds (CT_Delay) later during the next read and store that value instead.  
         nowVal[j] = 0;              // set to 0 and read the True Running Amps on the Next read in 10 seconds.
     }
     if (nowVal[j]  < minCurrent) {  //The CT's may bounch around 0-2 amps during "No-Load".  
         nowVal[j] = 0;              //  Dont want to send 0.XX - 2.00 Amps to  so delete these low values, or "noise". 
         
         if (oldVal[j]  > minCurrent) {   // If the previous AMP reading showed the Pump to be Running, but Now it is NOT Running- So the PUMP just "STOPPED".
             Particle.publish("PUMP", "Pump # " + String(j) + " Stopped"   , PRIVATE);   // Comment Out this line if you do Not Want Start/Stop Notifications.  Use IFTTT.com if you do.  
             Flag[2]  = 1;           // Will REQUEST an immediate full publish - with no publish Delay Check for Flag[2] == 1.  
         }
     }    
     //  Same as above, but checking to see if the Pump JUST "STARTED".
     if (nowVal[j]  > minCurrent) {  //The CT's bounch around 0 amps.  Dont want to send 0.XX - 2.00 Amps to ThingSpeak
         Flag[1]  = 1;               // Flag[1] is used for ANY CT measurement above the minimum threshold - Requests a Full Publish after the Publish Delay Is Met.  This is to log normal runtime AMPS at the interval publish_delay.
         
             if (oldVal[j]  < minCurrent)   { // a PUMP is running now but wasn't on previous check, then it just "STARTED".
                 Particle.publish("PUMP", "Pump # " + String(j) + " Started "    , PRIVATE);   // Comment Out this line if you do Not Want Start/Stop Notifications.  Use IFTTT.com if you do.
                // Flag[2]  = 1;       // Will REQUEST an immediate full publish - with no publish Delay Check for Flag[2] == 1
             }
             
   
     }    
     oldVal[j] =  nowVal[j];         // Set the Old Value to the most recent Value for the Next Comparison to determine if the Pump is Starting or Stopping. 
     }
     lastCT = nowCT;                 // Since we've sucessfully read all the Channels of the CT Current Monitor Board, update the TIME for the Last Read.  We want to wait 10 seconds before another CT Current Monitor Board Read.  
 

 //  ALL READINGS ARE COMPLETE, SO UPDATE THE CHANNEL Float Values used for logging data to 
 CH1 = (nowVal[1] / 10.0) * 120;           //  Divide each Integer Value by 10 to recover the 1 Decimal Place precision
 CH2 = (nowVal[2] / 10.0) * 120;
 CH3 = (nowVal[3] / 10.0);
 CH4 = (nowVal[4] / 10.0);

 CH1trueamps = CH1;
 CH2trueamps = CH2; 

     //Check Blynk publish interval for temperature reading so we only publish every 1 second. 
//    // if(millis() > lastTempPub + tempPubInt){ 
  //       lastTempPub = millis(); 
    //     tempF = tempSensor.temperatureF(); 
      //   char temp[8]; 
//         sprintf(temp, "%.2fº", tempF); 
  //       Serial.println(temp); 
    ///     //Publish the current temperature reading to the Blynk app. 
       //  Blynk.virtualWrite(V8, temp); 
//     } 
     //Read inputs on relay board: 
     updateInputs(false); 
 	 
  
 
 
   BLYNK_WRITE(V0);{
       //Recieved command to control relay 1. 
       int value = param.asInt(); 
       Serial.printf("Blynk virtual write pin %i with param %i \n", V0, value); 
       switch(value){ 
           case 1: 
               relayController.turnOnRelay(1); 
                 break; 
           case 0: 
               relayController.turnOffRelay(1); 
               break; 
       } 
   }
   BLYNK_WRITE(V1) 
    {   //Recieved command to control relay 2. 
       int value = param.asInt(); 
       Serial.printf("Blynk virtual write pin %i with param %i \n", V1, value); 
       switch(value){ 
           case 1: 
               relayController.turnOnRelay(2); 
               break; 
           case 0: 
               relayController.turnOffRelay(2); 
               break; 
       } 
   } 
 
 
   void updateInputs(bool startup){ 
       //Read and debounce digital inputs on relay board. 
    	int status = relayController.readAllInputs(); 
    	int a = 0; 
      	for(int i = 1; i < 33; i*=2){ 
 		if(status & i){ 
 			debugTrips[a]++; 
 			if(debugTrips[a] >= minTrips || startup){ 
 				if(!tripped[a] || startup){ 
 				    //Input is closed 
 				    Serial.println("Input Closed"); 
 					tripped[a] = true; 
 					//Publish high status to LED indicator in Blynk app notifying user that input is closed. 
 				//	led[a].on(); 
 					if(a == 3){ 
 					    //If this is input 4 on the relay board then push notification to user's phone. 
 					    Blynk.notify("You're really pushing my buttons"); 
 					} 
 				} 
 			} 
 		}else{ 
 			debugTrips[a] = 0; 
 			if(tripped[a] || startup){ 
 			    Serial.println("Input Open"); 
 			    //Input is open 
 				tripped[a] = false; 
 				//Publish low status to LED indicator in Blynk app notifying user that input is open. 
 			//	led[a].off(); 
 			} 
 		} 
 		a++; 
 	} 
  } 
}

full loop
errors at end
Travis this is a copy and paste of, blynk-2relay-si7020temperature.ino, just the section for the relay control

void loop(){

 //Perform Housekeeping of Blynk connection 
 Blynk.run();
 
 nowCT = millis();

if (abs(nowCT - lastCT) > CT_delay) { // The intention is to only read the Current Monitor every 10 seconds, per the Specs.
for (int j = 1; j < noOfChannel + 1; j++) {
// Start I²C Transmission
Wire.beginTransmission(AddrCurrent);
// Command header byte-1
Wire.write(0x92);
// Command header byte-2
Wire.write(0x6A);
// Command 1
Wire.write(0x01);
// Start Channel No.
Wire.write(j);
// End Channel No.
Wire.write(j);
// Reserved
Wire.write(0x00);
// Reserved
Wire.write(0x00);
// CheckSum
Wire.write((0x92 + 0x6A + 0x01 + j + j + 0x00 + 0x00) & 0xFF);
// Stop I²C Transmission
Wire.endTransmission();
delay(1000);
// Request 3 bytes of data
Wire.requestFrom(AddrCurrent, 3);
// Read 3 bytes of data
// msb1, msb, lsb
msb1 = Wire.read();
msb = Wire.read();
lsb = Wire.read();
current = (msb1 * 65536) + (msb * 256) + lsb;
// Convert the data to ampere
amps = current / 1000;

 // the For Loop cycles through each Channel of the CT Board.  Store each AMP reading next. 
 nowVal[j] = round(amps * 10) ;  // Multiply the AMPS * 10 and store the value in the Array for that particular Channel (CH1 - CH4).  This converts the AMP reading to an integer, we will "recover" the decimal place later. 

 if (nowVal[j]  > spikeCurrent){ //  Want to eleminate the SPIKE during Startup.  The CT will recognize the TRUE Running Amps 10 seconds (CT_Delay) later during the next read and store that value instead.  
     nowVal[j] = 0;              // set to 0 and read the True Running Amps on the Next read in 10 seconds.
 }
 if (nowVal[j]  < minCurrent) {  //The CT's may bounch around 0-2 amps during "No-Load".  
     nowVal[j] = 0;              //  Dont want to send 0.XX - 2.00 Amps to  so delete these low values, or "noise". 
     
     if (oldVal[j]  > minCurrent) {   // If the previous AMP reading showed the Pump to be Running, but Now it is NOT Running- So the PUMP just "STOPPED".
         Particle.publish("PUMP", "Pump # " + String(j) + " Stopped"   , PRIVATE);   // Comment Out this line if you do Not Want Start/Stop Notifications.  Use IFTTT.com if you do.  
         Flag[2]  = 1;           // Will REQUEST an immediate full publish - with no publish Delay Check for Flag[2] == 1.  
     }
 }    
 //  Same as above, but checking to see if the Pump JUST "STARTED".
 if (nowVal[j]  > minCurrent) {  //The CT's bounch around 0 amps.  Dont want to send 0.XX - 2.00 Amps to ThingSpeak
     Flag[1]  = 1;               // Flag[1] is used for ANY CT measurement above the minimum threshold - Requests a Full Publish after the Publish Delay Is Met.  This is to log normal runtime AMPS at the interval publish_delay.
     
         if (oldVal[j]  < minCurrent)   { // a PUMP is running now but wasn't on previous check, then it just "STARTED".
             Particle.publish("PUMP", "Pump # " + String(j) + " Started "    , PRIVATE);   // Comment Out this line if you do Not Want Start/Stop Notifications.  Use IFTTT.com if you do.
            // Flag[2]  = 1;       // Will REQUEST an immediate full publish - with no publish Delay Check for Flag[2] == 1
         }
         

 }    
 oldVal[j] =  nowVal[j];         // Set the Old Value to the most recent Value for the Next Comparison to determine if the Pump is Starting or Stopping. 
 }
 lastCT = nowCT;                 // Since we've sucessfully read all the Channels of the CT Current Monitor Board, update the TIME for the Last Read.  We want to wait 10 seconds before another CT Current Monitor Board Read.  

// ALL READINGS ARE COMPLETE, SO UPDATE THE CHANNEL Float Values used for logging data to
CH1 = (nowVal[1] / 10.0) * 120; // Divide each Integer Value by 10 to recover the 1 Decimal Place precision
CH2 = (nowVal[2] / 10.0) * 120;
CH3 = (nowVal[3] / 10.0);
CH4 = (nowVal[4] / 10.0);

CH1trueamps = CH1;
CH2trueamps = CH2;

 //Check Blynk publish interval for temperature reading so we only publish every 1 second. 

// // if(millis() > lastTempPub + tempPubInt){
// lastTempPub = millis();
// tempF = tempSensor.temperatureF();
// char temp[8];
// sprintf(temp, “%.2fº”, tempF);
// Serial.println(temp);
/// //Publish the current temperature reading to the Blynk app.
// Blynk.virtualWrite(V8, temp);
// }
//Read inputs on relay board:
// updateInputs(false);

  BLYNK_WRITE(V0){
   //Recieved command to control relay 1. 
   int value = param.asInt(); 
   Serial.printf("Blynk virtual write pin %i with param %i \n", V0, value); 
   switch(value){ 
       case 1: 
           relayController.turnOnRelay(1); 
             break; 
       case 0: 
           relayController.turnOffRelay(1); 
           break; 
   } 

}

BLYNK_WRITE(V1) 
{   //Recieved command to control relay 2. 
   int value = param.asInt(); 
   Serial.printf("Blynk virtual write pin %i with param %i \n", V1, value); 
   switch(value){ 
       case 1: 
           relayController.turnOnRelay(2); 
           break; 
       case 0: 
           relayController.turnOffRelay(2); 
           break; 
   } 

}

void updateInputs(bool startup){
//Read and debounce digital inputs on relay board.
int status = relayController.readAllInputs();
int a = 0;
for(int i = 1; i < 33; i*=2){
if(status & i){
debugTrips[a]++;
if(debugTrips[a] >= minTrips || startup){
if(!tripped[a] || startup){
//Input is closed
Serial.println(“Input Closed”);
tripped[a] = true;
//Publish high status to LED indicator in Blynk app notifying user that input is closed.
// led[a].on();
if(a == 3){
//If this is input 4 on the relay board then push notification to user’s phone.
Blynk.notify(“You’re really pushing my buttons”);
}
}
}
}else{
debugTrips[a] = 0;
if(tripped[a] || startup){
Serial.println(“Input Open”);
//Input is open
tripped[a] = false;
//Publish low status to LED indicator in Blynk app notifying user that input is open.
// led[a].off();
}
}
a++;
}
}
}
bull.ino:284:22: a function-definition is not allowed here before ‘{’ token
error
bull.ino:346:1: expected ‘}’ at end of input

Are you writing your application on https://build.particl.io or in another IDE?

Yes sir, particle build

Try this:
https://go.particle.io/shared_apps/5a626e6085e1010fd7000b5c

Travis, I flashed the electron. Blynk showing its online. No relay control.

Have you tried monitoring Serial prints in the Blynk functions to make sure they are firing on virtual pin updates? We can assist a little with custom code but can’t go to far as it is expensive to have engineers spend large amounts of time trouble shooting code.

You may also consider posting on Blynk and Particle’s community as well. They have very large communities of users who are very willing to help.

Got it going thanks for the help.