Convertible Soft Top Controller

So looking to make my own hand held soft top controller. The car is a Mercedes clk 320. Here is the data I have come up with so far. The hydraulic pump has 7 solenoid valves. Each valve is opened with 12v DC. The pump motor is operated with a 20-40amp relay. I can turn the pump on by jumping two pins in the relay box. The pump must be on and the chosen valve open to move that part of the soft top. Here is the steps I need to perform to open the soft top and put it into the trunk.

Note. When valves are triggered pump must be running!

  1. Unlock rear deck and window hatch - solenoid #5

  2. Rear window forward (Moves the back window forward enough to raise the deck that covers the opening to the front half of the trunk that the top sleeps in :wink: solenoid #4

  3. Raise rear deck solenoid #? (Will have it figured out by end of today)

  4. Rear window back and since the deck is now up, It will keep going back into the trunk along with the top of the roof. solenoid #3

  5. Lower deck covering the top and making the car look 10x better solenoid #7

  6. Lock deck solenoid #6

  7. close rear window hatch so when you put the top back up it simply clicks into the hatch and locks (this is done by turning the pump on with no open valves( It will also lock the deck hatch and put pressure behind the closed system locking it all into place))

Might be a little complicated to make this work. If I have to use 6 buttons with a relay to the pump that is fine. If there is a better way, thats why I am here asking for input. And I am not willing to make the factory one work again. They have more sensors on this car then a 777 aircraft.

I was hoping to next count the time it took to do each step, then writing a program to automatically trigger the next solenoid valve accordingly to the value put into the code. Then have a kill switch just in case some unforeseen event comes about, or simply taking you finger off the button will stop the process. But then having the controller knowing where to pick back up the process is past my knowledge of coding.

Thanks a lot guys and enjoy the rest of your day.

Here what I have so far

/* 
Soft Top Controller 1.0

*/
  const int PushButton_0 = 0; //Drive Pump w/o open valves / valve #-
  const int PushButton_1 = 1; //Rear Window Back or Top into Trunk / valve #3
  const int PushButton_2 = 2; //Rear Window Forward or Top up / valve #4
  const int PushButton_3 = 3; //Deck Lid & Window Latch unlock / valve #5
  const int PushButton_4 = 4; //Deck Lid Lock / valve #6
  const int PushButton_5 = 5; //Deck Lid Close / valve #7
  const int Mosfet_0 = 6; //Push Button 0 to Mosfet gate pump relay
  const int Mosfet_1 = 7; //Push Button 1 to Mosfet Gate #3 
  const int Mosfet_2 = 8; //Push Button 2 to Mosfet Gate #4 
  const int Mosfet_3 = 9; //Push Button 3 to Mosfet Gate #5
  const int Mosfet_4 = 10; //Push Button 4 to Mosfet Gate #6 
  const int Mosfet_5 = 11; //Push Button 5 to Mosfet Gate #7

 // int PushButtonCounter = 0;           // Counter for the number of push button presses.
  int buttonState = 0;          // Current state of the push button.
//  int LastButtonState = 0;             // Previous state of the push button.
//  unsigned long ButtonPressed;


void setup()
{
  pinMode(PushButton_0, INPUT);
  pinMode(PushButton_1, INPUT);
  pinMode(PushButton_2, INPUT);
  pinMode(PushButton_3, INPUT);
  pinMode(PushButton_4, INPUT);
  pinMode(PushButton_5, INPUT);
  pinMode(Mosfet_0, OUTPUT);
  pinMode(Mosfet_1, OUTPUT);
  pinMode(Mosfet_2, OUTPUT);
  pinMode(Mosfet_3, OUTPUT);
  pinMode(Mosfet_4, OUTPUT);
  pinMode(Mosfet_5, OUTPUT);
 
}
void loop() {
  // put your main code here, to run repeatedly:
if (digitalRead(PushButton_0) == HIGH)
{
  digitalWrite(Mosfet_0, HIGH);
 }
else
{
  digitalWrite(Mosfet_0, LOW);

 }


if (digitalRead(PushButton_1) == HIGH)
{
  digitalWrite(Mosfet_0, HIGH);
  digitalWrite(Mosfet_1, HIGH);
 }
else
{
  digitalWrite(Mosfet_0, LOW);
  digitalWrite(Mosfet_1, LOW);
 }

if (digitalRead(PushButton_2) == HIGH)
{
  digitalWrite(Mosfet_0, HIGH);
  digitalWrite(Mosfet_2, HIGH);
 }
else
{
  digitalWrite(Mosfet_0, LOW);
  digitalWrite(Mosfet_2, LOW);
 }

if (digitalRead(PushButton_3) == HIGH)
{
  digitalWrite(Mosfet_0, HIGH);
  digitalWrite(Mosfet_3, HIGH);
 }
else
{
  digitalWrite(Mosfet_0, LOW);
  digitalWrite(Mosfet_3, LOW);
 }

if (digitalRead(PushButton_4) == HIGH)
{
  digitalWrite(Mosfet_0, HIGH);
  digitalWrite(Mosfet_4, HIGH);
 }
else
{
  digitalWrite(Mosfet_0, LOW);
  digitalWrite(Mosfet_4, LOW);
 }
 if (digitalRead(PushButton_5) == HIGH)
{
  digitalWrite(Mosfet_0, HIGH);
  digitalWrite(Mosfet_5, HIGH);
 }
else
{
  digitalWrite(Mosfet_0, LOW);
  digitalWrite(Mosfet_5, LOW);
  }
}

casmic911:
Thanks a lot guys and enjoy the rest of your day.

It was kind of you to give us all that information but I'm not clear what you are hoping that we might do in return?

If you want someone to write a program for you please ask in the Gigs and Collaborations section of the Forum and be prepared to pay.

...R

I am sure I can write it. I just posted the code I just wrote. I am new to Arduino so I am asking for help to make sure the code will run smooth and tips on hardware. Since the solenoids are 12V I will have to run a Mosfet. I have some IRLZ34N Mosfets but not sure if they will work. I also Have to drive a 40 amp relay with a Mosfet I believe, to turn the pump motor on while turning on/off the valves. Is there a way to run all valves off one Mosfet or do I need each one separate?

Sorry one other thing. In the if statement of the code, does the way I wrote it turn all pins on then off by pushing a button? If so do I have to write an if statement for each button, or can I make a variable of the HIGH and LOW state. Thanks

Start with turning an LED on and off. Then a 12V light, using a mosfet.

Then open up the "blink without delay" example and study it.

After that, you will be ready to understand State Machine

Yea good advice. I will do that. I have edited the code because I forgot that the pump has to come on with each valve. i am going to start the led test. thank you.

Well I am having no luck :frowning:

/* 
Soft Top Controller 1.0

*/
 // boolean Mos0 = HIGH, Mos1 = HIGH, Mos2 = HIGH, Mos3 = HIGH, Mos4 = HIGH, Mos5 = HIGH;
  int But0 = 0; //Drive Pump w/o open valves / valve #-
  int But1 = 1; //Rear Window Back or Top into Trunk / valve #3
  int But2 = 2; //Rear Window Forward or Top up / valve #4
  int But3 = 3; //Deck Lid & Window Latch unlock / valve #5
  int But4 = 4; //Deck Lid Lock / valve #6
  int But5 = 5; //Deck Lid Close / valve #7
  int Mos0 = 6; //Push Button 0 to Mosfet gate pump relay
  int Mos1 = 7; //Push Button 1 to Mosfet Gate #3 
  int Mos2 = 8; //Push Button 2 to Mosfet Gate #4 
  int Mos3 = 9; //Push Button 3 to Mosfet Gate #5
  int Mos4 = 10; //Push Button 4 to Mosfet Gate #6 
  int Mos5 = 11; //Push Button 5 to Mosfet Gate #7

// int PushButtonCounter = 0;           // Counter for the number of push button presses.
//  int buttonState = 0;          // Current state of the push button.
//  int LastButtonState = 0;             // Previous state of the push button.
//  unsigned long ButtonPressed;

void setup()
{
  pinMode(0,INPUT);
  pinMode(1,INPUT);
  pinMode(2,INPUT);
  pinMode(3,INPUT);
  pinMode(4,INPUT);
  pinMode(5,INPUT);
  pinMode(6,OUTPUT);
  pinMode(7,OUTPUT);
  pinMode(8,OUTPUT);
  pinMode(9,OUTPUT);
  pinMode(10,OUTPUT);
  pinMode(11,OUTPUT);
 
}
void loop() {
  // put your main code here, to run repeatedly:
if (digitalRead(But0 == HIGH))
{
  digitalWrite(Mos0, LOW);
  Mos0 = LOW;
  
 }
else
{
  digitalWrite(Mos0, HIGH);
  Mos0 = HIGH;

 }

if (digitalRead(But1 == HIGH))
{
  digitalWrite(Mos0, HIGH);
  digitalWrite(Mos1, HIGH);
  Mos0 = HIGH;
  Mos1 = HIGH;
 }
else
{
  digitalWrite(Mos0, LOW);
  digitalWrite(Mos1, LOW);
  Mos0 = LOW;
  Mos1 = LOW;
 }
if (digitalRead(But2 == HIGH))
{
  digitalWrite(Mos0, HIGH);
  digitalWrite(Mos2, HIGH);
  Mos0 = HIGH;
  Mos2 = HIGH;
 }
else
{
  digitalWrite(Mos0, LOW);
  digitalWrite(Mos2, LOW);
  Mos0 = LOW;
  Mos2 = LOW;
 }
 if (digitalRead(But3 == HIGH))
{
  digitalWrite(Mos0, HIGH);
  digitalWrite(Mos3, HIGH);
  Mos0 = HIGH;
  Mos3 = HIGH;
 }
else
{
  digitalWrite(Mos0, LOW);
  digitalWrite(Mos3, LOW);
  Mos0 = LOW;
  Mos3 = LOW;
 }
if (digitalRead(But4 == HIGH))
{
  digitalWrite(Mos0, HIGH);
  digitalWrite(Mos4, HIGH);
  Mos0 = HIGH;
  Mos4 = HIGH;
 }
else
{
  digitalWrite(Mos0, LOW);
  digitalWrite(Mos4, LOW);
  Mos0 = LOW;
  Mos4 = LOW;
 }
if (digitalRead(But5 == HIGH))
{
  digitalWrite(Mos0, HIGH);
  digitalWrite(Mos5, HIGH);
  Mos0 = HIGH;
  Mos5 = HIGH;
 }
else
{
  digitalWrite(Mos0, LOW);
  digitalWrite(Mos5, LOW);
  Mos0 = LOW;
  Mos5 = LOW;
 }
 
}

casmic911:
Well I am having no luck :frowning:

That may be true but it does not contain information that enables us to help you.

You need to tell us in as much detail as possible exactly what your program does and what you want it to do that is different.

...R

It is good practice to declare your pin numbers as const int because then the compiler will let you know you are doing something stupid in that sketch.

Ok so here the thing on this project. I was trying to recreate the factory convertible open close. The software did bite me in the ass and was so frustrated I couldn't even switch the dang led exercise mentioned. I went to hardware. Note I had 7 buttons that simply provided the switch for the 12v solenoids. And one that triggered the factory relay turning the pump on. Come to find out it's not that easy. I almost had it but there a combination of solenoids that must be opened/closed at a critical point that I couldn't replicate. I got tired of charging the battery over and over. The original open close is done with a single switch. So that was my goal to begin with but I needed a lot of help since new to Arduino. I have now learned more and created a simple project. As to the comment on the
const int.

From what I understand witch is very little is it holds a pin or variable permanent. I had a problem with this exact piece of code and removing the const made it possible to compile the program. My question would be. How does it help you know where u went wrong? My problem being new to c or Arduino, is the placement and structure. Coming from a mostly Unix shell script where the if command was

if [ ! -r $var ]; then
do this thing
else
do this thing
fi

So I guess what I am asking or saying is there a good place online to find info on the structure of the code. As to the "()" brackets and the { function. Also aside form the provided libraries for hardware. What language of code can be implimented into Arduino. Here my last projects code to give a brief what I can understand. Thanks again for the replies

//Cameron's Car door led, lcd, distance activated light controller

#define BLUE 6
#define RED 8
#include <LiquidCrystal.h> // includes the LiquidCrystal Library
const int rs = 12, en = 11, d4 = 5, d5 = 4, d6 = 3, d7 = 2;
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);
const int trigPin = 9; //Ultrasonic Sensor trig pin
const int echoPin = 10; // its echo pin
const int relay = 13; //The relay trigger pin
long duration;
int distanceInch, distanceCm;
int i;
int brightness = 0;    // how bright the LED is
int fadeAmount =15;    // How many steps to fade

void setup() 
   
   {
    lcd.begin(16,2); //Brings up the LCD 
    pinMode(trigPin, OUTPUT); //Setup pin function
    pinMode(echoPin, INPUT);
    pinMode(relay, OUTPUT);
    pinMode(RED, OUTPUT);
    pinMode(BLUE, OUTPUT);
    digitalWrite(RED, HIGH);
    digitalWrite(BLUE, HIGH);
  }

void loop() {


brightness = brightness + fadeAmount; //For changing the LED state

// Distance of Door or whatever from sensor

digitalWrite(trigPin, LOW);
delayMicroseconds(2);
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
duration = pulseIn(echoPin, HIGH);
//distanceCm= duration*0.034/2; //option to have cm
distanceInch = duration*0.0133/2;

//#define delayTime 5

// Prints a few thing to 16, 2 type Display (optional)
lcd.setCursor(0,2);
lcd.print("-----> ");
lcd.print(distanceInch); //change to distanceCm if you want
lcd.print(" in"); // change to cm if you want
delay(10);

// Door distance trigger
            
            if (distanceInch > 3) // If Door is OPEN //Change number to however many inches until it triggers the relay
    {
            digitalWrite(relay, HIGH); // Sends signal to relay to turn lights or whatever on
            digitalWrite(RED, HIGH); //Used an RGB LED so had to turn color on 
            digitalWrite(BLUE, LOW); // And this off
            lcd.setCursor(0,0);
            lcd.print("Goodbye!...."); //Choose whatever you want to say inside the ""

        // A little fun with the LCD to make the statement scrool off left then come back from the right. Giving the illusion it is wrapping around
                
                for (int positionCounter = 0; positionCounter < 17; positionCounter++) {
                lcd.scrollDisplayLeft();
                delay(200);
  }
                for (int positionCounter = -17; positionCounter < 0; positionCounter++) {
                lcd.scrollDisplayLeft();
                delay(200);
          
     analogWrite(RED, brightness); // Turns on LED RED
  }
 analogWrite(RED, brightness); // Makes the LED Blink
 if (brightness <= 125 || brightness >= 255) {
    fadeAmount = -fadeAmount;
 }
 delay(10);
 }
else if (distanceInch < 3) // If door is CLOSED
{
 digitalWrite(relay, LOW); // Send signal to relay turning Lights or whatever off
digitalWrite(BLUE, HIGH); //Turn on BLUE
 digitalWrite(RED, LOW); // Turn off RED
 
 lcd.setCursor(0,0);
 lcd.print("Where we going?"); // Door Closed Statement Put whatever inside ""
              
        // LCD Trick
              
              for (int positionCounter = 0; positionCounter < 18; positionCounter++) {
              lcd.scrollDisplayLeft();
              delay(200);
  }
              for (int positionCounter = -18; positionCounter < 0; positionCounter++) {
              lcd.scrollDisplayLeft();
              delay(200);
  }
    analogWrite(BLUE, brightness);
 if (brightness <= 0 || brightness >= 200) { // Change to however bright you want the LED on the BreadBoard
    fadeAmount = -fadeAmount;
    }
   delay(10);
  }
}

The problem with this code I struggle with still is the LCD. When the sensor senses the object is far enough and the relay is switched. When the new lcd.print for the next triggered function. The new string on the LCD sometimes carries a few letters from the function before at the end of the statement. I have tried to adjust delay and impliment lcd.clear but it changes the way the words scroll. So ? Is this due to my vague understanding of the code structure?

The simple fix to the LCD lettering is to make sure that each new string printed to the LCD includes enough spaces at the end to overwrite whatever was there before.

Your code is covered with delays. It's time to switch to a state-machine approach. You are going to have a lot of states, so start with a clean sheet of paper. Top-center, write "unknown" and draw a circle around it. This is the state when just switched on. The Arduino doesn't yet know if the top is up or down. Maybe there's a switch that tells you it's fully up and latched and maybe there's another for down? So if the down switch is triggered, you can move out of the "unknown" state into "down and latched".

Within each state, the Arduino is actively driving its outputs and reading all of the switches and buttons. It also may keep the time that it entered the state, so it knows how long it spent in that state.

The state transitions are the arrows leading between the states. Pressing the "up" button obviously moves you out of the "down" state and into some state that's driving the relays to begin the up process. You might start with "unlatch from down" which drives the latches open. Maybe you don't have a switch to tell you when the latches reach fully-open, so you just have to do it by time. So after 500ms or whatever, you move to the next state which might be "driving up".

Pretty much every state will react to the "emergency stop" button (if you have one.) Or, like normal soft-top operations, if you release the button it will stop. That adds a lot of states because you still want to remember where you are in the up or down cycle.

The blinky/fading LEDs are also state machines of their own. "Standby" "fading-up" and "fading-down" might be all you need for each one. The other state machine may send the LED into "fading up" or "standby" to get it started or stopped. Each X milliseconds in "fading-up", increase the brightness by fadeAmount unless you reach the maximum brightness, then switch to "fading-down".

The LCD may have "scrolling" and "not scrolling" states. Maybe more. If 200ms has expired since you last did a scroll and you're still in the "scrolling" state, make it scroll by one step. Don't use delay().