Last active
August 30, 2015 15:14
-
-
Save MatteoRagni/3a7a520597f9b2a6ee78 to your computer and use it in GitHub Desktop.
Arduino per la didattica. Sorgenti corretti.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
void setup() { | |
Serial.begin(115200); | |
} | |
void loop() { | |
if (Serial.available()) { | |
if (Serial.read() == 'a') { | |
Serial.println("Hello, World!") | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "msp430g2553.h" | |
#define TXLED BIT0 | |
#define RXLED BIT6 | |
#define TXD BIT2 | |
#define RXD BIT1 | |
const char string[] = { "Hello World\r\n" }; | |
unsigned int i; //Counter | |
int main(void) | |
{ | |
WDTCTL = WDTPW + WDTHOLD; // Stop WDT | |
DCOCTL = 0; // Select lowest DCOx and MODx settings | |
BCSCTL1 = CALBC1_1MHZ; // Set DCO | |
DCOCTL = CALDCO_1MHZ; | |
P2DIR |= 0xFF; // All P2.x outputs | |
P2OUT &= 0x00; // All P2.x reset | |
P1SEL |= RXD + TXD ; // P1.1 = RXD, P1.2=TXD | |
P1SEL2 |= RXD + TXD ; // P1.1 = RXD, P1.2=TXD | |
P1DIR |= RXLED + TXLED; | |
P1OUT &= 0x00; | |
UCA0CTL1 |= UCSSEL_2; // SMCLK | |
UCA0BR0 = 0x08; // 1MHz 115200 | |
UCA0BR1 = 0x00; // 1MHz 115200 | |
UCA0MCTL = UCBRS2 + UCBRS0; // Modulation UCBRSx = 5 | |
UCA0CTL1 &= ~UCSWRST; // **Initialize USCI state machine** | |
UC0IE |= UCA0RXIE; // Enable USCI_A0 RX interrupt | |
__bis_SR_register(CPUOFF + GIE); // Enter LPM0 w/ int until Byte RXed | |
while (1) | |
{ } | |
} | |
#pragma vector=USCIAB0TX_VECTOR | |
__interrupt void USCI0TX_ISR(void) | |
{ | |
P1OUT |= TXLED; | |
UCA0TXBUF = string[i++]; // TX next character | |
if (i == sizeof string - 1) // TX over? | |
UC0IE &= ~UCA0TXIE; // Disable USCI_A0 TX interrupt | |
P1OUT &= ~TXLED; } | |
#pragma vector=USCIAB0RX_VECTOR | |
__interrupt void USCI0RX_ISR(void) | |
{ | |
P1OUT |= RXLED; | |
if (UCA0RXBUF == 'a') // 'a' received? | |
{ | |
i = 0; | |
UC0IE |= UCA0TXIE; // Enable USCI_A0 TX interrupt | |
UCA0TXBUF = string[i++]; | |
} | |
P1OUT &= ~RXLED; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <Servo.h> | |
Servo servo; | |
#define SERVO_MIN 5 | |
#define SERVO_MAX 175 | |
#define STEP_SIZE 1 | |
// Definizione della interfaccia: | |
#define SERIAL_LASER_ON 'l' | |
#define SERIAL_LIGHTS_ON 'd' | |
#define SERIAL_NEXT_STEP 'n' | |
#define SERIAL_PREV_STEP 'p' | |
#define SERIAL_GO_HOME 'h' | |
#define SERIAL_GO_TO 'g' | |
#define SERIAL_QUERY '?' | |
#define SERIAL_WAIT 'w' | |
#define PRINT_PROMPT() Serial.print('>'); | |
#define SERVO_PIN 9 | |
#define LIGHTS_PIN 3 | |
#define LASER_PIN 5 | |
enum StateID { | |
WAIT, | |
LASER, | |
LIGHTS, | |
SERVO | |
}; | |
struct State { | |
StateID id; | |
StateID transition; | |
int x_position; | |
int u_position; | |
bool laser; | |
bool lights; | |
}; | |
struct State state; | |
// Tools //////////////////////////////////////////////////// | |
/* SERVO */ | |
void servo_exec() { | |
if (state.id == SERVO) { | |
if (state.x_position != state.u_position) { | |
int dir = (state.x_position < state.u_position ? 1 : -1); | |
state.x_position += dir; | |
if (state.x_position >= SERVO_MIN && state.x_position <= SERVO_MAX) { | |
servo.write(state.x_position); | |
} else { | |
state.transition = WAIT; | |
} | |
} else { | |
state.transition = WAIT; | |
} | |
} | |
} | |
void servo_go_to(int new_pos) { | |
if (new_pos >= SERVO_MIN && new_pos <= SERVO_MAX) { | |
state.u_position = new_pos; | |
state.transition = SERVO; | |
} | |
} | |
void servo_go_next() { | |
servo_go_to(state.x_position + STEP_SIZE); | |
} | |
void servo_go_prev() { | |
servo_go_to(state.x_position - STEP_SIZE); | |
} | |
void servo_go_home() { | |
servo_go_to(SERVO_MIN); | |
} | |
void servo_sync() { | |
state.u_position = state.x_position; | |
} | |
/* LASER */ | |
void laser_switch() { | |
state.laser = (state.laser ? false : true); | |
digitalWrite(LASER_PIN, (state.laser ? HIGH : LOW)); | |
} | |
void laser_on() { | |
if(!state.laser) | |
laser_switch(); | |
} | |
void laser_off() { | |
if(state.laser) | |
laser_switch(); | |
} | |
/* LIGHTS */ | |
void lights_switch() { | |
state.lights = (state.lights ? false : true); | |
analogWrite(LIGHTS_PIN, (state.lights ? 255 : 0)); | |
} | |
void lights_on() { | |
if(!state.lights) | |
lights_switch(); | |
} | |
void lights_off() { | |
if(state.lights) | |
lights_switch(); | |
} | |
// State Machine Handling ////////////////////////////////////////// | |
void state_on_enter() { | |
if (state.id != state.transition) { | |
switch(state.transition) { | |
case WAIT: | |
// void | |
break; | |
case LASER: | |
laser_on(); | |
break; | |
case LIGHTS: | |
lights_on(); | |
break; | |
case SERVO: | |
// void | |
break; | |
default: | |
break; | |
} | |
state.id = state.transition; | |
} | |
} | |
void state_on_exec() { | |
switch(state.id) { | |
case WAIT: | |
// void | |
break; | |
case LASER: | |
// void | |
break; | |
case LIGHTS: | |
// void | |
break; | |
case SERVO: | |
servo_exec(); | |
break; | |
default: | |
break; | |
} | |
} | |
void state_on_exit() { | |
if (state.id != state.transition) { | |
switch(state.id) { | |
case WAIT: | |
// void | |
break; | |
case LASER: | |
laser_off(); | |
break; | |
case LIGHTS: | |
lights_off(); | |
break; | |
case SERVO: | |
servo_sync(); | |
break; | |
default: | |
break; | |
} | |
} | |
} | |
// Setup /////////////////////////////////////////////////////////// | |
void setup() { | |
// Initializzare lo stato in modo consistente | |
// Laser | |
pinMode(LASER_PIN, OUTPUT); | |
laser_off(); | |
delay(10); | |
// Luci | |
lights_off(); | |
delay(10); | |
// Servo | |
servo.attach(SERVO_PIN); | |
servo.write(SERVO_MIN); | |
delay(250); | |
state.id = WAIT; | |
state.transition = WAIT; | |
state.x_position = SERVO_MIN; | |
state.u_position = SERVO_MIN; | |
Serial.begin(115200); | |
} | |
// Main Loop /////////////////////////////////////////////////////////// | |
int buff = 0; | |
void loop() { | |
if(Serial.available()) { | |
char ch = Serial.read(); | |
switch(ch) { | |
case '0'...'9': | |
buff = buff * 10 + (ch - '0'); | |
break; | |
case SERIAL_LASER_ON: | |
buff = 0; | |
state.transition = LASER; | |
break; | |
case SERIAL_LIGHTS_ON: | |
buff = 0; | |
state.transition = LIGHTS; | |
break; | |
case SERIAL_NEXT_STEP: | |
buff = 0; | |
servo_go_next(); | |
break; | |
case SERIAL_PREV_STEP: | |
buff = 0; | |
servo_go_prev(); | |
break; | |
case SERIAL_GO_HOME: | |
buff = 0; | |
servo_go_home(); | |
break; | |
case SERIAL_GO_TO: | |
servo_go_to(buff); | |
buff = 0; | |
break; | |
case SERIAL_QUERY: | |
buff = 0; | |
Serial.print(state.x_position); | |
break; | |
case SERIAL_WAIT: | |
buff = 0; | |
state.transition = WAIT; | |
break; | |
default: | |
buff = 0; | |
break; | |
} | |
PRINT_PROMPT(); | |
} | |
state_on_exit(); | |
state_on_enter(); | |
state_on_exec(); | |
delay(5); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* La didattica con Arduino | |
* Matteo Ragni | |
* Universita' degli Studi di Trento | |
* | |
* Obbiettivi: | |
* Costruire una piccola macchina a stati. La macchina comanda un fading led e un puntatore | |
* laser. Il laser non deve essere mai acceso quando il led e' acceso. Il fader deve sempre | |
* ripartire da zero quando richiamato. | |
* | |
* | |
* +----------------+ | |
* | Àrduino | | |
* | UNO | +---------------+ | |
* | Pin 5 --------------+ LASER +-----+ | |
* | | +---------------+ | | |
* | | | | |
* | Pin 3 (~) -----+ | | |
* | | | +--------+ +---------+ | | |
* | | +---+ 220omh +--+ LED +----+ | |
* | | | +--------+ +---------+ | | |
* | | | +--------+ +---------+ | | |
* | | +---- 220omh +--+ LED +----+ | |
* | | | +--------+ +---------+ | | |
* | GND | | +--------+ +---------+ | | |
* +------|---------+ +---+ 220omh +--+ LED +----+ | |
* | +--------+ +---------+ | | |
* | | | |
* | | | |
* +---------------------------------------------+ | |
*/ | |
/* Struttura della macchina a stati | |
* +---------------+ Serial 'n' | |
* | |<----------------+---------------------------------------+ | |
* | Stato NULLO | Serial 'd' | | | |
* | 0|--+-----------+ | | | |
* +---------------+ | | | | | |
* | | V | | | |
* Serial | | +---------------+ | | |
* 'l' | | | | | | |
* | | +-| Init LED PWM | | | |
* V | | | 2| | | |
* +---------------+ | | +---------------+ | | |
* | |--+ | | end init | | |
* +-| Exec LASER | | | | | |
* | | 1|<------+ | +-------------------------+-----------+ | |
* | +---------------+ Serial V | | | | |
* | ^ 'l' +---------------+ pwm = 255 +---------------+ | | |
* | | | Exec LED PWM |---------->| Exec LED PWM | | | |
* | | | pwm_dir = 1 | | pwm_dir = -1 | | | |
* | | | 3|<----------| 4| | | |
* | | +---------------+ pwm = 0 +---------------+ | | |
* | | Serial 'l' | | | | |
* | +-------------------------+---------------------------+ | | |
* +---------------------------------------------------------------------------+ | |
*/ | |
// Struttura che contiene tutte le informazioni riguardanti lo | |
// stato del nostro automa | |
struct State { | |
// Id dello stato corrente della macchina | |
int id; | |
// Id dello stato nel quale si deve effettuare la transizione | |
int transition; | |
// Stato della componente A | |
int pwm_value; | |
int pwm_direction; | |
// Stato della componente B | |
int laser; | |
}; | |
struct State state; | |
#define A_PIN 3 | |
#define B_PIN 5 | |
void setup() { | |
Serial.begin(115200); | |
pinMode(B_PIN,OUTPUT); | |
// Inizializzazione dello stato della macchina | |
// attenzione: deve essere consistente... | |
state.id = 0; | |
state.pwm_value = 0; | |
state.pwm_direction = 0; | |
state.laser = LOW; | |
analogWrite(A_PIN, 0); | |
} | |
///////////////////////////////////////////////////////////////////////////////////// | |
// Funzioni Led | |
void led_init() { | |
state.pwm_value = 0; | |
state.pwm_direction = 1; | |
analogWrite(A_PIN, state.pwm_value); | |
state.transition = 3; | |
} | |
void led_fadein_in() { | |
state.pwm_direction = 1; | |
} | |
void led_fadein_loop() { | |
state.pwm_value += (5 * state.pwm_direction); | |
if (state.pwm_value > 255) { | |
state.transition = 4; | |
} else { | |
analogWrite(A_PIN, state.pwm_value); | |
} | |
} | |
void led_fadein_exit() { | |
if (state.transition != 4) | |
analogWrite(A_PIN, 0); | |
} | |
void led_fadeout_in() { | |
state.pwm_direction = -1; | |
} | |
void led_fadeout_loop() { | |
state.pwm_value += (5 * state.pwm_direction); | |
if (state.pwm_value < 0) { | |
state.transition = 3; | |
} else { | |
analogWrite(A_PIN, state.pwm_value); | |
} | |
} | |
void led_fadeout_exit() { | |
if (state.transition != 3) | |
analogWrite(A_PIN, 0); | |
} | |
// Funzioni Laser | |
void laser_off() { | |
state.laser = LOW; | |
digitalWrite(B_PIN, state.laser); | |
} | |
void laser_on() { | |
state.laser = HIGH; | |
digitalWrite(B_PIN, state.laser); | |
} | |
////////////////////////////////////////////////////////////////////////////////////// | |
// Macchina a stati: esecuzione in ingresso in uno stato | |
void state_on_enter() { | |
if(state.transition != state.id) { | |
switch(state.transition) { | |
case 1: | |
laser_on(); | |
break; | |
case 3: | |
led_fadein_in(); | |
break; | |
case 4: | |
led_fadeout_in(); | |
break; | |
case 0: | |
case 2: | |
default: | |
break; | |
} | |
#ifdef DEBUG | |
Serial.print("Switch from: "); | |
Serial.print(state.id); | |
Serial.print(" to:"); | |
Serial.println(state.transition); | |
delay(10); | |
#endif | |
state.id = state.transition; | |
} | |
} | |
// Macchina a stati: esecuzione nello stato | |
void state_on_exec() { | |
switch(state.id) { | |
case 2: | |
led_init(); | |
break; | |
case 3: | |
led_fadein_loop(); | |
break; | |
case 4: | |
led_fadeout_loop(); | |
break; | |
case 0: | |
case 1: | |
default: | |
// nulla da fare qui | |
break; | |
} | |
} | |
// Macchina a stati: Esecuzione in uscita da uno stato | |
void state_on_exit() { | |
if(state.transition != state.id) { | |
switch(state.id) { | |
case 1: | |
laser_off(); | |
break; | |
case 3: | |
led_fadein_exit(); | |
break; | |
case 4: | |
led_fadeout_exit(); | |
break; | |
case 0: | |
case 2: | |
default: | |
// nulla di particolare | |
break; | |
} | |
} | |
} | |
void loop() { | |
if (Serial.available()) { | |
char ch = Serial.read(); | |
switch(ch) { | |
case 'l': | |
state.transition = 1; | |
break; | |
case 'd': | |
state.transition = 2; | |
break; | |
case 'n': | |
state.transition = 0; | |
break; | |
case '?': | |
Serial.print(state.id); | |
Serial.print('\t'); | |
Serial.print(state.pwm_value); | |
Serial.print('\t'); | |
Serial.print(state.pwm_direction); | |
Serial.print('\t'); | |
Serial.print(state.laser); | |
Serial.print('\n'); | |
break; | |
default: | |
break; | |
} | |
} | |
state_on_exit(); | |
state_on_enter(); | |
state_on_exec(); | |
delay(20); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* La didattica con Arduino | |
* Matteo Ragni | |
* Universita' degli Studi di Trento | |
* | |
* Obbiettivi: | |
* Comandare un servo utilizzando Arduino. Il modulo deve essere in grado | |
* di ricvevere un angolo in input via seriale (lightweight arduino parser) | |
* effettuare lo spostamento aventi o indietro di uno step, ritornare a casa | |
* etc. | |
* Il progetto pone le basi su come costruire in modo efficiente una interfaccia | |
* macchina macchina via seriale. | |
* | |
* +--------------+ | |
* | Arduino | | |
* | UNO | +--------+ | |
* | | +--------+ | |
* | | +--------++ | |
* | | | || | |
* | Pin 9 (~PWM) +--------------+ Giallo || | |
* | 5V +--------------+ Rosso || | |
* | GND +--------------+ Nero || | |
* | | +--------++ | |
* | | ServoMotore | |
* +--------------+ | |
*/ | |
#include <Servo.h> | |
Servo servo; | |
// Riduciamo il campo di spostamento de 5 a 175 gradi per | |
// non stallare il motore. Il problema di stallaggio deriva dalla | |
// non ottima costruzione del servo | |
#define START_ANGLE 5 | |
#define STOP_ANGLE 180 | |
// Scriviamo una piccola funzione che stampa in seriale il valore attuale di | |
// angolo a cui ci troviamo. | |
#define REPORT_ANGLE() Serial.print(pos); | |
// Il prompt e' un carattere che ci permette di capire dal | |
// computer che il nostro spostamento e' terminato. | |
#define RETURN_PROMPT() Serial.print('|'); | |
// Le tre variabili globali utilizzate nello sketch. pos trattiene lo stato attuale | |
// del servo (ovvero la sua posizione | |
int pos = START_ANGLE; | |
int buff = 0; | |
//////////////////////////////////////////////////////////////////////// | |
void move_servo_at(int buff) { | |
if (buff >= START_ANGLE && buff <= STOP_ANGLE) { | |
pos = buff; | |
} else { | |
pos = (buff < START_ANGLE ? pos = START_ANGLE : pos = STOP_ANGLE); | |
} | |
REPORT_ANGLE(); | |
servo.write(pos); | |
} | |
void move_servo_next() { | |
if (pos < STOP_ANGLE) { | |
pos += 1; | |
REPORT_ANGLE(); | |
servo.write(pos); | |
} | |
} | |
void move_servo_previous() { | |
if (pos > START_ANGLE) { | |
pos -= 1; | |
REPORT_ANGLE(); | |
servo.write(pos); | |
} | |
} | |
void move_servo_at_home() { | |
pos = START_ANGLE; | |
REPORT_ANGLE(); | |
servo.write(pos); | |
} | |
//////////////////////////////////////////////////////////////////////// | |
void setup() | |
{ | |
servo.attach(9); | |
servo.write(pos); | |
Serial.begin(115200); | |
} | |
//////////////////////////////////////////////////////////////////////// | |
void loop() | |
{ | |
char ch; | |
if (Serial.available()) { | |
ch = Serial.read(); | |
switch(ch) { | |
case '0'...'9': | |
buff = buff * 10 + (ch - '0'); | |
break; | |
case 'g': | |
move_servo_at(buff); | |
buff = 0; | |
RETURN_PROMPT(); | |
break; | |
case 'h': | |
move_servo_at_home(); | |
buff = 0; | |
RETURN_PROMPT(); | |
break; | |
case 'n': | |
buff = 0; | |
move_servo_next(); | |
RETURN_PROMPT(); | |
break; | |
case 'p': | |
buff = 0; | |
move_servo_previous(); | |
RETURN_PROMPT(); | |
break; | |
default: | |
buff = 0; | |
RETURN_PROMPT(); | |
break; | |
} | |
} | |
delay(20); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment