Projets:Appui-tete electrique

De wikilab

Le projet de l'appui tête électrique est proposé par Mathilde.

Description du projet

Créer un support à bas-coût permettant de soutenir et faire pivoter la tête d'une personne dont l'insuffisance musculaire au niveau du cou ne lui permet ni un soutien ni une rotation naturelle de gauche à droite (la rotation n'étant pas impossible articulairement mais uniquement musculairement). Mathilde ne souhaite pas un énième bouton de télécommande pour le contrôle de cette fonctionnalité car elle en a déjà beaucoup et ne peut pas toujours y accéder selon les circonstances.

Cahier des charges

Le dispositif doit :

 * supporter le poids de la tête,
 * permettre une rotation de 30° à gauche, 30° à droite,
 * être piloté électroniquement à la demande,
 * supporter un usage quotidien en toutes conditions (vibrations, humidité, chaleur,...)
 * être suffisamment hermétique pour ne pas que les cheveux se prennent dans le mécanisme
 * être résistant aux intempéries
 * prendre en compte que Mathilde va être équipé d'un nouveau fauteuil

Analyse de l'existant

Cette solution n'existe pas dans le commerce, il en existe seulement des non électriques.

La solution suivante a été testée et convient à Mathilde sauf le manque d'aide électrique. http://www.medifab.co.nz/products/wheelchair-seating/axion-rotary-interface-wheelchair-headrests

Exemple d'interface rotative du commerce : https://media.wix.com/ugd/3c5a2b_070f4373519443e69189391e8c695b87.pdf

Détail sur le mécanisme de roulements http://ot-sieber.ch/wp-content/uploads/2016/03/DSC_0052_3-180x180.jpg

Equipe

  • Mathilde Fuchs, responsable du projet
  • Yves Le Chevalier, conception 3D
  • Philippe Pacotte, conception 3D
  • Laurent Danke, conception
  • Stéphane, électronique, moteur
  • Delphine, coordination

Pistes de recherche

Electronique

Utilisation de capteurs musculaires :

   +++ instinctif
   - prix (qualité du capteur)
   - mise en oeuvre (choix de l'emplacement au quotidien)

Utilisation d'une commande type interrupteur :

   ++ simple à mettre en oeuvre,
   -  ajoute une commande manuelle sur un dispositif déjà bien rempli

Mécanique

L'axe de rotation naturel de la tête se situe au niveau des vertèbres cervicales placées sous le crâne.

[images anatomiques face/profil d'un squelette]

Deux possibilités :

1: on respecte cet axe :

       ++ mouvement naturel de la tête,
       - plus complexe à concevoir (effort mécanique plus important),
       - dispositif potentiellement plus encombrant
   --> 1er choix exploré, refaire un peu comme celui du commerce mais en l'électrifiant (avec donc arceau de rotation) (quid du brevet de celui du commerce)
   ---> 2e choix exploré, mettre une crémaillère à l arrière de l'appui tête actuel (difficulté à garder la rotule de réglage et aussi la solidité... déporter la rotule...) modélisation de Danke et Yves

Crémaillère + vis sans fin

      ++ la crémaillère est bloquée en position si le moteur ne tourne pas
      - force sur l'axe moteur faible
      - frottement de la vis sur la crémaillère


2: on déplace l'axe sous la têtière, au plus proche de la colonne vertébrale :

       ++ mécanisme grandement simplifié
       + effort mécanique diminué (moins de bras de levier)
       -- mouvement moins naturel (risque de traumatisme sur la durée ?)

Choix exploré, mettre l'axe de rotation dans l appui tete avec double gros roulements et la rotation s'effectuerait avec un bras relié au moteur déporté légèrement en arrière (cela nécessite de refaire l'appui tete et mathilde émet des craintes sur cela) modélisation philippe et ?

Test capteur musculaire avec le "Finger starter"

Objectif : contrôler la rotation grâce à deux capteurs placés de part et d'autre du cou et déclenchés par contraction musculaire (seul endroit pour Mathilde où elle a un tendon qui permet de détecter une contraction par un capteur)

Lien vers video facebook du capteur Ottobock en action

Limites :

- Il faut deux capteurs constamment sur le cou.

- Les capteurs doivent adhérer parfaitement à la peau et avec le mouvement de contraction, il a tendance à se décoller.

Conclusion:' Il faudrait envisager une autre solution. Peut-être un micro switch (comme les "end-stop" que l'on trouve sur des imprimantes 3D).

Code Arduino mappé sur la contraction du cou de Mathilde

int muscle;
//servo library
#include <Servo.h>
Servo myservo;  // create servo object to control a servo
int val;    // variable to read the value from the analog pin

void setup()
{
  myservo.attach(7);  // attaches the servo on pin 9 to the servo object
  Serial.begin(57600);
  pinMode(A0,INPUT);
    myservo.write(0);
}
void loop()
{
//muscle
muscle=analogRead(A0);
Serial.println(muscle);

 //action of the finger
 if(muscle>20){
  kikoo();
  }
  else{
  myservo.write(50);
  delay(100);
  }
 }

//action of the finger : the last point is without tension (90 degrees).
void kikoo(){
  myservo.write(100);
  delay(100);   
}

Premières conceptions de l'appui tête en 3D

Ebauche 29.03.2017, Version 1 Yves Le Chevalier :

Ebauche 03.04.2017, version Philippe Pacotte :

Limites  : L'axe de rotation n'est pas dans l'axe du cou et risque de poser problème. Cette version est donc abandonnée.

Version2 04.04.2017, Yves Le Chevalier :

Notes  : J'ai travaillé sur une seconde maquette avec une rotation par vis sans fin et réglage motorisé de l'inclinaison. Ce n'est ici aussi qu'une ébauche pour matérialiser mes idées, mais cela ne peut pas être fonctionnel en l'état.

Addon v2 07.04.2017, Yves Le chevalier :

Notes : En vue de ta réunion de lundi, voici un petit travail qui pourra servi de support à votre discussion. J'ai, en effet, un peu retravaillé ce matin le projet suite à nos échanges d'hier. (cf photos ci dessous) J'ai donc dessiné une lame cintrée en métal (acier ?) avec une bille (soudée) pour permettre le raccordement sur la rotule du collier anatomique. Le moteur (Nema 17) entraîne l'ensemble par une vis sans fin. Le tout est monté sur supports articulés.

Le rail de guidage doit être vissé en le cintrant sur la lame de métal en dessous du point de fixation de l'entraînement.

Je suis passé voir John pour lui demander ce qu'on pouvait fraiser avec la CNC au LabFab afin de faire le rail de guidage. On ne peut fraiser que orthogonalement et dans les 3 directions mais sans incliner la fraise. Par contre on peut fraiser une dépouille en biais avec une fraise a 45° par ex. (mais à acheter) Par contre cela peut être fait ailleurs s'il le faut (Airbus, lycée technique,...?) Le conseil de John c'est de concevoir un rail droit dans une matière semi-souple (nylon ?) qui pourra être cintré selon l'arc en métal.

v2 10.04.2017, Yves Le chevalier :

Notes : Je pense que le rail courbe est faisable à la CNC dans un bloc de téflon ou nylon.... sinon le rail droit a le même profil mais me semble difficile à courber une fois fait.


Fichiers sources Freecad + photos

http://dl.free.fr/vizWvvTT0

Choix des matériaux

Questions pour rencontre le 10/04/2017 avec Francis Esnault (ingénieur mécanique/résistance de matériaux)

Choix judicieux du moteur : (si trop puissant = consomme trop) Le couple du moteur (en N/m) doit permettre de supporter l'ensemble : poids de la tête, poids ensemble mécanismes, frein rotation cou).Cela va conditionner la taille du mécanisme.

si crémaillère nylon : quel type de vis sans fin ? (métal, imprimée, nylon,....?):usure dûe à la friction à prendre en compte

profil du rail de guidage pour usinage facile au LabFab (CNC 3 axes) et choix matière  : nylon, téflon,.... sachant que rail courbe

question à Mathilde : De combien on peut baisser la tige de l'appui tête dans le dossier du fauteuil (conditionne hauteur disponible pour le systeme motorisé) sans considérer que Mathilde doit être dessus, c'est juste pour un calcul Peux-tu ramener les clés allen pour devisser le reglage de ton ancien support d'appui tête

Retour de Francis sur la dernière proposition de Yves

Le système avec la vis sans fin est un peu complexe et prend beaucoup de place. Il faut peut-être envisager une simplification du système sur le modèle qu'avait envisagé Danke comme le modèle ci-dessous.


Calcul de Francis pour le choix du moteur 13.04.2017

Télécharger le détail des calculs.

Nota bene : Avec un diamètre de tête de 220 mm :

- les effets d'inertie demeurent négligeables(très faible accélération angulaire) devant le couple résistant dû aux forces de contact

- le couple résistant, à contrario, se trouve significativement augmenté

Au final, on arrive à un couple moteur théorique devant être délivré par le moteur :

C moteur = 0,15 Nm (le double de mon précédent résultat)

Vue arrière de la fixation de l'appui-tête 06.04.2017

Mesures 13.04.2017

Modélisation du prototype final 19.04.2017, Yves Le Chevalier

Toutes les instructions sur ce pdf : http://wikilab.myhumankit.org/images/a/a1/ATM_V3_Notes_de_fabrication_et_de_montage.pdf

Tous les fichiers stl+FCStd+images : Fichiers


Fichier:ATM-V3 modele rails alu.stl

Schema fritzing carte de commande 27/04/2017, Stéphane

Firmware Arduino, Stéphane

Le fichier .zip avec le projet complet Appuitete-arduino.v1

V1.0 27/04/2017

Fichier principal

#include <SoftTimer.h>
#include <Task.h>
#include <AccelStepper.h>
#include <MultiStepper.h>

#include "config.h"


// task definition for periodic scheduling 1ms
void motorControl(Task* me);
Task schedule (1, motorControl);

// stepper configuration
AccelStepper stepper1(AccelStepper::DRIVER, MOTOR_STEP, MOTOR_DIR);

void setup() {
  // initialize motor
  stepper1.setMaxSpeed (MAX_SPEED);
  stepper1.setAcceleration (MAX_ACCEL);
  // initialize led
  pinMode(LED, OUTPUT);
  digitalWrite (LED, LOW);

  // initialize buttons
  pinMode(BTN_RIGHT, INPUT);
  pinMode(BTN_LEFT, INPUT);

  // stepper microstep
  pinMode (MOTOR_MS1, OUTPUT),
  pinMode (MOTOR_MS2, OUTPUT);
  digitalWrite (MOTOR_MS1, LOW); // todo place config in config.h
  digitalWrite (MOTOR_MS2, LOW);

  //endstop
  pinMode (ENDSTOP_LEFT, INPUT),
  pinMode (ENDSTOP_RIGHT, INPUT);
  
  
  // run scheduler
  SoftTimer.add(&schedule);

}

// function :SensorLeft
//
// Description :
// return te logic state of the left sensor
//
// Return :
// true if the left sensor is active. Otherwise false
boolean SensorLeft ()
{
  return (digitalRead (BTN_LEFT)== BTN_LEFT_ACTIVE_STATE ? true : false);
}

// function :SensorRight
//
// Description :
// return te logic state of the right sensor
//
// Return :
// true if the right sensor is active. Otherwise false
boolean SensorRight()
{
  return (digitalRead (BTN_RIGHT) == BTN_RIGHT_ACTIVE_STATE ? true : false);
}

// function :EndStopLeft
//
// Description :
// return the logic state of the left endstop sensor
//
// Return :
// true if the left endstop is active. Otherwise false
boolean EndStopLeft ()
{
  return (digitalRead (ENDSTOP_LEFT) == ENDSTOP_LEFT_STATE ? true : false); 
}

// function :EndStopRight
//
// Description :
// return the logic state of the right endstop sensor
//
// Return :
// true if the right endstop is active. Otherwise false
boolean EndStopRight ()
{
  return (digitalRead (ENDSTOP_RIGHT) == ENDSTOP_RIGHT_STATE ?  true : false); 
}

int RIGHT_MOVE = 1;
int LEFT_MOVE = -1;
int STOP_MOVE = 0;

void turnOn(Task* me)
{

}


// Function: motorControl
//
// Description :
// The function is called every 1 ms. check command sensor and enstop and control the motor
//
// 
void motorControl(Task* me)
{
  // put your main code here, to run repeatedly:

  int step = 0;
  // decide move
  int move = STOP_MOVE;

  boolean right = SensorRight ();
  boolean left = SensorLeft ();
  
  boolean endl = EndStopLeft ();
  boolean endr = EndStopRight ();
 if (endr || endl)
  digitalWrite (LED, HIGH);
  else
  digitalWrite (LED,LOW);
 
 //endr = false;
 //endl=false;
  if (right == left)
  {
    move = STOP_MOVE;
    
    //digitalWrite(LED, LOW);
  }
  else if (right==true)
  {
    if (endr)
    {
      move=STOP_MOVE;
    }
    else
    {
      move = RIGHT_MOVE;
      stepper1.move (1000);
      //digitalWrite(LED, HIGH);
    }
  }
  else if (left == true)
  {
    if (endl)
    {
      move=STOP_MOVE;
    }
    else
    {
      move = LEFT_MOVE;
      stepper1.move(-1000);
      //digitalWrite(LED, HIGH);
    }
  }

  // motor control
  if (move != STOP_MOVE)
  {
    stepper1.run();
  }
  else
  {
    //stepper1.disableOutputs();
    stepper1.setSpeed(0);
    stepper1.setCurrentPosition (0);
  }

}

Fichier de configuration config.h


#define MOTOR_MS1 11 // EASY DRIVER MS1 IO FROM ARDUINO
#define  MOTOR_MS2  10 // Easy Driver MS2 IO From Arduino

#define MOTOR_STEP 9 // EasyDriver STEP IO from Arduino (single step command)
#define MOTOR_DIR 8  // EasyDriver DIR IO from arduino (move direction)

#define LED 13 // Onboard arduino led for signaling

#define BTN_RIGHT 4 // Input for right movement
#define BTN_LEFT 5 // Input for left movement

#define BTN_RIGHT_ACTIVE_STATE LOW // Input state to consider BTN active
#define BTN_LEFT_ACTIVE_STATE LOW // Input state to consider BTN active


#define MAX_SPEED 10000 // max speed in step/s
#define MAX_ACCEL 1000 // max acceleration in step / s / s

#define ENDSTOP_LEFT 7
#define ENDSTOP_RIGHT 6
#define ENDSTOP_LEFT_STATE LOW
#define ENDSTOP_RIGHT_STATE LOW