Benoit Debled

Software Developer
Firmware Developer
SysAdmin
Entrepreneur

Bubble bath

This is my real first project as a young computer programmer! Well, before I used to create some little websites but let’s say that it doesn’t count. I have a bubble bath at my parent’s house that had some crappy electronics to run two pumps : one for the air bubble and one for the jets. But one day, probably due to condensation, that electronic failed… So we had to figure out a way to control those two pumps.

my dad’s work, some people use a device called Crouzet that could have allowed to drive those two pumps. But this device is quite expensive ! So, after some research, I found out that the parallel port on any computer could be controlled with a C function. With some electronics behind, it could be then possible to drive those two pumps! So, after some work on the electronic, I’ve made a little program in C, and later in C++ to control the pumps.

I wish that I would have discovered arduino earlier as it would have simplify this project a lot ! I’m still sharing with you this project in case you need to control a parallel port on an old computer, but I doubt that ! So the only thing to learn from this project is that C function that allows you to set 8 outputs of a parallel port : outbmo

Btw, sorry, but in this code, my comments, var names, and functions names are in french… My english was pretty bad at that time, and I wasn’t accustomed to code in english…


////////////////////////////////////
// Auteur : Benoit Debled
// Date : 22/02/09
// Version : 0.5 final
// But : baignoire
////////////////////////////////////

//Include
#include <iostream>
#include <sys/io.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <math.h>
using namespace std;

// Prototype
void etape(int puissance_jets, bool variable_jets, int puissance_bulles, bool variable_bulles, int temps_fonction);

// Main
int main()
{
    if(ioperm(0x378, 1, 1))
    {
        perror("ioperm");
        exit(1);
    }
        cout << "\033[01;31m################### DÉBUT DE PROGRAMME ###################\033[00;30m" << endl; 
    etape(0,false,14,true,90);

    cout << "\033[01;31m#################### FIN DE PROGRAMME ####################\033[00;30m" << endl;
        return 0;
}

// Variable
bool precedent_variable_jets = false;
int precedent_puissance_jets = 0;
int actual_inb = 0;
int numero_etape = 1; 

// Fonction étape
void etape(int puissance_jets, bool variable_jets, int puissance_bulles, bool variable_bulles, int temps_fonction)
{
    cout << "\033[00;32m&&&&&&&&&&&&& étape n°" << numero_etape << " &&&&&&&&&&&&&\033[00;30m" << endl;
    // Jets
        cout << "\033[04;34m Jets \033[00;34m" << endl;
        // Allumage/éteignage
        if(puissance_jets >> 0 && precedent_puissance_jets == 0 || puissance_jets == 0 && precedent_puissance_jets >> 0)
        {
            actual_inb = inb(0x378);
            outb(actual_inb+16, 0x378);
            usleep(500000);
            outb(actual_inb, 0x378);
            cout << "  allumage/éteignage de la pompe" << endl;
            sleep(2);
        }
        // Calcul de la différence
        int diff_precedent_actuel = puissance_jets - precedent_puissance_jets;
        // Augmentation
        if(diff_precedent_actuel > 0)
        {
            cout << "  puissance : " << puissance_jets << " => augmentation de " << diff_precedent_actuel << " secondes" << endl;
            outb(actual_inb+32, 0x378);
            usleep(500000*diff_precedent_actuel);
            outb(actual_inb, 0x378);
        }
        // Diminution
        if(diff_precedent_actuel < 0)
        {
            cout << "  puissance : " << puissance_jets << " => diminution de " << fabs(diff_precedent_actuel) << " secondes" << endl;
            outb(actual_inb+64, 0x378);
            usleep(500000*fabs(diff_precedent_actuel));
            outb(actual_inb, 0x378);
        }
        // Variable
        if(variable_jets == true && precedent_variable_jets == false || precedent_variable_jets == true && variable_jets == false)
        {
            cout << "  alternatif : activé" << endl;
            outb(actual_inb+128,0x378);
            usleep(500000);
            outb(actual_inb,0x378);
        }
    // Actualisation de l'état des jets
        precedent_puissance_jets = puissance_jets;
    // Bulles
        cout << "\033[04;34m Bulles \033[00;34m" << endl;
        // Alternatif
        if(variable_bulles == true)
        {
            cout << "  alternatif : activé\033[00;30m" << endl;
            int bulles = 0;

            int bulles2[10];
            bulles2[0] = 5;
            bulles2[1] = 9;
            bulles2[2] = 1;
            bulles2[3] = 14;
            bulles2[4] = 6;
            bulles2[5] = 10;
            bulles2[6] = 2;
            bulles2[7] = 12;
            bulles2[8] = 4;
            bulles2[9] = 8;
            bulles2[10] = 0;

            for(int time=0; time < temps_fonction; time++)
            {
                bulles = round(10*fabs(sin(2*M_PI/120*time)));      
                outb(bulles2[bulles], 0x378);
                cout << bulles << " - " << flush;
                usleep(500000);
            }
            cout << endl;
        }
        // Statique
        else
        {
            cout << "  puissance : " << puissance_bulles << endl;
            cout << "  alternatif : désactivé\033[00;30m" << endl;
            outb(15-puissance_bulles, 0x378);
            sleep(temps_fonction);
        }
    numero_etape++;
}