cami01FoxySetaalice12
Published © MIT

Bosco Test

Bosco tests are designed to assess the morphofunctional characteristics of one's legs muscles as well as their neuromuscular skills.

BeginnerShowcase (no instructions)6,197
Bosco Test

Things used in this project

Hardware components

Arduino Mega 2560
Arduino Mega 2560
Actually, pretty much any Arduino board would do just fine.
×1
Breadboard (generic)
Breadboard (generic)
×2
Jumper wires (generic)
Jumper wires (generic)
Please consider the quantity indicated above a generic rule of thumb.
×30
ICStation KY-008 Laser Transmitter Module
×1
Photo resistor
Photo resistor
×1
Resistor 10k ohm
Resistor 10k ohm
×1
HC-05 Bluetooth Module
HC-05 Bluetooth Module
×1
Android device
Android device
×1

Software apps and online services

Arduino IDE
Arduino IDE
MIT App Inventor 2
MIT App Inventor 2

Story

Read more

Schematics

Fritzing project

This Fritzing file includes both the project's breaboard view and schematic view. It does not include any code.

Code

test_di_bosco.ino

Arduino
A source file containing our sketch's opening comment.
/*
	Program: test di bosco
	Date: 16/09/2019
	Author: Volpe Stefano | V Bsa | L.S. "A. Oriani" Ravenna
	
	Currently, everything is coded "in Italian" (WIP?)
*/

0_apparecchiatura_h.ino

Arduino
This file defines the interface used by the laser barrier module.
// 0_apparecchiatura_h: intestazione del modulo per la gestione della barriera laser

#ifndef APPARECCHIATURA_H
#define APPARECCHIATURA_H

namespace Apparecchiatura {

	// una barriera dovrebbe avere l'esclusiva sull'accesso ai propri pin
	class Barriera {
	public:
		// inizializzazione obbligatoria
		Barriera(int pin_laser_a, int pin_laser_b, int pin_foto_a, int pin_foto_b); // [a, b[
		Barriera() = delete;
		// spostamento consentito
		Barriera(Barriera&&) = default;
		Barriera& operator=(Barriera&&) = default;
		// copia vietata: un pin dovrebbe appartenere a una sola barriera
		Barriera(const Barriera&) = default;
		Barriera& operator=(const Barriera&) = delete;
		// la barriera viene spenta alla distruzione
		~Barriera();

		// costanti e getter
		static constexpr int tolleranza { 100 }; // fra lettura luce naturale e lettura a barriera accesa con ostacolo
		int pin_laser_a() const;
		int pin_laser_b() const;
		int pin_foto_a() const;
		int pin_foto_b() const;
		bool stato() const; // true = accesa, false = spenta

		// false: la barriera era gi nello stato desiderato
		bool accendi();
		bool spegni();
		bool ostacolo() const; // false se non ci sono ostacoli o a barriera spenta

	private:
		int pin_l_a, pin_l_b, pin_f_a, pin_f_b; // primi e ultimi pin per laser e fotoresistenze
		bool st; // true = accesa, false = spenta
		int luce_naturale { 0 };
		
		void imposta_laser(int valore); // HIGH o LOW
		int leggi_fotoresistenze() const; // media delle analogRead()
	};
	
}

#endif

1_connessione_h.ino

Arduino
This file defines the interface used by the connection module.
// 1_connessione_h: intestazione del modulo di connessione bluetooth al terminale

#ifndef CONNESSIONE_H
#define CONNESSIONE_H

#include <SoftwareSerial.h>

namespace Connessione {

	class Terminale {
	public:
		// inizializzazione obbligatoria
		Terminale(Apparecchiatura::Barriera& barriera, int pin_tra, int pin_ric,
				  long baud = baud_def, HardwareSerial& debug = Serial, long baud_debug = baud_debug_def);
		Terminale(Apparecchiatura::Barriera& barriera, int pin_tra, int pin_ric,
				  HardwareSerial& debug, long baud_debug = baud_debug_def);
		Terminale() = delete;
		// spostamento consentito
		Terminale(Terminale&&) = default;
		Terminale& operator=(Terminale&&) = default;
		// copia vietata: un pin dovrebbe appartenere a un solo terminale
		Terminale(const Terminale&) = default;
		Terminale& operator=(const Terminale&) = delete;
		// distruttore predefinito
		~Terminale() = default;

		// costanti
		static constexpr long baud_def { 9600 }, baud_debug_def { 9600 };
		static constexpr char comando_stato { '0' }, // chiede se la barriera sia accesa
							  comando_spegni { '1' }, // spegne la barriera
							  comando_accendi { '2' }, // accende la barriera
							  comando_chiedi { '3' }, // chiede una prova di N salti
							  comando_abortisci { '4' }; // annulla la richiesta
		static constexpr int salti_richiesti_default { 1 };
		static constexpr size_t salti_richiesti_string_dim { 10 };

		// getter
		Apparecchiatura::Barriera& barriera() const;
		int pin_tra() const;
		int pin_ric() const;
		long baud() const;
		HardwareSerial& debug() const;
		long baud_debug() const;

		void setup();
		void loop();

	private:
		Apparecchiatura::Barriera& bar; // la barriera controllata dal terminale
		int pin_tx, pin_rx; // pin del flusso di comunicazione col terminale
		SoftwareSerial m; // modulo per la comunicazione col terminale
		long b; // velocit di trasmissione (in baud) col terminale
		HardwareSerial& d; // pin del flusso di comunicazione per debug
		long b_d; // velocit di trasmissione (in baud) per debug 

		void azione_stato();
		void azione_spegni();
		void azione_accendi();
		void azione_chiedi();
		bool azione_aborto();
		void azione_sconosciuta(char input);

		int calcola_salti_richiesti();
	};
	
}

#endif

2_main_cpp.ino

Arduino
// 2_main_cpp: il punto di ingresso del programma (contiene setup() e void())

namespace {
	constexpr int pin_laser_inizio { 2 },
				  pin_laser_fine { 3 },
				  pin_fotoresistenza_inizio { 0 },
				  pin_fotoresistenza_fine { 1 },
				  pin_bluetooth_trasmettitore { 10 },
				  pin_bluetooth_ricevitore { 11 };
	
	Apparecchiatura::Barriera pedana(pin_laser_inizio, pin_laser_fine, pin_fotoresistenza_inizio, pin_fotoresistenza_fine);
	Connessione::Terminale operatore(pedana, pin_bluetooth_trasmettitore, pin_bluetooth_ricevitore); 
}

void setup() {
	operatore.setup();
}

void loop() {
  operatore.loop();
}

3_apparecchiatura_cpp.ino

Arduino
This file implements the management of the laser barrier module.
// 3_apparecchiatura_cpp: implementazione del modulo per la gestione della barriera laser

namespace Apparecchiatura {
	
	Barriera::Barriera(int pin_laser_a, int pin_laser_b, int pin_foto_a, int pin_foto_b)
		:pin_l_a{pin_laser_a}, pin_f_a{pin_foto_a} {
		// eventuale correzione dell'input
		pin_l_b = pin_laser_b <= pin_laser_a ? pin_l_a + 1 : pin_laser_b;
		pin_f_b = pin_foto_b <= pin_foto_a ? pin_f_a + 1: pin_foto_b;
		// configurazione pin
		for (int i { pin_l_a }; i < pin_l_b; ++i)
			pinMode(i, OUTPUT);
		// spengimento eventuali laser rimasti accesi da precedente utilizzo
		imposta_laser(LOW);
	}

	Barriera::~Barriera() {
		spegni();
	}

	int Barriera::pin_laser_a() const {
		return pin_l_a;
	}

	int Barriera::pin_laser_b() const {
		return pin_l_b;
	}

	int Barriera::pin_foto_a() const {
		return pin_f_a;
	}

	int Barriera::pin_foto_b() const {
		return pin_f_b;
	}
	
	bool Barriera::stato() const {
		return st;
	}

	bool Barriera::accendi() {
		if (st) // barriera gi accesa
			return false;
		luce_naturale = leggi_fotoresistenze();
		imposta_laser(HIGH);
		st = true;
		return true;
	}

	bool Barriera::spegni() {
		if (!(st && luce_naturale)) // barriera gi spenta, barriera accesa non correttamente
			return false;
		imposta_laser(LOW);
		st = false;
		return true;
	}

	bool Barriera::ostacolo() const {
		if (!st) // barriera spenta
			return false;
		for (int i { pin_f_a }; i < pin_f_b; ++i)
			if (analogRead(i) <= luce_naturale + tolleranza)
				return true;
		return false;
	}
	
	void Barriera::imposta_laser(int valore) {
		for (int i { pin_l_a }; i < pin_l_b; ++i)
			digitalWrite(i, valore);
	}

	int Barriera::leggi_fotoresistenze() const {
		int somma { 0 };
		for (int i { pin_f_a }; i < pin_f_b; ++i)
			somma += analogRead(i);
		return somma / (pin_f_b - pin_f_a);
	}
}

4_connessione_cpp.ino

Arduino
This file implements the bluetooth connection module into the terminal.
// 4_connessione_cpp: implementazione del modulo di connessione bluetooth al terminale

namespace Connessione {
	
	Terminale::Terminale(Apparecchiatura::Barriera& barriera, int pin_tra, int pin_ric,
						 long baud, HardwareSerial& debug, long baud_debug)
		:bar{barriera},
		pin_tx{pin_tra},
		pin_rx{pin_ric},
		m{SoftwareSerial(pin_tx, pin_rx)},
		b{baud}, d{debug},
		b_d{baud_debug} {
		// preparazione modulo di connessione
		m.begin(b);
	}

	Terminale::Terminale(Apparecchiatura::Barriera& barriera, int pin_tra, int pin_ric,
						 HardwareSerial& debug, long baud_debug)
		:Terminale{barriera, pin_tra, pin_ric, baud_def, debug, baud_debug} { }

	Apparecchiatura::Barriera& Terminale::barriera() const {
		return bar;
	}

	int Terminale::pin_tra() const {
		return pin_tx;
	}

	int Terminale::pin_ric() const {
		return pin_rx;
	}

	long Terminale::baud() const {
		return b;
	}

	HardwareSerial& Terminale::debug() const {
		return d;
	}

	long Terminale::baud_debug() const {
		return b_d;
	}

	void Terminale::setup() {
		d.begin(b_d);
		d.println("Modulo di connessione al terminale in funzione.");
	}
	
	void Terminale::loop() {
		if (m.available()) {
			char input { m.read() };
			switch (input) {
			case comando_stato:
				azione_stato();
				break;
			case comando_spegni:
				azione_spegni();
				break;
			case comando_accendi:
				azione_accendi();
				break;
			case comando_chiedi:
				azione_chiedi();
				break;
			case comando_abortisci:
				d.println("Aborto fallito (nessuna richiesta da abortire.");
				break;
			default:
				azione_sconosciuta(input);
			}
		}
	}
	
	void Terminale::azione_stato() {
		m.println(bar.stato());
		d.println("Stato della barriera comunicato.");
	}
	
	void Terminale::azione_spegni() {
		if (bar.spegni())
			d.println("Barriera spenta.");
		else
			d.println("Barriera spenta da prima.");
	}
	
	void Terminale::azione_accendi() {
		if (bar.accendi())
			d.println("Barriera accesa.");
		else
			d.println("Barriera accesa da prima.");		
	}

	void Terminale::azione_chiedi() {
		if (!bar.ostacolo()) {
			m.println(false);
			m.readString(); // ignoro il resto dell'input
			d.println("Atleta non rilevato sulla pedana.");
			return;
		}
		const int salti_richiesti = calcola_salti_richiesti();
		d.print("Salti richiesti: ");
		d.print(salti_richiesti);
		d.println(".");
		for (int i { 0 }; i < salti_richiesti; ++i) {
			while (bar.ostacolo()) // prima dello stacco
				if (azione_aborto())
					return;
			const unsigned long millis_stacco { millis() };
			while (!bar.ostacolo()) // fase di volo
				if (azione_aborto())
					return;
			m.println(millis() - millis_stacco);
			d.print("Salto #");
			d.print(i + 1);
			d.println(" acquisito.");
		}
	}

	bool Terminale::azione_aborto() {
		if (m.available() && m.read() == comando_abortisci) {
			d.println("Prova abortita.");
			return true;
		}
		return false;
	}
	
	void Terminale::azione_sconosciuta(char input) {
		d.print("Comando '");
		d.print(input);
		d.println("' non riconosciuto.");
	}

	int Terminale::calcola_salti_richiesti() {
		if (!m.available())
			return salti_richiesti_default;
		char salti_richiesti[salti_richiesti_string_dim];
		m.readString().toCharArray(salti_richiesti, salti_richiesti_string_dim);
		return atoi(salti_richiesti);
	}
	
}

Credits

cami01

cami01

1 project • 1 follower
FoxySeta

FoxySeta

1 project • 1 follower
alice12

alice12

1 project • 1 follower

Comments