Go Down

Topic: Code for multitasking on the Yun isn't working  (Read 739 times) previous topic - next topic

rcvolley

So I found this code for haveing multiple leds blinking at the same time on the same yun board it also can make a servo motor move and turn on an led with a button at the same time but I only need it to blink the leds I cant get it to work and am wondering if anyone can see why I think I must be missing something the code compiles and uploads with out a problem but it doesn't print out any of the console.println lines on the serial monotor and it doesn't blink. This is where I got the original code from.

Multi tasking code forum

this is my edited version to take out the servo and the button
Code: [Select]
// SeveralThingsAtTheSameTimeRev1.ino

// An expansion of the BlinkWithoutDelay concept to illustrate how a script
//  can appear to do several things at the same time

// this sketch does the following
//    it blinks the onboard LED (as in the blinkWithoutDelay sketch)
//    it blinks two external LEDs (LedA and LedB) that are connected to pins 12 and 11.
//    it turns another Led (buttonLed connected to pin 10) on or off whenever a button
//       connected to pin 7 is pressed
//    it sweeps a servo (connected to pin 5) back and forth at different speeds

//  One leg of each LED should be connected to the relevant pin and the other leg should be connected to a
//   resistor of 470 ohms or more and the other end of the resistor to the Arduino GND.
//   If the LED doesn't light its probably connected the wrong way round.

//  On my Uno and Mega the "button" is just a piece of wire inserted into pin 7.
//   Touching the end of the wire with a moist finger is sufficient to cause the switching action
//   Of course a proper press-on-release-off button switch could also be used!

//  The Arduino is not capable of supplying enough 5v power to operate a servo
//    The servo should have it's own power supply and the power supply Ground should
//      be connected to the Arduino Ground.

// The sketch is written to illustrate a few different programming features.
//    The use of many functions with short pieces of code.
//       Short pieces of code are much easier to follow and debug
//    The use of variables to record the state of something (e.g. onBoardLedState) as a means to
//       enable the different functions to determine what to do.
//    The use of millis() to manage the timing of activities
//    The definition of all numbers used by the program at the top of the sketch where
//       they can easily be found if they need to be changed

//=======

// -----LIBRARIES

#include <Servo.h>
#include <Bridge.h>
// ----CONSTANTS (won't change)

const int onBoardLedPin =  9;      // the pin numbers for the LEDs
const int led_A_Pin = 10;
const int led_B_Pin = 11;
//const int buttonLed_Pin = 10;

//const int buttonPin = 7; // the pin number for the button

//const int servoPin = 5; // the pin number for the servo signal

const int onBoardLedInterval = 200; // number of millisecs between blinks
const int led_A_Interval = 250;
const int led_B_Interval = 450;;

const int blinkDuration = 500; // number of millisecs that Led's are on - all three leds use this

//const int buttonInterval = 300; // number of millisecs between button readings

//const int servoMinDegrees = 20; // the limits to servo movement
//const int servoMaxDegrees = 150;


//------- VARIABLES (will change)

byte onBoardLedState = LOW;             // used to record whether the LEDs are on or off
byte led_A_State = LOW;           //   LOW = off
byte led_B_State = LOW;
//byte buttonLed_State = LOW;

//Servo myservo;  // create servo object to control a servo

//int servoPosition = 90;     // the current angle of the servo - starting at 90.
//int servoSlowInterval = 80; // millisecs between servo moves
//int servoFastInterval = 10;
//int servoInterval = servoSlowInterval; // initial millisecs between servo moves
//int servoDegrees = 2;       // amount servo moves at each step
//    will be changed to negative value for movement in the other direction

unsigned long currentMillis = 0;    // stores the value of millis() in each iteration of loop()
unsigned long previousOnBoardLedMillis = 0;   // will store last time the LED was updated
unsigned long previousLed_A_Millis = 0;
unsigned long previousLed_B_Millis = 0;

//unsigned long previousButtonMillis = 0; // time when button press last checked

//unsigned long previousServoMillis = 0; // the time when the servo was last moved

//========

void setup() {
  Bridge.begin();
  Console.begin();
  Console.println("Starting SeveralThingsAtTheSameTimeRev1.ino");  // so we know what sketch is running

  // set the Led pins as output:
  pinMode(onBoardLedPin, OUTPUT);
  pinMode(led_A_Pin, OUTPUT);
  pinMode(led_B_Pin, OUTPUT);
  //pinMode(buttonLed_Pin, OUTPUT);
  Console.println("led outputs");
  // set the button pin as input with a pullup resistor to ensure it defaults to HIGH
  //pinMode(buttonPin, INPUT_PULLUP);

  //myservo.write(servoPosition); // sets the initial position
  // myservo.attach(servoPin);

}

//=======

void loop() {

  // Notice that none of the action happens in loop() apart from reading millis()
  //   it just calls the functions that have the action code

  currentMillis = millis();   // capture the latest value of millis()
  //   this is equivalent to noting the time from a clock
  //   use the same time for all LED flashes to keep them synchronized

  //readButton();               // call the functions that do the work
  updateOnBoardLedState();
  updateLed_A_State();
  updateLed_B_State();
  //switchLeds();
  //servoSweep();

}

//========

void updateOnBoardLedState() {

  if (onBoardLedState == LOW) {
    // if the Led is off, we must wait for the interval to expire before turning it on
    if (currentMillis - previousOnBoardLedMillis >= onBoardLedInterval) {
      // time is up, so change the state to HIGH
      onBoardLedState = HIGH;
      // and save the time when we made the change
      previousOnBoardLedMillis += onBoardLedInterval;
      // NOTE: The previous line could alternatively be
      //              previousOnBoardLedMillis = currentMillis
      //        which is the style used in the BlinkWithoutDelay example sketch
      //        Adding on the interval is a better way to ensure that succesive periods are identical

    }
  }
  else {  // i.e. if onBoardLedState is HIGH

    // if the Led is on, we must wait for the duration to expire before turning it off
    if (currentMillis - previousOnBoardLedMillis >= blinkDuration) {
      // time is up, so change the state to LOW
      onBoardLedState = LOW;
      // and save the time when we made the change
      previousOnBoardLedMillis += blinkDuration;
    }
  }
}

//=======

void updateLed_A_State() {

  if (led_A_State == LOW) {
    if (currentMillis - previousLed_A_Millis >= led_A_Interval) {
      led_A_State = HIGH;
      previousLed_A_Millis += led_A_Interval;
    }
  }
  else {
    if (currentMillis - previousLed_A_Millis >= blinkDuration) {
      led_A_State = LOW;
      previousLed_A_Millis += blinkDuration;
    }
  }
}

//=======

void updateLed_B_State() {

  if (led_B_State == LOW) {
    if (currentMillis - previousLed_B_Millis >= led_B_Interval) {
      led_B_State = HIGH;
      previousLed_B_Millis += led_B_Interval;
    }
  }
  else {
    if (currentMillis - previousLed_B_Millis >= blinkDuration) {
      led_B_State = LOW;
      previousLed_B_Millis += blinkDuration;
    }
  }
}

//========

void switchLeds() {
  // this is the code that actually switches the LEDs on and off

  digitalWrite(onBoardLedPin, onBoardLedState);
  digitalWrite(led_A_Pin, led_A_State);
  digitalWrite(led_B_Pin, led_B_State);
  //digitalWrite(buttonLed_Pin, buttonLed_State);
}

ShapeShifter

It appears you have two concerns: lack of Console output, and LEDs not blinking.

For the Console output, it's important to confirm that you have the Yun's network port selected in the Arduino IDE Port menu, not the USB serial port. The Console class communicates only over the network, while the Serial class communicates only over the USB port. The other possibility is that the only Console output is in Setup(), so the output will happen quickly and will be short. It's possible that you are missing the output before you open the Serial Monitor window.

The LEDs blinking is a little more clear cut. The individual LED control functions update state variables, but don't actually update the output pins - that's done in the switchLeds() function. That function is normally called near the end of the loop() function, after all of the LED state flags have been updated. But you have commented out the call to switchLeds(), so it never gets called, and the LED outputs are not updated.

rcvolley

thank you so much that totally fixed the problem I was wondering if you knew anything about the update function I've set up a similar code to try and get it to be able to be changed in a way similar to the bridge example but when I try to use the update command in my code it won't compile.

Code: [Select]
#include <Bridge.h>
#include <BridgeServer.h>
#include <BridgeClient.h>

BridgeServer server;//set up a bridge server

//LED Pin vairiables (they will stay constant)
const int Led1 = 11;
const int Led2 = 9;
const int Led3 = 6;
const int Led4 = 3;

const int P = 50; //perioud of the cycle it can't go below 50

//Vairiables that will change
unsigned long DC1 = 0;
unsigned long DC2 = 0;
unsigned long DC3 = 0;
unsigned long DC4 = 0;

//on LED signals
unsigned long ONLed1 = (P * DC1);
unsigned long ONLed2 = (P * DC2);
unsigned long ONLed3 = (P * DC3);
unsigned long ONLed4 = (P * DC4);

//LED off signals
unsigned long OFFLed1 = (P * (1 - DC1));
unsigned long OFFLed2 = (P * (1 - DC2));
unsigned long OFFLed3 = (P * (1 - DC3));
unsigned long OFFLed4 = (P * (1 - DC4));

byte totalmillies = 0;// the total number of miliseconds on the loop
//checking if the LEDS are on or off
byte Led1State = LOW;
byte Led2State = LOW;
byte Led3State = LOW;
byte Led4State = LOW;

void setup() {
  Bridge.begin();
  Console.begin();
  Console.println ("through vairiables");

  //set up server
  server.listenOnLocalhost();
  server.begin();
 
  //setting Leds as outputs
  pinMode(Led1, OUTPUT);
  pinMode(Led2, OUTPUT);
  pinMode(Led3, OUTPUT);
  pinMode(Led4, OUTPUT);
}

void loop() {
  totalmillies = millis();

  updateLed1State();


as far as I can tell I have very similar variable up to that point I'm, not sure whats going wrong

ShapeShifter

when I try to use the update command in my code it won't compile.
Please post your complete sketch, as well as the exact compilation error message you are getting. Without it, we as just guessing.

rcvolley

#4
May 30, 2018, 08:28 pm Last Edit: May 30, 2018, 08:49 pm by rcvolley
so I've added a bit to the code science I last posted it here is the entire code I'm not getting errors anymore but it's not working as it should and I'm not sure why. it should be able to take a URL that looks like this http://192.168.240.1/arduino/analog/11/123 and use the last value 123 as the value variable and use that to make the LED a changeable PWM.

Code: [Select]
#include <Bridge.h>
#include <BridgeServer.h>
#include <BridgeClient.h>

BridgeServer server;//set up a bridge server

//LED Pin vairiables (they will stay constant)
const int Led1 = 11;
const int Led2 = 9;
const int Led3 = 6;
const int Led4 = 3;

const int P = 50; //perioud of the cycle it can't go below 50

//Vairiables that will change
unsigned long DC1 = 0;
unsigned long DC2 = 0;
unsigned long DC3 = 0;
unsigned long DC4 = 0;

//on LED signals
unsigned long ONLed1 = (P * DC1);
unsigned long ONLed2 = (P * DC2);
unsigned long ONLed3 = (P * DC3);
unsigned long ONLed4 = (P * DC4);

//LED off signals
unsigned long OFFLed1 = (P * (1 - DC1));
unsigned long OFFLed2 = (P * (1 - DC2));
unsigned long OFFLed3 = (P * (1 - DC3));
unsigned long OFFLed4 = (P * (1 - DC4));

byte totalmillies = 0;// the total number of miliseconds on the loop
//checking if the LEDS are on or off
byte Led1State = LOW;
byte Led2State = LOW;
byte Led3State = LOW;
byte Led4State = LOW;

void setup() {
  Bridge.begin();
  Console.begin();
  Console.println ("through vairiables");

  //set up server
  server.listenOnLocalhost();
  server.begin();

  //setting Leds as outputs
  pinMode(Led1, OUTPUT);
  pinMode(Led2, OUTPUT);
  pinMode(Led3, OUTPUT);
  pinMode(Led4, OUTPUT);



}


void loop() {
  totalmillies = millis();

  updateLed1State();
  updateLed2State();
  updateLed3State();
  updateLed4State();
  BridgeClient client = server.accept();


}



void process(BridgeClient client) {
  String command = client.readStringUntil('/');
  if (client) {
    process(client);
    Console.println("client connected and will now close");
    client.stop();
  }
  if (command == "analog") {
    analogCommand(client);

  }
}

int pin, value;

void analogCommand(BridgeClient client) {
  pin = client.parseInt();

}

void updateLed1State() {
  if (Led1State == LOW) {
    if (totalmillies - OFFLed1 >= ONLed1) {
      Led1State = HIGH;
    }
  }

  else {
    if (totalmillies - ONLed1 >= ONLed1 + OFFLed1)
    {
      Led1State = LOW;
    }
  }
}
void updateLed2State() {
  if (Led2State == LOW) {
    if (totalmillies - OFFLed2 >= ONLed2) {
      Led2State = HIGH;
    }
  }

  else {
    if (totalmillies - ONLed2 >= ONLed2 + OFFLed2)
    {
      Led1State = LOW;
    }
  }
}
void updateLed3State() {
  if (Led3State == LOW) {
    if (totalmillies - OFFLed3 >= ONLed3) {
      Led3State = HIGH;
    }
  }

  else {
    if (totalmillies - ONLed3 >= ONLed3 + OFFLed3)
    {
      Led3State = LOW;
    }
  }
}
void updateLed4State() {
  if (Led4State == LOW) {
    if (totalmillies - OFFLed4 >= ONLed4) {
      Led4State = HIGH;
    }
  }

  else {
    if (totalmillies - ONLed4 >= ONLed4 + OFFLed4)
    {
      Led4State = LOW;
    }
  }
}
void updateDC1() {
  BridgeClient client = server.accept();
  if (pin = 11) {
    if (client.read() == '/') {
      value = client.parseInt();
      DC1 == (value / 255);
    }
  }
}

ShapeShifter

In your loop function, you are calling server.accept() to check for a client connection. But then the function ends without checking whether there has been a connection attempt, and without calling the process() function to handle the connection.

Take another look at the Bridge Tutorial, and pay particular attention to the section where it describes the actions of the loop() function.

I didn't try fixing and running the code, but after a quick glance, there appears to be other issues as well:
  • You are calling the individual LED update routines, but you are still not updating the actual LED pin outputs. Instead of adding a call to the switchLeds() function that was missing in your previous version, it looks like you removed that function in this version?
  • In your analogCommand() function, all it does is try to read a pin number. It then doesn't do anything with that pin number, nor does it try to read the PWM value or update an output. There is a lot that is missing from this function before it will do anything useful.
  • There is a new function updateDC1() at the end of the sketch. It has multiple issues:
    • The function is not called from anywhere
    • It calls server.accept(), and then goes on to process the connection, but without checking whether a connection was made. This is an issue since the vast majority of the time that server.accept() is called, it will return a disconnected client indicating that no connection is in progress.
    • Since it tries to parse a 0 to 255 value, I'm guessing this is trying to parse the PWM field of your analog URL request, and the intent is to call this from the processAnalog() function. If this is the case, the server.accept() call at the beginning of updateDC1() is going to cause big problems - it will overwrite the client object you are trying to read from with a new client object, which is almost certainly going to indicate no connection (the only time it will show a connection is if you had made a second URL request in the microseconds before it finished processing the first request.) If you do happen to get a connection with that client object, it will be reading the beginning of the new URL request, not continuing on from the prior one.


rcvolley

so I attempted to fix all the problems you mentioned but I'm having trouble I keep getting the error

expected primary-expression before 'client'

when I try to compile it says the error is where I'm trying to call the analog command(BridgeClient client); function that I set up I'm not sure if there is something I'm missing or if I need to put the function before the Dc1 function



Code: [Select]
#include <Bridge.h>
#include <BridgeServer.h>
#include <BridgeClient.h>

BridgeServer server;//set up a bridge server

//LED Pin vairiables (they will stay constant)
const int Led1 = 11;
const int Led2 = 9;
const int Led3 = 6;
const int Led4 = 3;

const int P = 50; //perioud of the cycle it can't go below 50

//Vairiables that will change
unsigned long DC1 = 0;
unsigned long DC2 = 0;
unsigned long DC3 = 0;
unsigned long DC4 = 0;

//on LED signals
unsigned long ONLed1 = (P * DC1);
unsigned long ONLed2 = (P * DC2);
unsigned long ONLed3 = (P * DC3);
unsigned long ONLed4 = (P * DC4);

//LED off signals
unsigned long OFFLed1 = (P * (1 - DC1));
unsigned long OFFLed2 = (P * (1 - DC2));
unsigned long OFFLed3 = (P * (1 - DC3));
unsigned long OFFLed4 = (P * (1 - DC4));

byte totalmillies = 0;// the total number of miliseconds on the loop
//checking if the LEDS are on or off
byte Led1State = LOW;
byte Led2State = LOW;
byte Led3State = LOW;
byte Led4State = LOW;

void setup() {
  Bridge.begin();
  Console.begin();
  Console.println ("through vairiables");

  //set up server
  server.listenOnLocalhost();
  server.begin();

  //setting Leds as outputs
  pinMode(Led1, OUTPUT);
  pinMode(Led2, OUTPUT);
  pinMode(Led3, OUTPUT);
  pinMode(Led4, OUTPUT);



}


void loop() {
  totalmillies = millis();

  updateLed1State();
  updateLed2State();
  updateLed3State();
  updateLed4State();
  SwitchLeds();
  BridgeClient client = server.accept();
  analogCommand(BridgeClient client);

}

void updateDC1() {
 analogCommand(BridgeClient client);
  if (pin = 11) {
    DC1 == (value / 255);
  }
}

void process(BridgeClient client) {
  String command = client.readStringUntil('/');
  if (client) {
    process(client);
    Console.println("client connected and will now close");
    client.stop();
  }
  if (command == "analog") {
    analogCommand(client);

  }
}



float analogCommand(BridgeClient client) {
  int pin, value;
  pin = client.parseInt();
  if (client.read() == '/') {
    value = client.parseInt();
    return value;
    return pin;
  }
}

void updateLed1State() {
  if (Led1State == LOW) {
    if (totalmillies - OFFLed1 >= ONLed1) {
      Led1State = HIGH;
    }
  }

  else {
    if (totalmillies - ONLed1 >= ONLed1 + OFFLed1)
    {
      Led1State = LOW;
    }
  }
}
void updateLed2State() {
  if (Led2State == LOW) {
    if (totalmillies - OFFLed2 >= ONLed2) {
      Led2State = HIGH;
    }
  }

  else {
    if (totalmillies - ONLed2 >= ONLed2 + OFFLed2)
    {
      Led1State = LOW;
    }
  }
}
void updateLed3State() {
  if (Led3State == LOW) {
    if (totalmillies - OFFLed3 >= ONLed3) {
      Led3State = HIGH;
    }
  }

  else {
    if (totalmillies - ONLed3 >= ONLed3 + OFFLed3)
    {
      Led3State = LOW;
    }
  }
}
void updateLed4State() {
  if (Led4State == LOW) {
    if (totalmillies - OFFLed4 >= ONLed4) {
      Led4State = HIGH;
    }
  }

  else {
    if (totalmillies - ONLed4 >= ONLed4 + OFFLed4)
    {
      Led4State = LOW;
    }
  }
}void SwitchLeds() {
  digitalWrite(Led1, Led1State);
  digitalWrite(Led2, Led2State);
  digitalWrite(Led3, Led3State);
  digitalWrite(Led4, Led4State);
}

ShapeShifter

For the analogCommand() function, BridgeClient is the type name for the client parameter. You only provide the type names for parameters when you define the function, not when you call it. The error message is complaining that you are also including the the type name while calling the function, which is wrong.

There are still many things wrong with the logic and structure of this sketch. For example, the loop() function is calling analogCommand() directly, yet neither loop() nor analogCommand() check to see if a client connection was made before reading from the client. This check is normally done in the process() function, but that function is not called - and that's a good thing because process() has many issues starting with reading from the client before checking for a connection, and recursively calling itself if there is a connection. Once there is a connection, this recursive call will cause an infinite loop that will quickly fill up the stack and crash the sketch. There is much more that is concerning about the design of this sketch.

It looks to me that you don't understand what the code is trying to do. You cannot write successful software by randomly copying some statements from here and there and putting them together. I suggest that you take a step back and try to break this project down into basic parts, figure out how each part works, and truly understand what it is doing. When you have each part working by itself as an independent sketch, and you know what the various statements are doing, only then should you try to combine them into a single sketch.

Please, take a step back to work out the small details and get comfortable with what is going on before you tackle such a complex project.

Go Up