xl97's Iron Man motorized face plate tutorial

That doesnt look like my code... so not clear where it came from.

However on page 2 (did you even read this thread?)

There seems to be a merge of the my code with an IR remote/sensor already posted....and working I believe.
 
Last edited:
That doesnt look like my code... so not clear where it came from.

However on page 2 (did you even read this thread?)

There seems to be a merge of the my code with an IR remote/sensor already posted....and working I believe.
Thank you and I don't know how I missed that. I have been combing through all the Iron man posts for months just to get my helmet working. Lol now I don't know which post I got the code from but I will utilize your suggested approach to and go watch the tutorial and see about implementing the ir code into the code for my helmet
 
Last edited:
I was just saying:

1.) That wasnt my code
2.) Someone here posted a merge of my code and an IR remote on page #2.. not sure if its the same as your or can be easily edited to fit yours.. but its probably a good place to start.

Either way (going form memory here).. You'd want to import your libraries... and then in the IDLE state.. do your IR checking.. same the normal button checking is being done.

Once you get something together.. post it here (using code tags) if you need some help.
 
I was just saying:

1.) That wasnt my code
2.) Someone here posted a merge of my code and an IR remote on page #2.. not sure if its the same as your or can be easily edited to fit yours.. but its probably a good place to start.

Either way (going form memory here).. You'd want to import your libraries... and then in the IDLE state.. do your IR checking.. same the normal button checking is being done.

Once you get something together.. post it here (using code tags) if you need some help.
Thank you sir!! I'm working on it now and will post results soon
 
Ok so I found an IR code that controlled a servo online linking from the tutorial you suggested to the poster on page 2.

Code:
/*
  IR Receiver Demonstration 4
  IR-Rcv-Demo4.ino
  Demonstrates IR codes with Custom Remote and IR Receiver
  Makes use of Repeat function

  DroneBot Workshop 2017
  http://dronebotworkshop.com
*/

// Include IR Remote Library by Ken Shirriff
#include <IRremote.h>

// Include Arduino Servo Library
#include <Servo.h>

// Define Sensor Pin
const int RECV_PIN = 4;

// Define Servo Pin
const int SERVO_PIN = 6;

// Define Variable for Servo position
// Start at 90 Degrees (Center position)
int pos = 90;         

// Define variable to store last code received
unsigned long lastCode; 

// Define IR Receiver and Results Objects
IRrecv irrecv(RECV_PIN);
decode_results results;

// Create servo object
Servo myservo;          

void setup()
{
  // Start the receiver
  irrecv.enableIRIn();
   
  // Attach the servo
  myservo.attach(SERVO_PIN); 

  // Start with Servo in Center
  myservo.write(pos); 
}

void loop() {
if(irrecv.decode(&results)) //this checks to see if a code has been received
{

    if(results.value == 0xFFFFFFFF)   
    {
       // If Repeat then use last code received
       results.value = lastCode;        
    }

    if(results.value == 0xFF22DD)    
    {
        // Left Button Pressed
        lastCode = results.value;
        // Move left 2 degrees     
        pos += 2; 
        // Prevent position above 180
        if(pos > 180){pos = 180;}                     
        myservo.write(pos);      
    }
      
    if(results.value == 0xFFC23D)     
    {
       // Right Button Pressed
       lastCode = results.value;
       // Move Right 2 degrees  
       pos -= 2; 
       // Prevent position below 0
       if(pos < 0){pos = 0;}                   
       myservo.write(pos);     
    }

   if(results.value == 0xFF02FD)     
    {
       // Center Button Pressed
       lastCode = results.value;
       // Move to Center  
       pos = 90;          
       myservo.write(pos);     
    }

    // Add delay to prevent false readings
    delay(30); 
    //receive the next value  
    irrecv.resume(); 
}
    
}

And I tried to bring over elements from the original code I was using for the helmet which was

Code:
#include <Servo.h>
//servo 1
Servo myservo;

int val; // variable for reading the pin status
int val2; // variable for reading the delayed/debounced status
int buttonState;
int pos = 20;
int servostatus = 0;
int switchPin =4; // Switch connected to digital pin 2
int ledPin = 6;


void setup() // run once, when the sketch starts
{
//servo 1

myservo.attach(5);
pinMode(switchPin, INPUT);
pinMode(ledPin, OUTPUT);
buttonState = digitalRead(switchPin);
myservo.write(0);

}

void loop() // run over and over again

//servo 1
{
val = digitalRead(switchPin); // read input value and store it in val
delay(10); // 10 milliseconds is a good amount of time
val2 = digitalRead(switchPin); // read the input again to check for bounces
if (val == val2) { // make sure we got 2 consistant readings!
if (val != buttonState) { // the button state has changed!
if (val == LOW) { // check if the button is pressed
if (servostatus == 0) { // is the light off?
servostatus = 1; // turn light on!

myservo.write(120);

delay(1000);
digitalWrite(ledPin, HIGH);
delay(50);
digitalWrite(ledPin, LOW);
delay(00);
digitalWrite(ledPin, HIGH);
delay(50);
digitalWrite(ledPin, LOW);
delay(00);


// fading
for(int fadeValue = 0 ; fadeValue <= 255; fadeValue +=5) {
// sets the value (range from 0 to 255):
analogWrite(ledPin, fadeValue);
delay(30);


}

} else {
servostatus = 0; // turn light off!


digitalWrite(ledPin, LOW);
delay(15);
myservo.write(25);







}
}
}
buttonState = val; // save the new state in our variable
}
}

I came up with this

Code:
#include <IRremote.h>  // Include IR Remote Library by Ken Shirriff
#include <Servo.h>    // Include Arduino Servo Library


const int RECV_PIN = 4;  // Define Sensor Pin
const int SERVO_PIN = 5;  // Define Servo Pin
int ledPin = 6;


int pos = 20;   // Define Variable for Servo position      


unsigned long lastCode;  // Define variable to store last code received


IRrecv irrecv(RECV_PIN);  // Define IR Receiver and Results Objects
decode_results results;


Servo myservo;  // Create servo object        


void setup()
{
  
  irrecv.enableIRIn();        // Start the receiver
   
  
  myservo.attach(SERVO_PIN);  // Attach the servo

  
  myservo.write(pos);    // Start with Servo in Center
}

void loop() {
if(irrecv.decode(&results)) //this checks to see if a code has been received
{

    if(results.value == 0xFFFFFFFF)   
    {
       
       results.value = lastCode;        // If Repeat then use last code received
    }

    if(results.value == 0xF7807F)    
    {
        
        myservo.write(120);

delay(1000);
digitalWrite(ledPin, HIGH);
delay(50);
digitalWrite(ledPin, LOW);
delay(00);
digitalWrite(ledPin, HIGH);
delay(50);
digitalWrite(ledPin, LOW);
delay(00);


// fading
for(int fadeValue = 0 ; fadeValue <= 255; fadeValue +=5) {
// sets the value (range from 0 to 255):
analogWrite(ledPin, fadeValue);
delay(30);
    }
      
    if(results.value == 0xF700FF)     
    {
       
       lastCode = results.value;   // 
         
digitalWrite(ledPin, LOW);
delay(15);
myservo.write(25);     
    }

  
    // Add delay to prevent false readings
    delay(30); 
    //receive the next value  
    irrecv.resume(); 
}
    
}
}


I don't have my servo plugged in at the moment, I was trying to see if the leds would mimic the behavior from the original helmet code. So far it seems as though what ever button I push the arduino only reads the first command and no others after that. Example if I hit the button associated with F7807F (closing the helmet) the leds fade on ( which before they blinked I believe twice and faded on, the blink is gone) but if I hit the button associated with F700FF ( open helmet) after I have already hit the close button the leds remain on ( they are suppose to turn off). Same thing happens in reverse if I hit the open helmet button the leds remain off and if I try to hit the button to close helmet the leds still remain off. I'm going to plug the servo up to see if it will work with this code, I'm just waiting for the battery to charge.
 
Ok so I have figured out the led part now I just need to plug the servo in and make sure it works as well. Still have a little bit of charging to go. Here's the revised code so far.

Code:
#include <IRremote.h>  // Include IR Remote Library by Ken Shirriff
#include <Servo.h>    // Include Arduino Servo Library


const int RECV_PIN = 4;  // Define Sensor Pin
const int SERVO_PIN = 5;  // Define Servo Pin
const int ledPin = 6;  // Define LED pin constants


int pos = 120;   // Define Variable for Servo position    
int togglestate = 0;  // Define integer to remember toggle state

unsigned long lastCode;  // Define variable to store last code received


IRrecv irrecv(RECV_PIN);  // Define IR Receiver and Results Objects
decode_results results;


Servo myservo;  // Create servo object      


void setup()
{

  irrecv.enableIRIn();        // Start the receiver
 

  myservo.attach(SERVO_PIN);  // Attach the servo


  myservo.write(pos);    // Start with Servo in Center

  pinMode(ledPin, OUTPUT);  // Set LED pins as Outputs
}

void loop() {
if(irrecv.decode(&results)) //this checks to see if a code has been received
{

   

    switch(results.value){
          case 0xF700FF: //down Keypad Button
    
        if(togglestate==0){
        myservo.write(120);

delay(1000);
digitalWrite(ledPin, HIGH);
delay(50);
digitalWrite(ledPin, LOW);
delay(00);
digitalWrite(ledPin, HIGH);
delay(50);
digitalWrite(ledPin, LOW);
delay(00);


// fading
for(int fadeValue = 0 ; fadeValue <= 255; fadeValue +=5) {
// sets the value (range from 0 to 255):
analogWrite(ledPin, fadeValue);
delay(30);
    togglestate=1;
    }
        }  else {
digitalWrite(ledPin, LOW);
delay(15);
myservo.write(25);   
  togglestate=0;
    }
    break;

      }
   
    irrecv.resume(); //receive the next value
}
  
}
 
(again).. you are trying to add new (IR) code to base code that is NOT mine. :)

I'm not familiar with it.. and I dont recommend using DELAYS().. ever. (unless its by design, otherwise its a blocking function)..

I know my code my be a bit more overwhelming, but it gives you more control over the pauses..etc.. between actions.

When you are in a DELAY() function.. nothing else happens. (so you cant even check if the button is being pressed)..

quick skim of the code looks like the delays shouldnt be an issue I guess. (still not recommended)


This code should work for you:

 
Last edited:
This is using the SAME IR lib... so it should work for you.

You obviously would have to wire things up the correct way using the correct PIN#'s for the IR, servo, and leds..etc..etc..

Code:
//import servo lib
#include <Servo.h>
#include <IRremote.h>

//New
int RECV_PIN = 2; //pin 2
IRrecv irrecv(RECV_PIN); //IRrecv
decode_results results; //decode_results

void irdisplay(unsigned long value){
    switch (value) {
    case 0xFD00FF:
        digitalWrite(RECV_PIN, LOW);
        break;
    }
}
//New End

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

const int buttonPin = 2; // the pin that the pushbutton is attached to
int buttonState = 0; // current state of the button
int lastButtonState = 0; // previous state of the button

// led control pins (need to be PWM enabled pins for fading)
const int leftEye = 6; // the number of the left eye/pcb LEDs
const int rightEye = 3; // the number of the right eye/pcb LEDs

unsigned long fadeDelay = .5; //speed of the eye 'fade'
unsigned long callDelay = 700; //length to wait to start eye flicker after face plate comes down
unsigned long blinkSpeed = 1; //delay between init blink on/off
unsigned long currentPWM = 0;
boolean isOpen = true;
int openAngle = 180;
int closeAngle = 0;

#define S_IDLE 1
#define S_LEDON 2
#define S_WAITON 3
#define S_LEDOFF 4
#define S_WAITOFF 5
#define S_INITON 6
#define S_INITWAIT 7
#define S_BLINKON 8
#define S_SERVOUP 9
#define S_SERVODOWN 0
#define S_SERVOWAIT 10

//FSM init vars
static int state = S_IDLE; // initial state is 1, the "idle" state (checking for IR input/commands).
static unsigned long lastTime; // To store the "current" time in for delays.


void setup() {
    // Set up serial port
    Serial.begin(9600);
    //start it off
    //state = S_BLINKON;
    Serial.print("INTIT STATE: ");
    Serial.println(state);

    myservo.attach(9); // attaches the servo on pin 9 to the servo object
    myservo1.attach(10); // attaches the servo on pin 10 to the servo object

    pinMode(buttonPin, INPUT); // initialize the button pin as a input
    digitalWrite(buttonPin, HIGH); //use interal pull up resistors

}

void loop() {
    switch (state) {
    case S_IDLE:
        // We don't need to do anything here, waiting for a forced state change...like button press.
        //check mian button state
        buttonState = digitalRead(buttonPin);

        // compare buttonState to previous state
        if (buttonState != lastButtonState) {
            //if button pressed/down
            if (buttonState == LOW) {
                //ie: pressed
                if (isOpen == true) {
                    Serial.print("CLOSING FACE PLATE: ");
                    Serial.println(isOpen, DEC);
                    state = S_SERVODOWN;
                } else {
                    Serial.print("OPENING FACE PLATE: ");
                    Serial.println(isOpen, DEC);
                    //state = S_SERVOUP;
                    state = S_LEDOFF;
                }
                isOpen = !isOpen;
            } else {
                //went from ON/HIGH to LOW/OFF..ie: released
                //Serial.print("RELEASE: ");
                //Serial.println(isOpen, DEC);
            }
        }
        // save the current state for next loop
        lastButtonState = buttonState;
        break;

    case S_BLINKON:
        Serial.println("init blink.........");
        //do blink routine here
        //one blink
        analogWrite(leftEye, 155);
        analogWrite(rightEye, 155);
        delay(blinkSpeed);
        analogWrite(leftEye, 0);
        analogWrite(rightEye, 0);
        delay(10);
        //two blinks
        /*
        analogWrite(leftEye, 155);
        analogWrite(rightEye, 155);
        delay(blinkSpeed);
        analogWrite(leftEye, 0);
        analogWrite(rightEye, 0);
        delay(10);
        */
        state = S_LEDON;
        break;

    case S_LEDON:
        Serial.println("increase........");
        lastTime = millis(); // Remember the current time
        analogWrite(leftEye, currentPWM);
        analogWrite(rightEye, currentPWM);
        state = S_WAITON; // Move to the next state
        break;

    case S_WAITON:
        // If one second has passed, then move on to the next state.
        if (millis() > (lastTime + fadeDelay)) {
            if (currentPWM < 255) {
                currentPWM += 5;
                state = S_LEDON;
            } else {
                Serial.println("@ 255 done........");
                state = S_IDLE;
                //state = S_LEDOFF; //no auto turn off.. set to idle state
            }
        }
        break;

    case S_LEDOFF:
        Serial.println("........decrease");
        lastTime = millis(); // Remember the current time
        analogWrite(leftEye, currentPWM);
        analogWrite(rightEye, currentPWM);
        state = S_WAITOFF;
        break;

    case S_WAITOFF:
        // If one second has passed, then move on to the next state.
        if (millis() > (lastTime + fadeDelay)) {
            if (currentPWM > 0) { //change 0 to higher number to init face 'up' function sooner.
                currentPWM -= 5;
                state = S_LEDOFF;
            } else {
                Serial.println("@ 0 done........");
                state = S_SERVOUP; //leds off..raise faceplate
            }
        }
        break;

    case S_SERVOUP:
        Serial.println("servo up.........");
        myservo.write(openAngle);
        myservo1.write(openAngle);
        state = S_IDLE;
        break;

    case S_SERVODOWN:
        lastTime = millis(); // Remember the current time
        Serial.println("servo down.........");
        myservo.write(closeAngle);
        myservo1.write(closeAngle);
        state = S_SERVOWAIT;
        break;

    case S_SERVOWAIT:
        // If enough time has passed, call the eye flicker routine
        if (millis() > (lastTime + callDelay)) {
            Serial.println("start eye flicker routine");
            state = S_BLINKON;
        } else {
            Serial.println("waiting........");
        }
        break;

    default:
        state = S_IDLE;
        break;
    }
}
 
Hi xl97 I have used your third version of the code (posted below) and have noticed there doesn't seem to be an int for servo angle in it. I was curious if this was an oversight or if it was controlled now somewhere else in the code.

Code:
// IronMan Helmet: eye blink sequence_v1.0
// created by: xl97


//import servo lib
#include <Servo.h>

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

const int buttonPin = 2; // the pin that the pushbutton is attached to
int buttonState = 0; // current state of the button
int lastButtonState = 0; // previous state of the button


// led control pins (need to be PWM enabled pins for fading)
const int leftEye =  6;  // the number of the left eye/pcb LEDs
const int rightEye =  3;  // the number of the right eye/pcb LEDs

unsigned long fadeDelay = .5; //speed of the eye 'fade'
unsigned long callDelay = 700; //length to wait to start eye flicker after face plate comes down
unsigned long blinkSpeed = 100; //delay between init blink on/off
unsigned long currentPWM = 0;
boolean isOpen = true;

#define S_IDLE 1
#define S_LEDON 2
#define S_WAITON 3
#define S_LEDOFF 4
#define S_WAITOFF 5
#define S_INITON 6
#define S_INITWAIT 7
#define S_BLINKON 8
#define S_SERVOUP 9
#define S_SERVODOWN 0
#define S_SERVOWAIT 10



//FSM init vars
static int state = S_IDLE; // initial state is 1, the "idle" state.
static unsigned long lastTime;  // To store the "current" time in for delays.


void setup() {
  // Set up serial port
  Serial.begin(9600); 
  //start it off
  //state = S_BLINKON;
  Serial.print("INTIT STATE: ");
  Serial.println(state);

  myservo.attach(9); // attaches the servo on pin 9 to the servo object
  myservo1.attach(10); // attaches the servo on pin 10 to the servo object

  pinMode(buttonPin, INPUT); // initialize the button pin as a input
  digitalWrite(buttonPin, HIGH); //use interal pull up resistors
}

void loop() {
  switch(state)
  {
  case S_IDLE:
    // We don't need to do anything here, waiting for a forced state change...like button press.
    //check mian button state
    buttonState = digitalRead(buttonPin);

    // compare buttonState to previous state 
    if (buttonState != lastButtonState) {
      //if button pressed/down
      if (buttonState == LOW){
        //ie: pressed   
        if(isOpen == true){
          Serial.print("CLOSING FACE PLATE: ");
          Serial.println(isOpen, DEC);
          state = S_SERVODOWN;
        }
        else{
          Serial.print("OPENING FACE PLATE: ");
          Serial.println(isOpen, DEC);
          //state = S_SERVOUP;
          state = S_LEDOFF;
        }
        isOpen = !isOpen;
      }
      else{
        //went from ON/HIGH to LOW/OFF..ie: released
        //Serial.print("RELEASE: ");
        //Serial.println(isOpen, DEC);
      }
    }
    // save the current state for next loop
    lastButtonState = buttonState;
    break;

  case S_BLINKON:
    Serial.println("init blink.........");   
    //do blink routine here
    //one blink
    analogWrite(leftEye, 155);
    analogWrite(rightEye, 155);
    delay(blinkSpeed);
    analogWrite(leftEye, 0);
    analogWrite(rightEye, 0);
    delay(10);
    //two blinks
    /*
    analogWrite(leftEye, 155);
     analogWrite(rightEye, 155);
     delay(blinkSpeed);
     analogWrite(leftEye, 0);
     analogWrite(rightEye, 0);
     delay(10);
     */
    state = S_LEDON;   
    break;

  case S_LEDON:
    Serial.println("increase........");   
    lastTime = millis();  // Remember the current time
    analogWrite(leftEye, currentPWM);
    analogWrite(rightEye, currentPWM);
    state = S_WAITON;  // Move to the next state
    break;

  case S_WAITON:
    // If one second has passed, then move on to the next state.
    if(millis() > (lastTime + fadeDelay)){
      if(currentPWM < 255){
        currentPWM += 5;
        state = S_LEDON;       
      }
      else{
        Serial.println("@ 255 done........");
        state = S_IDLE;
        //state = S_LEDOFF; //no auto turn off.. set to idle state
      }
    }
    break;

  case S_LEDOFF:
    Serial.println("........decrease");     
    lastTime = millis();  // Remember the current time
    analogWrite(leftEye, currentPWM);
    analogWrite(rightEye, currentPWM);
    state = S_WAITOFF;
    break;

  case S_WAITOFF:
    // If one second has passed, then move on to the next state.
    if(millis() > (lastTime + fadeDelay)){
      if(currentPWM > 0){  //change 0 to higher number to init face 'up' function sooner.
        currentPWM -= 5;
        state = S_LEDOFF;       
      }
      else{
        Serial.println("@ 0 done........");
        state = S_SERVOUP; //leds off..raise faceplate
      }
    }
    break;

  case S_SERVOUP:
    Serial.println("servo up.........");
    myservo.write(100);
    myservo1.write(100);
    state = S_IDLE;   
    break;

  case S_SERVODOWN:
    lastTime = millis();  // Remember the current time
    Serial.println("servo down.........");   
    myservo.write(0);
    myservo1.write(0);
    state = S_SERVOWAIT;   
    break;

  case S_SERVOWAIT:
    // If enough time has passed, call the eye flicker routine
    if(millis() > (lastTime + callDelay)){   
      Serial.println("start eye flicker routine");
      state = S_BLINKON;       
    }
    else{
      Serial.println("waiting........");
    }
    break;

  default:
    state = S_IDLE;
    break;
  }
}
 
Its been a long time since I've looked at this stuff.. LOL (or the different versions and what they do/are for)

at quick glance.. looks likes it hard coded? in S_SERVODOWN section...

edit there or replace with variable.
 
Thanks very much for the fast reply - I appreciate it's been some time since you did all this. Thanks for responding.

I have changed around the variables

Code:
    myservo.write(0);
    myservo1.write(0);

To read

Code:
    myservo.write(0);
    myservo1.write(100);

And the other way around on the servoup section because my servos are in the opposite direction from each other and that worked just fine. I wasn't sure if those were opening angles or just open close integers. I thought i would ask because those variables are there in the second version of the code but still there's an int for angles.
 
hey new hear don't even know if this forum is still active, I have an issue and seen someone post the same problem a few years ago and don't see an answer to it, when I connect power each time one of the servos moves a bit, twisting the faceplate, after 1 button press the servos go back into alignment and work fine from there on unless power is disconnected and reconnected then it 1 moves out of sync again till i press the button
all grounds are connected from both servos the Arduino mini and to the voltage regulator, LEDs haven't been installed yet but there ground wire is there too. I'm using version 3 code from page 2. with 1 small change
Code:
 case S_SERVOUP:
    Serial.println("servo up........."); 
    myservo.write(100);
    myservo1.write(0);
    state = S_IDLE;    
    break;

  case S_SERVODOWN:
    lastTime = millis();  // Remember the current time
    Serial.println("servo down.........");   
    myservo.write(0);
    myservo1.write(100);
    state = S_SERVOWAIT;    
    break;

i needed to make this change or the servos were driving in opposite directions

thanks
gordon
 

Your message may be considered spam for the following reasons:

If you wish to reply despite these issues, check the box below before replying.
Be aware that malicious compliance may result in more severe penalties.
Back
Top