I've pretty much decided that the 4L80e is the path I'm going to take with my CUCV. But the $600+ for a controller stings. I've been tinkering with a arduino to control it. Right now this is only a proof of concept. The LEDs would actually be IRF540's to control the solenoids. There actually needs to be a 4th as well for the line control, but I'll just live with firm shifts for now. What I have envisioned is to add a LCD screen (simple monochrome one) to display the transmission gear, mode, RPM, trans temp, maybe MPH. What will be needed for automatic shifting would be a TPS, engine RPM, and VSS. I know a 6.5TD TPS should be useable. The RPM could be had by swapping out the "distributor" with a 6.5TD as well. The VSS would probably need to be a inline adapter from dakota digital. Or if you're swapping in a later model t-case, you'd have a VSS. (But you'd need to deal with the speedo for a CUCV with either a GPS unit, a digital to cable adapter, or a speedo that uses a signal instead) I'd like to add a tow/haul button where 3rd gear also locks TCC after delay. As well as button to cycle through modes. (Auto/Manual) I'm wanting this to all be open source, so anyone else wanting to help on this, please feel free to help/share.
Here's the initial code:
Here's the initial code:
#define NUM_FWD_GEARS 4 //# number of forward speeds #define BUTTON_READ_INTERVAL 50ul //mS time between up/down button reads #define NO_PRESS 0x00 //mask bit mask for no buttons pressed #define BUTTON_UP_PRESSED 0x01 //mask bit mask for up button pressed #define BUTTON_DOWN_PRESSED 0x02 //mask bit mask for down button pressed #define TCC_DELAY 1000ul //mS after TCC is enabled, time delay before activation const byte buttonUP = 2; //pin Push Button for UP shift const byte buttonDOWN = 4; //pin Push Button for Down shift const byte solA = 3; //pin Solenoid A output const byte solB = 5; //pin Solenoid B output const byte TCC = 6; //pin TCC output const byte modeswitch = 7; //pin Switch for tow/haul mode byte gearSelection, lastGearSelection, lastUp, lastDn; bool bTCCStatus; unsigned long timeTCCSolenoid; typedef struct structGearSolenoidProfiles ** byte solenoid_A; byte solenoid_B; bool bEnableTCC; }sGearSolenoidProfiles; // // How does Arduino know reverse, park or drive? // const sGearSolenoidProfiles GearSolenoidProfiles[NUM_FWD_GEARS] = ** ** //1st .solenoid_A = HIGH, .solenoid_B = LOW, .bEnableTCC = false }, ** //2nd .solenoid_A = LOW, .solenoid_B = LOW, .bEnableTCC = false }, ** //3rd .solenoid_A = LOW, .solenoid_B = HIGH, .bEnableTCC = false }, ** //4th .solenoid_A = HIGH, .solenoid_B = HIGH, .bEnableTCC = true } };//GearSolenoidProfiles void setup() ** pinMode( buttonUP, INPUT_PULLUP ); lastUp = digitalRead( buttonUP ); //set initial button state pinMode( buttonDOWN, INPUT_PULLUP ); lastDn = digitalRead( buttonDOWN ); //set initial button state pinMode( modeswitch, INPUT ); //modeswitch set as input pinMode( solA, OUTPUT ); //Solenoid A set as output pinMode( solB, OUTPUT ); //Solenoid B set as output pinMode( TCC, OUTPUT ); //TCC set as output digitalWrite( solA, LOW ); //set intital state as off digitalWrite( solB, LOW ); digitalWrite( TCC, LOW ); //internal flag for TCC status bTCCStatus = false; gearSelection = 0; //start in "1st" gear for this test lastGearSelection = 0xff; //ensure we change into correct gear first pass by making last != current }//setup void loop() ** Gear_Selection_Control(); Gear_Solenoid_Control(); TCC_Control(); }//loop void Gear_Selection_Control( void ) ** byte btnState; btnState = ReadButtons(); switch( btnState ) ** case NO_PRESS: //nothing pressed or not read (interval not elapsed); no action break; case BUTTON_UP_PRESSED: if( gearSelection < (NUM_FWD_GEARS-1) ) gearSelection++; break; case BUTTON_DOWN_PRESSED: if( gearSelection > 0 ) gearSelection--; break; default: //only remaining possibility is both pressed; ignore with no action break; }//switch }//void void Gear_Solenoid_Control( void ) ** if( gearSelection != lastGearSelection ) ** lastGearSelection = gearSelection; digitalWrite( solA, GearSolenoidProfiles[gearSelection].solenoid_A ); digitalWrite( solB, GearSolenoidProfiles[gearSelection].solenoid_B ); //if the gear just selected enables the TCC, start the hold-off timer if( GearSolenoidProfiles[gearSelection].bEnableTCC == true ) ** timeTCCSolenoid = millis(); }//if }//if }//Gear_Control void TCC_Control( void ) ** //is TCC now off? if( bTCCStatus == false ) ** //is TCC enabled? if( GearSolenoidProfiles[gearSelection].bEnableTCC == true ) ** //has hold-off time passed? if( millis() - timeTCCSolenoid >= TCC_DELAY ) ** //turn on TCC digitalWrite( TCC, HIGH ); bTCCStatus = true; }//if }//if }//if else ** //TCC is on now; is TCC disabled now? if( GearSolenoidProfiles[gearSelection].bEnableTCC == false ) ** //turn off TCC digitalWrite( TCC, LOW ); bTCCStatus = false; }//if }//else }//TCC_Control //returns a mask: //0b00000000 - no buttons pressed //0b00000001 - up pressed //0b00000010 - down pressed //0b00000011 - both pressed // byte ReadButtons( void ) ** static unsigned long timeButton = 0; unsigned long tNow; byte retval, nowButton; retval = NO_PRESS; tNow = millis(); if( (tNow - timeButton) >= BUTTON_READ_INTERVAL ) ** //set up for next read interval timeButton = tNow; //read the button and set the flags nowButton = digitalRead( buttonUP ); if( nowButton != lastUp ) ** lastUp = nowButton; if( nowButton == LOW ) retval |= BUTTON_UP_PRESSED; }//if nowButton = digitalRead( buttonDOWN ); if( nowButton != lastDn ) ** lastDn = nowButton; if( nowButton == LOW ) retval |= BUTTON_DOWN_PRESSED; }//if }//if return retval; }//ReadButtons