Included in this version:
MicroScout Program 4 Protocol works!
MicroScout Switches works!
Problems:
It does work, but after a while the switches stop responding. So the switches need to be turned off, and then back on. (Why? Have to figure that one out...)
The code:
/*
Lego Connector Version 4
by Donald Hosford (Donzerme@Yahoo.com)
Last Update: 09/18/2018
Purpose:
-- Use an Arduino Uno to enable old Lego Computer Bricks to be
controlled by any bluetooth enabled smart phone/tablet/PC etc.
-- Working on: VLL protocol
----------------------------
Physical Pin assignments:
pin 0 - BT transmit
pin 1 - BT receive
pin 2 - IR receiver unit
pin 3 - IR transmit led
pin 4 - MicroScout 1 led
pin 5 - MicroScout 2 led
pin 6 - MicroScout 3 led
pin 7 - MicroScout 1 touch switch
pin 8 - MicroScout 2 touch switch
pin 9 - MicroScout 3 touch switch
pin 10 - BT connect led?
----------------------------
Commands:
All commands are simple text characters. Every command will start
with a two letter device code (upper case for now). Below is a
list of Lego P-brick devices I intend to support.
----------------------------
Command format: (Device)(unit id)(action)
Devices: (So far -- this may change.)
BM - Bionicle Manas
MS - MicroScout (Program 4)
PF - Power Functions
RC - RCX
SB - Spybot
SC - Scout
VL - MicroScout VLL
----------------------------
Microscout:
Device: MS
Unit ID:
0 - All units
1 - First unit
2 - Second unit
3 - Third unit
Action:
0 - Stop motor
1 - Forward rotation
2 - Backwards rotation
Switch Watcher
MSS0 - Turn Switch watcher off.
MSS1 - Turn Switch watcher on.
Example: MS11 - MicroScout unit 1, Motor forwards.
MS02 - All MicroScouts, motor backwards.
----------------------------
VLL:
Device: VL
Unit ID:
0 - All units
1 - First unit
2 - Second unit
3 - Third unit
Action:
code 0 to 127
I - Initialize microscout for vll?
Examples:
VL1100 - Send VLL code 100 to Microscout port 1,
VL1I - Initialize microscout port 1 for vll?
Note: call VLLInit() first? Then send VLL commands.
----------------------------
*/
// Code Start:
// init variables
String message = "";
// initialize MicroScout variables
int MSNum = 0;
int Action = 0;
//Array hold MicroScout data
int MSD[] = {
0, 1, 1, 1
};
//Pin array to hold the assignments
int pin[] = {
0, 4, 5, 6, 7, 8, 9, 3, 2, 0, 1
};
/*
Pin[] array positions
0 = space holder, not a pin number
1 = MS1 Led
2 = MS2 Led
3 = MS3 Led
4 = MS1 sw
5 = MS2 sw
6 = MS3 sw
7 = IR transmitter led
8 = IR receiver unit
9 = BT transmitter
10 = BT receiver
*/
// MS Switch Last Total
int LTot = 1000;
// Switch Debounce
// SwitchDebounce time in ms for microscout switches.
int SwitchDebounce = 100;
// Last Time Switches Checked
int LSC = millis();
// Current Time Checked
int CC = LSC;
// MS Switch Status
int MS1St = 0;
int MS2St = 0;
int MS3St = 0;
// MS Switch pins
int SW1=7;
int SW2=8;
int SW3=9;
// Switchtoggle 0=switch check off, 1=switch check on
int Switchtoggle = 1;
// Switchtoggle 0=switch check off, 1=switch check on
// Switchtoggle 0=switch check off, 1=switch check on
//VLL variables
int N = 0;
int N2 = 0;
int command = 0;
// Infared variables
// None yet...
void setup() {
LSC = CC;
//pinmodes
pinMode(pin[1], OUTPUT); // MS1 led
pinMode(pin[2], OUTPUT); // MS2 led
pinMode(pin[3], OUTPUT); // MS3 led
pinMode(SW1, INPUT_PULLUP); // MS1 switch
pinMode(SW2, INPUT_PULLUP); // MS2 switch
pinMode(SW3, INPUT_PULLUP); // MS3 switch
pinMode(pin[7], OUTPUT); // IR send
pinMode(pin[8], INPUT); // IR receive
pinMode(pin[9], OUTPUT); // BT send
pinMode(pin[10], INPUT); // BT receive
pinMode(pin[11], OUTPUT); // BT connect led
//serial setup/output ready
Serial.begin(9600);
delay(5000); // give user time to open serial monitor.
Serial.println("Ready"); //tell user its ready for commands
}
// ----------------------------
void loop() {
message = "";
// listen for message
// receive messages from the serial monitor/BT HC-05 module
while (Serial.available() == 0) {
// loop until something is recieved from serial.
// If Switchtoggle is on, then check status of switches.
// report any changes from last check.
if (Switchtoggle == 1) {
MSSwitches();
}
// this code is remarked out, because it doesn't exist yet...
// If IRToggle is on, then check status of IR reciever.
//if (IRToggle == 1) {
// IRWatcher();
//}
}
message = Serial.readString();
Serial.print ("you typed: ");
Serial.println(message);
// process message
if (message > "") {
protocol();
}
// end of voidloop
}
// ----------------------------
void protocol() {
// if message starts with a two letter code then 'gosub'
// to appropriate 'subroutine'
if (message.startsWith("MS")) {
MicroScout();
}
if (message.startsWith("VL")) {
VLL();
}
if (message.startsWith("RC")) {
RCX();
}
if (message.startsWith("BM")) {
Manas();
}
if (message.startsWith("SB")) {
Spybot();
}
if (message.startsWith("SC")) {
Scout();
}
if (message.startsWith("PF")) {
PowerFunctions();
}
}
// ----------------------------
void VLL() {
// The main entry for MicroScout/Code Pilot VLL protocol.
// Init variables
String c = "";
int CS = 0;
int n = 0;
// get message length
int mlen = message.length();
// retrieve MS number, and convert to number
MSNum = message.charAt(2);
MSNum = MSNum - 48;
// retrieve action
c = message.substring(3);
Action = c.toInt();
Serial.print (Action);
//Serial.println(MSNum);
//Serial.println(Action);
// check for init action.
if (Action == 73) {
// Initalize VLL.
VLLInit();
// Done, clear message.
message = "";
Action = -1;
}
else {
VLLSend();
}
}
void VLLSend() {
//retreive action, send it
// This VLL code has been adapted from a python3 program by:
// https://github.com/JorgePe/mindstorms-vll/blob/master/vll-atat.py
//Serial.println("Start");
// Init variables
int CS = 0;
int n = 0;
int v = 0;
// Delay long: 40ms
int DLo = 38;
// Delay short: 20ms
int DSh = 19;
Action = message.toInt();
// vll send number
//void VLLsend()
//VLLstart
// led off, delay 20ms
digitalWrite(pin[MSNum], LOW);
delay(20);
// checksum calculation
// checksum formulas:
// C or Perl: 7-((n+(n>2)+(n>>4))&7)
// Basic: 7-(n+int(n/4)+int(n/16)) mod 8
// Arduino Scratch: 7-(n+int(n/4)+int(n/16)) % 8
// Arduino uno scratch MOD command: z = x % y
n = Action;
//Serial.println("---");
//Serial.print(n);
//Serial.print("/");
// checksum calculation -- seems to be correct
CS = 7 - (n + int(n / 4) + int(n / 16)) % 8;
//Serial.print(CS);
//Serial.print("/");
// Shift the bits to the left, seven spaces.
// Makes room for the number.
CS = CS << 7;
//Serial.print(CS);
//Serial.print("/");
// Add number.
CS = CS + n;
//Serial.println(CS);
//Serial.println("---");
// Read bits, and send them.
for ( int i = 9; i >= 0; i--) {
v = bitRead(CS, i);
//Serial.print(i);
//Serial.print("/");
//Serial.print(v);
//Serial.print("/");
//Serial.print (i);
if (v == 1) {
//VLL1();
//led on, delay 20ms, led off, delay 40ms
//Serial.print("One");
digitalWrite(pin[MSNum], HIGH);
delay(DSh);
digitalWrite(pin[MSNum], LOW);
delay(DLo);
}
else {
//VLL0();
// Led on, delay 40ms, led off, delay 20ms
//Serial.print("Zero");
digitalWrite(pin[MSNum], HIGH);
delay(DLo);
digitalWrite(pin[MSNum], LOW);
delay(DSh);
}
//Serial.print("/");
}
//VLLstop();
// led on, delay 20ms, led off, delay 60ms, led on, delay 120ms
digitalWrite(pin[MSNum], HIGH);
delay(20);
digitalWrite(pin[MSNum], LOW);
delay(60);
digitalWrite(pin[MSNum], HIGH);
delay(120);
digitalWrite(pin[MSNum], LOW);
//vllpause();
//led on, delay 150
digitalWrite(pin[MSNum], HIGH);
delay(150);
digitalWrite(pin[MSNum], LOW);
// all done, clear message.
message = "";
Action = -1;
//Serial.println("Done");
}
void VLLInit() {
// VLLinit() {
// led on, delay 400ms, (led off?)
digitalWrite(pin[MSNum], HIGH);
delay(400);
digitalWrite(pin[MSNum], LOW);
// delay 2000ms?
//delay(2000);
}
// ----------------------------
void MicroScout() {
// The main entry for MicroScout program 4 protocol.
String c = "";
int d = 0;
// pull MS number, and Action
MSNum = message.charAt(2);
MSNum = MSNum - 48;
// get action -- action "e" integer
c = message.substring(3);
Action = c.toInt();
d = Action;
// code for all MS.
if (MSNum == 0) {
MSNum = 1;
MSSend();
Action = d;
MSNum = 2;
MSSend();
Action = d;
MSNum = 3;
MSSend();
// clear message
message = "";
Action = -1;
MSNum = 0;
}
else {
// code for 1 MS
MSSend();
// clear message
MSNum = 0;
Action = -1;
message = "";
}
}
void MSSend() {
// code for MS program 4
// MS switches toggle
if (MSNum == 35) {
if (Action == 0) {
Switchtoggle = 0;
Serial.println("MS Switches OFF");
}
else {
Switchtoggle = 1;
Serial.println("MS Switches ON");
}
}
//check direction here
//if needed do reverse blink
if (Action == 1 && MSD[MSNum] == 2) {
MSRevBlink();
MSD[MSNum] = 1;
}
if (Action == 2 && MSD[MSNum] == 1) {
MSRevBlink();
MSD[MSNum] = 2;
}
// Action: stop motor
if (Action == 0) {
digitalWrite(pin[MSNum], LOW);
}
// Action: motor forwards
if (Action == 1) {
digitalWrite(pin[MSNum], HIGH);
}
// Action: motor backwards
if (Action == 2) {
digitalWrite(pin[MSNum], HIGH);
}
// all done, clear message.
message = "";
Action = -1;
}
void MSRevBlink() {
digitalWrite(pin[MSNum], HIGH);
delay(100);
digitalWrite(pin[MSNum], LOW);
delay(100);
digitalWrite(pin[MSNum], HIGH);
delay(100);
digitalWrite(pin[MSNum], LOW);
delay(100);
digitalWrite(pin[MSNum], HIGH);
}
void MSSwitches() {
CC = millis();
// check MicroScout Switches and report changes in status if any.
if ((CC - LSC) > SwitchDebounce) {
int CTot = 1000;
// read pins
MS1St=digitalRead(SW1);
MS2St=digitalRead(SW2);
MS3St=digitalRead(SW3);
// total statuses
if (MS1St == 0) {
CTot=CTot+100;
}
if (MS2St == 0) {
CTot=CTot+10;
}
if (MS3St == 0) {
CTot=CTot+1;
}
// check results
if (CTot == LTot) {
// if equal, do nothing.
}
else {
//print CTot
Serial.print("MS");
Serial.println(CTot);
LTot=CTot;
LSC = CC;
}
}
}
void MVIdAct(){
// Init variables
String a = "";
char b = 0;
String c = "";
int d = 0;
int e = 0;
// get protocol -- protocol "a" String
a = message.substring(0,2);
// get MS port address -- MS address "d" integer
b = message.charAt(2);
d=b-48;
// get action -- action "e" integer
c = message.substring(3);
e = c.toInt();
}
// ----------------------------
// code for RCX
void RCX() {
Serial.println("RCX");
}
// ----------------------------
// code for Bionicle Manas
void Manas() {
Serial.println("Bionicle Manas");
}
// ----------------------------
// code for Spybot
void Spybot() {
Serial.println("Spybot");
}
// ----------------------------
// code for Scout brick
void Scout() {
Serial.println("Scout");
}
// ----------------------------
// code for Power Functions
void PowerFunctions() {
Serial.println("Power9 Function");
}