/*
Copyright 2009, Mike Jacobs
This file is part of Handy Board Interactive C Events (HB-ICE).
HB-ICE is free software: you can redistribute it and/or modify
it under the terms of the Lesser GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
HB-ICE is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
Lesser GNU General Public License for more details.
You should have received a copy of the Lesser GNU General Public License
along with HB-ICE. If not, see .
*/
buttons.ic
#define EVENT_ID_START_BUTTON 0
#define EVENT_ID_STOP_BUTTON 1
#define BUTTON_POLLING_TIME 0.2
#define EVENT_TYPE_BUTTON_RELEASED 0
struct Event buttonEvent_;
struct Event *buttonEvent = &buttonEvent_;
void signalButtonEvent(int id){
buttonEvent->id = id;
signalEvent(buttonEvent);
}
void monitorButtons(){
buttonEvent->type = EVENT_TYPE_BUTTON_RELEASED;
while(TRUE){
if(start_button()){
// button pressed, wait for release
while(start_button()){}
signalButtonEvent(EVENT_ID_START_BUTTON);
}
if(stop_button()){
// button pressed, wait for release
while(stop_button()){}
signalButtonEvent(EVENT_ID_STOP_BUTTON);
}
sleep(BUTTON_POLLING_TIME);
}
}
PROCESS_ID monitoringButtonsProcess = -1;
BOOLEAN monitoringButtons = FALSE;
void startMonitoringButtons(){
if(monitoringButtons == FALSE){
monitoringButtons = TRUE;
monitoringButtonsProcess = start_process(monitorButtons());
}
else {
tone(300.0, 1.5);
}
}
handybug.ic
#use "types.ic"
#use "events.ic"
#use "buttons.ic"
#use "digital.ic"
#use "motors.ic"
void initialize(){
initializeEventQueue();
intializeDigitalEvents();
initializeMotors();
startMonitoringButtons();
}
#define RIGHT_MOTOR 0
#define LEFT_MOTOR 3
#define RIGHT_BUMPER 13
#define LEFT_BUMPER 15
BOOLEAN started = FALSE;
void start(){
if(!started){
started = TRUE;
monitorDigital(RIGHT_BUMPER, TRUE);
monitorDigital(LEFT_BUMPER, TRUE);
startMonitoringDigitalInputs();
printf("running...\n");
moveForward(0.0);
}
}
void handleButtonReleasedEvent(struct Event* event){
int eventId = event->id;
switch(eventId) {
case EVENT_ID_START_BUTTON:
start();
break;
case EVENT_ID_STOP_BUTTON:
stop();
break;
}
}
void moveForward(float duration){
changeMotorSpeed(RIGHT_MOTOR,100);
changeMotorSpeed(LEFT_MOTOR,100);
sleep(duration);
}
void stopMoving(){
stopAllMotors();
}
void moveBackward(float duration){
changeMotorSpeed(RIGHT_MOTOR,-100);
changeMotorSpeed(LEFT_MOTOR,-100);
sleep(duration);
}
void turnRight(float duration){
changeMotorSpeed(RIGHT_MOTOR,-100);
changeMotorSpeed(LEFT_MOTOR,100);
sleep(duration);
}
void turnLeft(float duration){
changeMotorSpeed(RIGHT_MOTOR,100);
changeMotorSpeed(LEFT_MOTOR,-100);
sleep(duration);
}
void handleDigitalChangedEvent(struct Event* event){
int port = event->id;
int value = event->value;
if(value == CLOSED){
stopMoving();
moveBackward(0.5);
stopMoving();
if(port == LEFT_BUMPER){
turnRight(0.2);
}
else {
if(port == RIGHT_BUMPER){
turnLeft(0.2);
}
}
moveForward(0.0);
}
}
void handleEvent(struct Event* event){
int eventType = event->type;
switch(eventType){
case EVENT_TYPE_BUTTON_RELEASED:
handleButtonReleasedEvent(event);
break;
case EVENT_TYPE_DIGITAL_CHANGED:
handleDigitalChangedEvent(event);
break;
}
}
// Main event loop program...
BOOLEAN looping = TRUE;
void stop(){
stopMoving();
stopMonitoringDigitalInputs();
started = FALSE;
looping = FALSE;
}
void main(){
struct Event* event = NULL;
initialize();
printf("press start\n");
while(looping){
event = dequeue(eventQueue);
if(event != NULL){
handleEvent(event);
}
}
printf("done\n");
}
digital.ic
#define NUM_DIGITAL_INPUTS 9
#define FIRST_DIGITAL_INPUT 7
#define OPEN 0
#define CLOSED 1
#define DIGITAL_POLLING_TIME 0.2
#define EVENT_TYPE_DIGITAL_CHANGED 1
// DIGITAL INPUTS (ports 7:15)
struct Event digitalEvent7_ = {EVENT_TYPE_DIGITAL_CHANGED, 7, 0};
struct Event digitalEvent8_ = {EVENT_TYPE_DIGITAL_CHANGED, 8, 0};
struct Event digitalEvent9_ = {EVENT_TYPE_DIGITAL_CHANGED, 9, 0};
struct Event digitalEvent10_ = {EVENT_TYPE_DIGITAL_CHANGED, 10, 0};
struct Event digitalEvent11_ = {EVENT_TYPE_DIGITAL_CHANGED, 11, 0};
struct Event digitalEvent12_ = {EVENT_TYPE_DIGITAL_CHANGED, 12, 0};
struct Event digitalEvent13_ = {EVENT_TYPE_DIGITAL_CHANGED, 13, 0};
struct Event digitalEvent14_ = {EVENT_TYPE_DIGITAL_CHANGED, 14, 0};
struct Event digitalEvent15_ = {EVENT_TYPE_DIGITAL_CHANGED, 15, 0};
struct Event *digitalEvent7 = &digitalEvent7_;
struct Event *digitalEvent8 = &digitalEvent8_;
struct Event *digitalEvent9 = &digitalEvent9_;
struct Event *digitalEvent10 = &digitalEvent10_;
struct Event *digitalEvent11 = &digitalEvent11_;
struct Event *digitalEvent12 = &digitalEvent12_;
struct Event *digitalEvent13 = &digitalEvent13_;
struct Event *digitalEvent14 = &digitalEvent14_;
struct Event *digitalEvent15 = &digitalEvent15_;
struct Event (*digitalEvents)[NUM_DIGITAL_INPUTS];
void intializeDigitalEvents(){
digitalEvents[0] = digitalEvent7;
digitalEvents[1] = digitalEvent8;
digitalEvents[2] = digitalEvent9;
digitalEvents[3] = digitalEvent10;
digitalEvents[4] = digitalEvent11;
digitalEvents[5] = digitalEvent12;
digitalEvents[6] = digitalEvent13;
digitalEvents[7] = digitalEvent14;
digitalEvents[8] = digitalEvent15;
}
void signalDigitalEvent(int index, int value){
struct Event* event = digitalEvents[index];
event->value = value;
signalEvent(event);
}
int getStoredDigitalPortValue(int index){
struct Event* event = digitalEvents[index];
return event->value;
}
BOOLEAN monitoringDigital[] = {FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE};
void monitorDigital(int port, BOOLEAN value){
monitoringDigital[port-FIRST_DIGITAL_INPUT] = value;
}
void monitorDigitalInputs(){
int oldPortValue = 0;
int currentPortValue = 0;
int port;
while(TRUE){
int i;
for(i = 0; i < NUM_DIGITAL_INPUTS; i++){
BOOLEAN monitoring = monitoringDigital[i];
if(monitoring){
port = i + FIRST_DIGITAL_INPUT;
oldPortValue = getStoredDigitalPortValue(i);
currentPortValue = digital(port);
if(oldPortValue != currentPortValue){
signalDigitalEvent(i, currentPortValue);
}
}
}
sleep(DIGITAL_POLLING_TIME);
}
}
PROCESS_ID monitoringDigitalInputsProcess = -1;
void startMonitoringDigitalInputs(){
monitoringDigitalInputsProcess = start_process(monitorDigitalInputs());
}
void stopMonitoringDigitalInputs(){
kill_process(monitoringDigitalInputsProcess);
}
events.ic
#use "types.ic"
// EVENTS and EVENT QUEUE
struct Event {
int type;
int id;
int value;
long timestamp;
};
#define MAX_QUEUE_DEPTH 6
struct EventQueue {
int front;
int rear;
int size;
struct Event (*events)[MAX_QUEUE_DEPTH];
};
struct EventQueue eventQueue_;
struct EventQueue *eventQueue = &eventQueue_;
/*
The event queue is a FIFO queue.
Enqueue requests push elements to the rear of the queue.
Dequeue requests pop elements from the front of the queue.
*/
void initializeEventQueue(){
eventQueue->front = 1;
eventQueue->rear = 0;
eventQueue->size = 0;
}
/*
Increments the rear index with wrap around
and pushes an event to the queue.
*/
BOOLEAN enqueue(struct EventQueue* q, struct Event* event) {
BOOLEAN answer;
int i = 0;
if (q->size == MAX_QUEUE_DEPTH) {
answer = FALSE;
}
else {
i = (q->rear + 1) % MAX_QUEUE_DEPTH;
q->rear = i;
q->events[i] = event;
q->size = q->size + 1;
answer = TRUE;
event->timestamp = mseconds();
}
return answer;
}
/*
Pops an event from the front of the queue
and increments the front index with wrap around.
*/
struct Event* dequeue(struct EventQueue* q){
struct Event* event = NULL;
int i = 0;
int size = q->size;
if(size > 0){
i = q->front;
event = q->events[i];
i++;
i = i % MAX_QUEUE_DEPTH;
q->front = i;
q->size = size - 1;
}
return event;
}
void printQueue(struct EventQueue* q){
int size = q->size;
int front = q->front;
int rear = q->rear;
printf(" size: %d, front: %d, rear: %d \n", size, front, rear);
}
void printEventQueue(){
printQueue(eventQueue);
}
void signalEvent(struct Event* event){
BOOLEAN enqueued;
enqueued = enqueue(eventQueue, event);
}
motors.ic
#define NUMBER_OF_MOTORS 4
int motorSpeeds[NUMBER_OF_MOTORS];
void initializeMotors(){
int i;
for(i=0; i<NUMBER_OF_MOTORS; i++){
motorSpeeds[i] = 0;
}
}
void changeMotorSpeed(int motorID, int speed){
int currentSpeed = motorSpeeds[motorID];
if(currentSpeed != speed){
motorSpeeds[motorID] = speed;
motor(motorID, speed);
}
}
void stopMotor(int motorID){
changeMotorSpeed(motorID, 0);
}
void stopAllMotors(){
ao();
}
types.ic
#define BOOLEAN int
#define PROCESS_ID int
#define TRUE 1
#define FALSE 0
Like this:
Be the first to like this page.