Jump to content

Mech Warrior'd My Car A Little


7 replies to this topic

#1 HimseIf

    Member

  • PipPipPipPipPipPip
  • Visekorporal
  • 270 posts
  • Twitch: Link
  • LocationAotearoa

Posted 31 May 2019 - 01:27 AM

I did not know where to post this but figured some people might appreciate it & encourage me to finish it. If it is not a relevant thread just delete it I guess...

Did you ever want the old voice actress to read out how much fuel is in your car or give you some temp' readings?
If you know mechwarrior2 then you will probably recognize this voice.
When it's perfect i might hand out the code to make it work.

Not sure I want to put a thermal shutdown relay in the ignition though. That could be highly inconvenient.


Edited by HimseIf, 31 May 2019 - 01:31 AM.


#2 Lily from animove

    Member

  • PipPipPipPipPipPipPipPipPipPipPip
  • The Devoted
  • The Devoted
  • 13,891 posts
  • LocationOn a dropship to Terra

Posted 05 June 2019 - 04:12 AM

hmm, I expected some LRM 20 upgrade

#3 LordNothing

    Member

  • PipPipPipPipPipPipPipPipPipPipPipPip
  • Ace Of Spades
  • Ace Of Spades
  • 16,783 posts

Posted 07 June 2019 - 10:11 PM

this thread makes me want to play interstate '76 again.

#4 HimseIf

    Member

  • PipPipPipPipPipPip
  • Visekorporal
  • 270 posts
  • Twitch: Link
  • LocationAotearoa

Posted 18 June 2019 - 12:48 AM

LRM 20 upgrade will have to wait, the police give my car enough looks as it is.


Almost have the most important part of a mech' sorted. The heat warnings.
Not quite ready for the public yet but i'll keep you posted?

#5 Kalimaster

    Member

  • PipPipPipPipPipPipPipPipPip
  • Shredder
  • Shredder
  • 3,811 posts
  • LocationInside the Mech that just fired LRM's at you

Posted 18 June 2019 - 02:55 PM

Posted Image

I must admit, that would be interesting, but if I hear Incoming Missile I don't care if there is a bubble gum machine behind me.

#6 HimseIf

    Member

  • PipPipPipPipPipPip
  • Visekorporal
  • 270 posts
  • Twitch: Link
  • LocationAotearoa

Posted 27 June 2019 - 06:53 PM

If you want to mimic this at home, here's a basic code to start with.
Pins 2,3 and 4 are connected to from ground pin through momentary push buttons on the dashboard for volume and 'pause/recall' last voice readout.
Pins 5 through 9 get connected to ignition, lights ect, you can add more functions if you like, if you can find or make the sound effects for them.

In this code the pins for the max6675 thermocouple module are 12,13 & A1
All these pins are visible on the board.
And you'll need one of the DFRobot mini MP3 modules. They're not expensive & take a little tf card? micro Sd card?
Just add the files for the sound effects (MP3 or wave files) with names like "0001" or "0002". The power up sound is 0002 in my code.
If you add more to this code. The code module seems to like receiving commends in hex. So 0011 would be read as '000b'.

I used zener diodes for cutting the voltage from the 12 volt system down to a safe 3.3 or 5 volts for the arduino. But you can, and should use relays.

You'll need to download & add the software serial and max6675 libraries but that's pretty easy.

#include <max6675.h>
#include <SoftwareSerial.h>
 
SoftwareSerial mySerial(10, 11);
 
int soPin = 12;// SO=Serial Out
int csPin = 13;// CS = chip select CS pin
int sckPin = A1;// SCK = Serial Clock pin
 
MAX6675 thermoSensor(sckPin, csPin, soPin);
 
int volatile thermoSensorNewVal, thermoSensorOldVal;  // an attempt to add zoomcats potentometer test to thermosensor
 
#define TEMP_BAND	 2
#define TEMP_MINOR	60
#define TEMP_GENERAL  75
#define TEMP_DIRE	 90
#define INCR_MINOR	(TEMP_MINOR + TEMP_BAND)
#define INCR_GENERAL  (TEMP_GENERAL + TEMP_BAND)
#define INCR_DIRE	 (TEMP_DIRE + TEMP_BAND)
 
#define DECR_IDLE	 (TEMP_MINOR - TEMP_BAND)
#define DECR_MINOR	(TEMP_GENERAL - TEMP_BAND)
#define DECR_GENERAL  (TEMP_DIRE - TEMP_BAND)
 
enum warningStates_t {IDLE = 0, WARN_MINOR, WARN_GENERAL, WARN_DIRE};
warningStates_t curState, oldState;
 
int buttonPause = 3;
int buttonVolPlus = 2;
int buttonVolMinus = 4;
 
# define ACTIVATED LOW
 
boolean isPlaying = false;
 
const int  buttonPin = 6;	// the pin that the pushbutton is attached to
const int  buttonPin2 = 7;	// the pin that the pushbutton is attached to
const int  buttonPin3 = 8;	// the pin that the pushbutton is attached to
const int  buttonPin4 = 9;	// the pin that the pushbutton is attached to
const int  buttonPin5 = 5;
// the pin that the pushbutton is attached to
// Variables will change:
int buttonPushCounter = 0;   // counter for the number of button presses
int buttonState = 0;		 // current state of the button
int lastButtonState = 0;	 // previous state of the button
int buttonPushCounter2 = 0;   // counter for the number of button presses
int buttonState2 = 0;		 // current state of the button
int lastButtonState2 = 0;	 // previous state of the button
int buttonPushCounter3 = 0;   // counter for the number of button presses
int buttonState3 = 0;		 // current state of the button
int lastButtonState3 = 0;	 // previous state of the button
int buttonPushCounter4 = 0;   // counter for the number of button presses
int buttonState4 = 0;		 // current state of the button
int lastButtonState4 = 0;	 // previous state of the button
int buttonPushCounter5 = 0;   // counter for the number of button presses
int buttonState5 = 0;		 // current state of the button
int lastButtonState5 = 0;	 // previous state of the button
 
 
void setup() {
  Serial.begin(9600);  
  Serial.println("Robojax MAX6675");
 
# define Start_Byte 0x7E
# define Version_Byte 0xFF
# define Command_Length 0x06
# define End_Byte 0xEF
# define Acknowledge 0x00 //Returns info with command 0x41 [0x01: info, 0x00: no info]
 
# define ACTIVATED LOW
 
 
pinMode(buttonPause, INPUT);
digitalWrite(buttonPause,HIGH);
// initialize the button pin as a input:
pinMode(buttonVolPlus, INPUT);
digitalWrite(buttonVolPlus,HIGH);
// initialize the button pin as a input:
pinMode(buttonVolMinus, INPUT);
digitalWrite(buttonVolMinus,HIGH);
// initialize the button pin as a input:
 
pinMode(buttonPin, INPUT);
// initialize the button pin as a input:
pinMode(buttonPin2, INPUT);
// initialize the button pin as a input:
pinMode(buttonPin3, INPUT);
// initialize the button pin as a input:
pinMode(buttonPin4, INPUT);
// initialize the button pin as a input:
pinMode(buttonPin5, INPUT);
// initialize the button pin as a input:
 
  mySerial.begin (9600);
  delay(1000);
  execute_CMD(0x06, 0, 0x12);   // Set the volume between 0-30 (0x00~0x30)//
  execute_CMD(0x03, 0, 0x0002);	//file to play at system start-up//
  isPlaying = true;
 
 
 
}
 
 
void loop()
{
  thermoSensorNewVal = thermoSensor.readCelsius();
 
  if (thermoSensorNewVal != thermoSensorOldVal) {
	Serial.print(" C = ");
	Serial.print(thermoSensorNewVal);
 
	thermoSensorOldVal = thermoSensorNewVal;
  }
 
  switch (curState) {
	default:			curState = IDLE;  /* should never happen, but good practice to have a default */
	case IDLE:		  if (thermoSensorNewVal >= INCR_MINOR)   curState = WARN_MINOR;	break;
 
	case WARN_MINOR:	if (thermoSensorNewVal <= DECR_IDLE)	curState = IDLE;
	  if (thermoSensorNewVal >= INCR_GENERAL) curState = WARN_GENERAL;  break;
 
	case WARN_GENERAL:   if (thermoSensorNewVal <= DECR_MINOR)   curState = WARN_MINOR;
	  if (thermoSensorNewVal >= INCR_DIRE)	curState = WARN_DIRE;	 break;
 
	case WARN_DIRE:	 if (thermoSensorNewVal <= DECR_GENERAL) curState = WARN_GENERAL;  break;
  }
 
  if (curState > oldState) {
	// Increased temp warnings
	switch (curState) {
	  case WARN_MINOR:	playThermalExceed();   break;
	  case WARN_GENERAL:  playHeatLevelCrit(); break;
	  case WARN_DIRE:	 playMeltdownImminent();	break;
	  default:			break;  /* should never happen, but good practice to have a default */
	}
  }
 
  if (curState < oldState) {
	// Decreased temp warnings
	switch (curState) {
	  case IDLE:		  playHeatNominal();/* Could do an 'all clear' message here */	break;
	  case WARN_MINOR:	break;
	  case WARN_GENERAL:  playHeatModerate(); break;
	  default:			break;  /* should never happen, but good practice to have a default */
		}
  }
 
  oldState = curState;
  delay(500);
	Serial.print(" C = ");
	Serial.print(thermoSensorNewVal);
  // read the pushbutton input pin:
  buttonState = digitalRead(buttonPin);
 
  // compare the buttonState to its previous state
  if (buttonState != lastButtonState) {
	// if the state has changed, increment the counter
	if (buttonState == HIGH) {
	  // if the current state is HIGH then the button went from off to on:
	  buttonPushCounter++;
	  playEngineEnabled();
	} else {
	  // if the current state is LOW then the button went from on to off:
	  playShuttingDown();
	}
	// Delay a little bit to avoid bouncing
	delay(20);
  }
  // save the current state as the last state, for next time through the loop
  lastButtonState = buttonState;
 
  // read the pushbutton input pin:
  buttonState2 = digitalRead(buttonPin2);
 
  // compare the buttonState to its previous state
  if (buttonState2 != lastButtonState2) {
	// if the state has changed, increment the counter
	if (buttonState2 == HIGH) {
	  // if the current state is HIGH then the button went from off to on:
	  buttonPushCounter2++;
	  playLightAmpEngaged();
	} else {
	  // if the current state is LOW then the button went from on to off:
	  playButtonOff();
	}
	// Delay a little bit to avoid bouncing
	delay(20);
  }
  // save the current state as the last state, for next time through the loop
  lastButtonState2 = buttonState2;
 
  buttonState3 = digitalRead(buttonPin3);
  // compare the buttonState to its previous state
  if (buttonState3 != lastButtonState3) {
	// if the state has changed, increment the counter
	if (buttonState3 == HIGH) {
	  // if the current state is HIGH then the button went from off to on:
	  buttonPushCounter++;
	  playLightAmp2Engaged();
	} else {
	  // if the current state is LOW then the button went from on to off:
	  playButtonOff();
	}
	// Delay a little bit to avoid bouncing
	delay(20);
  }
  // save the current state as the last state, for next time through the loop
  lastButtonState3 = buttonState3;
 
  // read the pushbutton input pin:
  buttonState4 = digitalRead(buttonPin4);
 
  // compare the buttonState to its previous state
  if (buttonState4 != lastButtonState4) {
	// if the state has changed, increment the counter
	if (buttonState4 == HIGH) {
	  // if the current state is HIGH then the button went from off to on:
	  buttonPushCounter4++;
	  playEXcamEngaged();
	} else {
	  // if the current state is LOW then the button went from on to off:
	  playButtonOff();
	}
	// Delay a little bit to avoid bouncing
	delay(20);
  }
  // save the current state as the last state, for next time through the loop
  lastButtonState4 = buttonState4;
 
	// read the pushbutton input pin:
  buttonState5 = digitalRead(buttonPin5);
 
  // compare the buttonState to its previous state
  if (buttonState5 != lastButtonState5) {
	// if the state has changed, increment the counter
	if (buttonState5 == HIGH) {
	  // if the current state is HIGH then the button went from off to on:
	  buttonPushCounter5++;
	  playPhoneChargePort();
	} else {
	  // if the current state is LOW then the button went from on to off:
	  playButtonOff();
	}
	// Delay a little bit to avoid bouncing
	delay(20);
  }
  // save the current state as the last state, for next time through the loop
  lastButtonState5 = buttonState5;
 
if (digitalRead(buttonPause) == ACTIVATED)
  {
	if(isPlaying)
	{
	  pause();
	  isPlaying = false;
	}else
	{
	  isPlaying = true;
	  play();
	}
  }
 
if (digitalRead(buttonVolPlus) == ACTIVATED)
  {
	if(isPlaying)
	{
	  setVolumeUp();
	}
  }
 
  if (digitalRead(buttonVolMinus) == ACTIVATED)
  {
	if(isPlaying)
	{
	  setVolumeDown();
	}
  }
} // end of loop?
 
void playThermalExceed()
{
  Serial.println(" Thermal Exceeded Triggered Once ");
  execute_CMD(0x03, 0, 0x000c);	//file between 0-2999 in main folder. Doesn't love folders.//
  delay(500);
}
 
void playHeatLevelCrit()
{
  Serial.println(" Heat Critical Triggered Once ");
  execute_CMD(0x03, 0, 0x000a);	//file between 0-2999 in main folder. Doesn't love folders.//
  delay(500);
}
 
void playMeltdownImminent()
{
  Serial.println(" Meltdown Triggered Once ");
  execute_CMD(0x03, 0, 0x000b);	//file between 0-2999 in main folder. Doesn't love folders.//
  delay(500);
}
 
void playHeatModerate()
{
  Serial.println(" HeatModerate Once ");
  execute_CMD(0x03, 0, 0x000d);	//file between 0-2999 in main folder. Doesn't love folders.//
  delay(500);
}
 
void playHeatNominal()
{
  Serial.println(" HeatNominal Triggered Once ");
  execute_CMD(0x03, 0, 0x000e);	//file between 0-2999 in main folder. Doesn't love folders.//
  delay(500);
}
 
void pause()
{
  execute_CMD(0x0E,0,0);
  delay(500);
}
 
void play()
{
  execute_CMD(0x0D,0,1);
  delay(500);
}
 
void playNext()
{
  execute_CMD(0x01,0,1);
  delay(50);
}
 
void playPrevious()
{
  execute_CMD(0x02,0,1);
  delay(50);
}
 
void setVolumeUp()
{
  execute_CMD(0x04, 0, 1); // Set the volume (0x00~0x30)
  delay(50);
}
 
void setVolumeDown()
{
  execute_CMD(0x05, 0, 1); // Set the volume (0x00~0x30)
  delay(50);
}
 
void setVolume(int volume) //Specify volume using code. Not applicable to the normal button interface.
{
  execute_CMD(0x06, 0, volume); // Set the volume (0x00~0x30)
  delay(2000);
}
 
void playEngineEnabled()
{
  execute_CMD(0x03, 0, 0x0006);	//file between 0-2999 in main folder. Doesn't love folders.//
  delay(1500);
}
 
void playLightAmpEngaged()
{
  execute_CMD(0x03, 0, 0x0004);	//file between 0-2999 in main folder. Doesn't love folders.//
  delay(2200);
}
 
void playLightAmp2Engaged()
{
  execute_CMD(0x03, 0, 0x0005);	//file between 0-2999 in main folder. Doesn't love folders.//
  delay(2500);
}
 
void playEXcamEngaged()
{
  execute_CMD(0x03, 0, 0x0007);	//file between 0-2999 in main folder. Doesn't love folders.//
  delay(2500);
}
 
void playShuttingDown()
{
  execute_CMD(0x03, 0, 0x0003);	//file between 0-2999 in main folder. Doesn't love folders.//
  delay(600);
}
 
void playPhoneChargePort()
{
  execute_CMD(0x03, 0, 0x0009);	//file between 0-2999 in main folder. Doesn't love folders.//
  delay(1500);
}
 
void playButtonOff()
{
  execute_CMD(0x03, 0, 0x0008);	//file between 0-2999 in main folder. Doesn't love folders.//
  delay(400);
}
 
void execute_CMD(byte CMD, byte Par1, byte Par2)
// Excecute the command and parameters
{
  // Calculate the checksum (2 bytes)
  word checksum = -(Version_Byte + Command_Length + CMD + Acknowledge + Par1 + Par2);
  // Build the command line
  byte Command_line[10] = { Start_Byte, Version_Byte, Command_Length, CMD, Acknowledge,
							Par1, Par2, highByte(checksum), lowByte(checksum), End_Byte
						  };
  //Send the command line to the module
  for (byte k = 0; k < 10; k++)
  {
	mySerial.write( Command_line[k]);
  }
}


Have fun.

Edited by HimseIf, 27 June 2019 - 06:59 PM.


#7 Tordin

    Member

  • PipPipPipPipPipPipPipPipPip
  • The Wolf
  • The Wolf
  • 2,937 posts
  • LocationNordic Union

Posted 01 July 2019 - 12:14 PM

View PostLordNothing, on 07 June 2019 - 10:11 PM, said:

this thread makes me want to play interstate '76 again.


Oh yes! I remember that one, only played the demo but it was awesome. Not much about gunning up your cars in media sadly, maybe except mad max movies to some degree, but then again the raiders cars looks like scrap metal.

Awesome work this. Hope you will complete your mechcar someday. As if it wil sprout legs and walk!

Edited by Tordin, 01 July 2019 - 12:16 PM.


#8 LordNothing

    Member

  • PipPipPipPipPipPipPipPipPipPipPipPip
  • Ace Of Spades
  • Ace Of Spades
  • 16,783 posts

Posted 01 July 2019 - 04:50 PM

View PostTordin, on 01 July 2019 - 12:14 PM, said:


Oh yes! I remember that one, only played the demo but it was awesome. Not much about gunning up your cars in media sadly, maybe except mad max movies to some degree, but then again the raiders cars looks like scrap metal.


unfortunately i76 is notoriously hard to get running on modern hardware. its based on the mechwarrior2 engine so i wonder if i can run it in mechvm. the installer wont even run if it thinks your machine cant handle it, like having a processor other than a pentium or not having a voodoo card. a windows 98 instal on vm is probably required just to instal it. not that does me any good, i76 is one of those games i never got around to imaging and i dont have any cd drives that work.

i think my ideal vehicular shooter game would probably be a cross between i76 and carmageddon. pretty much everything from i76, even the funky soundtrack, plus splatterable pedestrians. its a franchise in dire need of a reboot.

Edited by LordNothing, 01 July 2019 - 04:56 PM.






1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users