Not joined yet? Register for free and enjoy features such as alerts, private messaging and viewing latest posts and topics.

E85 / E86 BMW Z4 – Android tablet integration

Post Reply
User avatar
sk93
Lifer
Lifer
Posts: 3970
Joined: Mon Oct 19, 2009 9:20 pm
Location: Nottingham
Contact:

Re: E85 / E86 BMW Z4 – Android tablet integration - INCOMPLE

Post by sk93 » Sun Jul 06, 2014 7:38 am

removed
Last edited by sk93 on Mon Jun 01, 2015 9:50 pm, edited 1 time in total.
:zzzz:

igeak691
Member
Member
Posts: 313
Joined: Thu Mar 06, 2014 1:31 am

Re: E85 / E86 BMW Z4 – Android tablet integration - INCOMPLE

Post by igeak691 » Mon Jul 07, 2014 4:00 am

Does the code have any provisions so that it knows when its open and knows when its closed?
YouTube channel with car vlogs in my zed!
Please subscribe and share my videos with fellow enthusiasts!

User avatar
sk93
Lifer
Lifer
Posts: 3970
Joined: Mon Oct 19, 2009 9:20 pm
Location: Nottingham
Contact:

Re: E85 / E86 BMW Z4 – Android tablet integration - INCOMPLE

Post by sk93 » Mon Jul 07, 2014 8:16 am

removed
Last edited by sk93 on Mon Jun 01, 2015 9:50 pm, edited 1 time in total.
:zzzz:

igeak691
Member
Member
Posts: 313
Joined: Thu Mar 06, 2014 1:31 am

Re: E85 / E86 BMW Z4 – Android tablet integration - INCOMPLE

Post by igeak691 » Tue Jul 08, 2014 4:11 pm

Just got the Arduino board and uploaded some test sketches with no issues, and uploaded the script. Waiting on the motor shield but once that arrives I should be good for testing. Thanks for doing all the hard work :)

For this setup as its written it would be best to close the screen if you have it open, before you turn on the radio, so that it doesn't try to open it again.
Same thing as if it was closed after the radio was turned on, it would be best to open it back up before turning off the radio.

I'll look more into it, perhaps we can use a magnetic reed switch to sense the position of the screen. I wonder if this is what the circuit board inside the motor housing was responsible for, since it has 11 wires instead of the 4.
YouTube channel with car vlogs in my zed!
Please subscribe and share my videos with fellow enthusiasts!

igeak691
Member
Member
Posts: 313
Joined: Thu Mar 06, 2014 1:31 am

Re: E85 / E86 BMW Z4 – Android tablet integration - INCOMPLE

Post by igeak691 » Wed Jul 09, 2014 7:35 pm

When connecting the motor wires, pairs have to go together, but do they have to be in a particular order? If the coils were put on in opposite directions, wouldn't it fight itself? Or does the arduino know which is which?
YouTube channel with car vlogs in my zed!
Please subscribe and share my videos with fellow enthusiasts!

igeak691
Member
Member
Posts: 313
Joined: Thu Mar 06, 2014 1:31 am

Re: E85 / E86 BMW Z4 – Android tablet integration - INCOMPLE

Post by igeak691 » Mon Jul 14, 2014 7:09 pm

sk93, are you using a switched 12v power supply? if so, where are you tapping into that on the wiring?
YouTube channel with car vlogs in my zed!
Please subscribe and share my videos with fellow enthusiasts!

User avatar
sk93
Lifer
Lifer
Posts: 3970
Joined: Mon Oct 19, 2009 9:20 pm
Location: Nottingham
Contact:

Re: E85 / E86 BMW Z4 – Android tablet integration - INCOMPLE

Post by sk93 » Mon Jul 14, 2014 7:39 pm

removed
Last edited by sk93 on Mon Jun 01, 2015 9:50 pm, edited 1 time in total.
:zzzz:

igeak691
Member
Member
Posts: 313
Joined: Thu Mar 06, 2014 1:31 am

Re: E85 / E86 BMW Z4 – Android tablet integration - INCOMPLE

Post by igeak691 » Tue Jul 15, 2014 2:41 pm

In your setup, don't you always have the screen juttering in the beginning?

For example, if the screen is down, when you turn the car on, and the radio isn't on, it'll jutter trying to close itself.
But if you have the radio on it'll open, and stay open, but nothing's going to close the screen when the car is turned off along with the radio since the arduino will lose power the same time the radio does. Am I making sense here? Or does the radio turn off before the switched power supply is cut?
YouTube channel with car vlogs in my zed!
Please subscribe and share my videos with fellow enthusiasts!

User avatar
LukeMace
Senior Member
Senior Member
Posts: 1918
Joined: Wed Apr 18, 2012 7:40 pm
Location: Northampton

Re: E85 / E86 BMW Z4 – Android tablet integration - INCOMPLE

Post by LukeMace » Tue Jul 15, 2014 10:39 pm

WOW!
3.0, Quad Conversion, 19" CSLs, Bucket Seats, Big Brake Conversion, Lowered 40mm, AE and Clear Hockeys etc...
CLICK HERE FOR THE BUILD THREAD
Image

User avatar
sk93
Lifer
Lifer
Posts: 3970
Joined: Mon Oct 19, 2009 9:20 pm
Location: Nottingham
Contact:

Re: E85 / E86 BMW Z4 – Android tablet integration - INCOMPLE

Post by sk93 » Tue Jul 15, 2014 10:44 pm

removed
Last edited by sk93 on Mon Jun 01, 2015 9:50 pm, edited 1 time in total.
:zzzz:

igeak691
Member
Member
Posts: 313
Joined: Thu Mar 06, 2014 1:31 am

Re: E85 / E86 BMW Z4 – Android tablet integration - INCOMPLE

Post by igeak691 » Wed Jul 16, 2014 3:20 am

That's why when I looked at your coding, I removed the initial detection for the state of the ACC line. I'm going to be continually powering the arduino (don't think it uses much standby current).

The arduino powering the tablet is a great idea! Is there any part of the arduino that can supply 1000mA of power at 5v? If so, there's your power supply right there. Also, one less cable exiting the side holes. Don't think I'll implement that myself, but cool to see it might be possible.

I've got mine all set up now, just waiting on a 3PDT switch so that I can use tablet aux in, or bluetooth from phone with the flip of a switch. Though this retrofitting has its quirks, its coming out better than I thought it would. :)
YouTube channel with car vlogs in my zed!
Please subscribe and share my videos with fellow enthusiasts!

igeak691
Member
Member
Posts: 313
Joined: Thu Mar 06, 2014 1:31 am

Re: E85 / E86 BMW Z4 – Android tablet integration - INCOMPLE

Post by igeak691 » Fri Jul 25, 2014 1:21 am

Which wires do you use for positive and ground for switched power supply? There's a bunch of wires going down to the seat heaters/roof modules and I don't want to probe all of them to find out since I'm lazy :)
YouTube channel with car vlogs in my zed!
Please subscribe and share my videos with fellow enthusiasts!

Svet88
Newbie
Newbie
Posts: 3
Joined: Mon Nov 24, 2014 11:49 pm

Re: E85 / E86 BMW Z4 – Android tablet integration - INCOMPLE

Post by Svet88 » Mon Nov 24, 2014 11:59 pm

Hi guys,

I have a hopefully simple question on powering the monitor .

I just bought the monitor and would like to do the following with it:

1. Power the motor
2. Make the motor behave as original ("wake up" on ignition, remember it's last position etc..). Not sure about that one, but as far as I know it has these functions stored on the motherboard of the monitor itself, and the mk computer is not needed for this

3. After the motor of the monitor is powered properly, I would like to power a tablet as well.

Powering and making the motor behave as stock without using the computer is the main goal here, integrating the tablet should be much more straightforward.

I really hope someone could help me out the with motorization. I would love if you could drop me a message on skype: T-1000-bg , or gmail : [email protected]

js_online
Newbie
Newbie
Posts: 25
Joined: Mon May 18, 2015 11:49 pm

Re: E85 / E86 BMW Z4 – Android tablet integration - INCOMPLE

Post by js_online » Tue May 19, 2015 12:54 am

Hi!

First of all thanks a lot for your effort, I really appreciate it. It really helped me to initially understand and to start implementing my setup.
I'd like to share details of setup using Arduino R3 UNO and native L9935 stepper motor driver using Serial Peripheral Interface (SPI) (without using Arduino Motor Shield).

I used Sony Xperia Z Ultra phone as tablet.
Image
Advantages:
1. 6.4" screen - fits perfect, original one is 6.5"
2. 4G Internet - perfect for online TV and online multimedia processing
3. Special socket for charging (magnetic charge, using my own wire I achieved >1A charging current - this is ok). Original USB cable is connected and will be used for sync when required.
Adjustments required in monitor frame to make it fit. I also used П style horizontal aluminum frame to fix tablet in frame and to fix wires and Arduino board.
4. waterproof protectors removed (for better cooling down).

I achieved functionality very similar to OEM, except manual adjustments by hand (counter is not counting these).
Counter is used to check monitor position and to do not move it in case of min/max position.
Last position of monitor is saved to internal memory of Arduino R3 UNO (EEPROM) in the moment key (ignition) is turned off and restored from internal memory in the moment ignition is turned on.

I also used timer to delay power off. Original board monitor 18pin white socket X18802 contains +12V Acc wire at pin 8 (linked to battery thru Fuse ?F49 - not verfied) and GND Pin 9.
1. This wire (+12V Acc) is connected to Timer as Input.
2. Timer Output +12V is connected to all consumers - 12v to 5v converter (used to power tablet, L9935 logic supply, arduino R3), stepper motor supply voltage Vs etc.
3. +12V IGN is used as Activating input of Timer.F

Timer logic is following:
1. after ignition is turned on everything is powered on.
2. after ignition is turned off timer is activated and disconnects +12V output from +12V input (ACC) after X seconds (time is adjusted by trimmer and is from 1sec up to 20mins).
As I am not expert in electronics I purchased timer on ebay.


Pictures of my setup are below:
See also demo videos below

1.Wires are soldered directly to L9935 stepper motor driver:
Image

2.Frame:
Image

3.Closer look to Arduino R3 UNO:
Image

4. Timer
Image

5.Wiring diagram:
Image

L9935 datasheet - detailed information about L9935 pinning and basic operating principles.

Stepper Motor Basics - understanding channels, polarity, states and direction of rotation.
Image

Code: Select all

/*==========================================================================================================================
Created by JS online, [email protected]
Last update 21-May-2015

Arduino R3 UNO code to operate L9935 stepper motor driver.
Main functionality:
1. Opening screen fully - after ignition is turned on or by open button
2. Closing screen fully - after ignition is turned off or by close button
3. Saving monitor last position to Arduino internal EEPROM memory after ignition is turned off (full step only).
4. Opening by small steps - by step open button
5. Closign by small steps - by step close button (min position is limited to half way - the same as in original behavior)

Enable Serial Monitor Ctrl + Shift + M to see debug messages.
==========================================================================================================================*/
#include <SPI.h>
#include <EEPROM.h>

//L9935 pinning
int SLAVESEL=10; //using digital pin 10 for SPI slave select
int DATAOUT=11;  //using digital pin 11 for MOSI (Master Out Slave In) - master line for sending data to slave
int DATAIN=12;   //using digital pin 12 for MISO (Master In Slave Out) - the slave sending data to the master
int SPICLOCK=13; //using digital pin 13 for SCK (Serial Clock) - The clock pulses which synchronize data transmission generated by the master 
int EN=9;        //Enable (Low Active)

//Board Monitor Buttons
#define OPEN_BUTTON 6       //montior open button full
#define CLOSE_BUTTON 7      //montior close button full
#define STEP_OPEN 4         //montior open button step 
#define STEP_CLOSE 5        //montior close button step

/*Ignition key 12V relay 
R3 UNO, L9935 stepper motor (tablet and other consumers) are powered from +12V ACC (Battery) - X18802 18pin white board monitor socket, Pin 8 = +12V ACC (thru fuse F49), Pin 9 = GND). 
Timer is used for power off delay option. Timer is activated by +12V IGN (Ignition). Power off delay is required to allow close screen after ignition key is turned off and to do not leave 
consumers connected to +12V ACC permanently. Timer logic is the following:
1. after ignition is turned on everything is powered on. Timer Output is operational and connected to +12 ACC: consumers are powered.
2. after ignition is turned off Timer is activated and disconnects +12V Timer Output from +12V Timer Input (ACC) after X seconds (time is adjusted by trimmer and is from 1 sec up to 20 mins). 
After timeout Timer disconnects ACC 12V power, so R3 UNO, L9935 stepper motor and other consumers are also unpowered.*/ 

#define IGN_PWR 8           //igntion 12V power detection. Relay connected to 12V iginition power connects/disconnects GND with IGN_PWR wire.
int ignState = 0;
  
//Delays - miliseconds used for various delays
int DELAY_SS=1;     //very short delay
int DELAY_S=16;     //short delay
int DELAY_N=100;    //standard delay
int DELAY_L=500;    //long delay
int DELAY_INIT=5000;    //delay on ignition

//Monitor positioning: over movement protection and last position. Last saved position works by operating buttons only. Positioning is not tracked if monitor is adjusted manually.
//Last position of monitor is saved after ignition 12v power is turned off. Last position of monitor is restored after ingnition 12v power is tuned on.
float POS_CUR=0;          //monitor current positon full step counter
int POS_CUR_HS=0;         //monitor position half step counter
float POS_STEP_HS=0.25;   //monitor position half step
int POS_STEP_MIN=7;       //limiting min half step position
float POS_MAX=10.7;       //monitor maximum position
int POS_CUR_SAVED=0;      //monitor saved position (full step only)
int POS_CUR_ADDR=0;       //EEPROM address for storing current position (full step only)

//int ERR_CODE;    //read L9935 SPI error code in case if DATAIN pin is connected

// the setup function runs once when you press reset or power the board
void setup() {
  
  pinMode(SLAVESEL, OUTPUT);           //CSN
  pinMode(DATAOUT, OUTPUT);            //SDI
  pinMode(DATAIN, INPUT);              //SDO not used
  pinMode(SPICLOCK, OUTPUT);           //SCK
  pinMode(EN, OUTPUT);                 //Enable

  pinMode(OPEN_BUTTON, INPUT_PULLUP);      //Open Button Full
  pinMode(CLOSE_BUTTON, INPUT_PULLUP);     //Close Button Full
  pinMode(STEP_OPEN, INPUT_PULLUP);        //Open Button Step
  pinMode(STEP_CLOSE, INPUT_PULLUP);       //Close Button Step  
  
  pinMode(IGN_PWR, INPUT_PULLUP);          //Iginition 12V
      
  SPI.begin();                           //wake up the SPI bus.
  SPI.setBitOrder(MSBFIRST);             //data to be sent MSB (most significant byte) first
  SPI.setClockDivider(SPI_CLOCK_DIV16);  //1Mhz SPI clock 16/16
  SPI.setDataMode(SPI_MODE3);            //SPI_MODE3 - CPOL=1 the base value of the clock is one; CPHA=1, data are captured on clock's rising edge and data is propagated on a falling edge

  // initialize serial communication at 9600 bits per second:
  Serial.begin(9600);

  //detect initial state of ignition 12V power
  ignState = digitalRead(IGN_PWR);
  if (ignState==LOW)   {
    //ignition 12V power is on
    //power on delay
    delay(DELAY_INIT);
    readPOS_CUR(POS_CUR_ADDR); //reading current monitor position from internal EEPROM memory
    screenUp(POS_CUR_SAVED);
  }
  else   {
    //ignition 12V power is off
    screenDown();
  } 
  
}

// the loop function runs over and over again forever
void loop() {
  
  int switchValue; 
  
    switchValue = digitalRead(IGN_PWR);
    if (switchValue != ignState)
    {
      if (switchValue==LOW) {
        //ignition 12V power has been turned on
        //power on delay
        delay(DELAY_INIT);
        readPOS_CUR(POS_CUR_ADDR); //reading current monitor position from internal EEPROM memory
        screenUp(POS_CUR_SAVED);
      }
      else {
        //ignition 12V power has been turned off
        writePOS_CUR(POS_CUR_ADDR, POS_CUR); //writing current monitor position to internal EEPROM memory
        screenDown();
      }
      //udpate state
      ignState = switchValue;
    }  
  
  switchValue = digitalRead(OPEN_BUTTON);
  if (switchValue==LOW) {
    screenUp(-1);    //sending -1 to execute standard logic without restoring last position 
  }
  
  switchValue = digitalRead(CLOSE_BUTTON);
  if (switchValue==LOW) {
    screenDown();
  }
  
  switchValue = digitalRead(STEP_OPEN);
  if (switchValue==LOW) {
    activateL9935EN();
    stepUpHalf();
  }
  
  switchValue = digitalRead(STEP_CLOSE);
  if (switchValue==LOW) {
    activateL9935EN();
    stepDownHalf();
  }
}

/* L9935 basic info. For more info see L9935 technical data sheet.
Command byte: 6 first bits (0-5) are used for command, Last 2 bits (6,7) are used for command response - return error code (not processed in current code, can be read and processed thru DATAIN pin).
Command byte bits: 76543210 
bit5,bit4: current range of bridge A (Outputs A1 and A2)
bit3: polarity of bridge A
bit2,bit1: current range of bridge B (Outputs B1 and B2)
bit0: polarity of bridge B
bit7,bit6: Error1 and Error 2
Command byte should be converted from binary to decimal (00001111 = 15) and passed as decimal to setValue function.

Current settings (bit5 bit4 for A1 and A2 or bit2 bit1 for B1 and B2). HIGH=H=1; LOW=L=0;
H H = 1 1 = 0 - not used in current code
H L = 1 0 = 60 mA  6% internally sensed - used in current code for parking, screen can be moved manually in this mode.
L H = 0 1 = 550 mA 61 % - used in current code for step opening and step closing
L L = 0 0 = 900 mA 100 % - used in current code for opening and closing screen fully
*/

//functions
void setSPIValue(int SPI_COMMAND)
{
  digitalWrite(SLAVESEL, LOW);       //Start of frame. Falling slope of CSN indicates start of frame. 
  SPI.transfer(SPI_COMMAND);         //Send value (0~255) in decimal format. Data transfer (reading SDI into the register) takes place at the rising slopes of SCK.
//  ERR_CODE = digitalRead(DATAIN);  //Read error code
  digitalWrite(SLAVESEL, HIGH);      //End of frame
  delay(DELAY_S);
}

void activateL9935EN(void) {
    digitalWrite(EN, HIGH);     //disable L9935 
    delay(DELAY_SS);
    digitalWrite(EN, LOW);      //enable L9935. Falling slope of EN activates the device. After ten.sck the device is ready to work.
    delay(DELAY_SS);
}

void screenUp(float POS) { 
  
    activateL9935EN();
    
    float b;   
    //Initial opening: saved positon from internal EEPROM will be used. Other cases: standard logic calculating current and max position.
    if (POS >= 0) b = POS; else b = POS_MAX-POS_CUR;     
    for (int a = 0; a < b; a++)
    {
      stepUp();
    }    
    screenPark(); 
    
}

void screenDown(void) { 
    
    activateL9935EN();

    int b = POS_CUR;
    while (POS_CUR >= 1)
    {    
      stepDown();
    }
    
    POS_CUR=0;        //resetting current position
    POS_CUR_HS=0;     //resetting half step position
    screenPark();

}

void stepUp(void) { 
  
   //full step mode processing for complete opening;
   //POS_CUR direction 0 --> 1 --> 2 --> 3
   /*States:
    0 = CH A enabled, polarity=HIGH. CH B disabled.
    1 = CH A disabled. CH B disabled, polarity=LOW.
    2 = CH A enabled, polarity = LOW. CH B disabled.
    1 = CH A disabled. CH B enabled, polarity=HIGH.
   */
   
   if(POS_CUR <= (POS_MAX - 1)) {  
      setSPIValue(15);    //00001111 CH A enabled, polarity=HIGH (Current=900mA). CH B disabled.
      setSPIValue(56);    //00111000 CH A disabled. CH B enabled, polarity=LOW (Current=900mA).
      setSPIValue(6);     //00000110 CH A enabled, polarity=LOW (Current=900mA). CH B disabled. 
      setSPIValue(57);    //00111001 CH A disabled. CH B enabled, polarity=HIGH (Current=900mA). 
      POS_CUR += 1;
      Serial.print("POS_CUR=");Serial.println(POS_CUR); 
   }
}

void stepDown(void) {
   //full step mode processing for complete closing;
   //POS_CUR direction 0 --> 3 --> 2 --> 1

   if(POS_CUR > 0) {     
      setSPIValue(15);    //00001111 CH A enabled, polarity=HIGH (Current=900mA). CH B disabled.
      setSPIValue(57);    //00111001 CH A disabled. CH B enabled, polarity=HIGH (Current=900mA). 
      setSPIValue(7);     //00000111 CH A enabled, polarity=LOW (Current=900mA). CH B disabled.
      setSPIValue(48);    //00110000 CH A disabled. CH B enabled, polarity=LOW (Current=900mA).
      POS_CUR -= 1;
      Serial.print("POS_CUR=");Serial.println(POS_CUR);
   }
}

void screenPark(void) { 
    /*Parking allows manual movement of screen by hand (counter is not working in this case). 
      Stepper motor current is set to HL (internally sensed).
      HH will not fix monitor at all as current is 0.
      HL and LL with 550mA and 900mA current will hold monitor and will not allow manual movement.
    */  
    setSPIValue(47);    //00101111 CH A enabled, polarity=HIGH. CH B disabled (Current 60mA).
    delay(DELAY_S); 
}


void stepUpHalf(void) {
/*Half steps can be used here by using middle states (currently not used) - step 1.2, step 2.2, step 3.2, step 4.2.
In this case both channels are enabled, use current max 550mA (avoid higher current 900mA, overheating risk exists).
*/
   if(POS_CUR <= (POS_MAX - POS_STEP_HS) && POS_CUR >= POS_STEP_MIN) {  
   //POS_CUR_HS direction 0 --> 1 --> 2 --> 3

   if(POS_CUR_HS == 0) {
      setSPIValue(31);    //00011111 CH A enabled, polarity=HIGH (Current=550mA). CH B disabled.  --current step
      setSPIValue(58);    //00111010 CH A disabled. CH B enabled, polarity=LOW. (Current=550mA). --next step
      setSPIValue(60);    //00111100 CH A disabled. CH B enabled, polarity=LOW (Current=60mA).   --park
      Serial.print("STEP1"); 
  }
  
   if(POS_CUR_HS == 1) {
      setSPIValue(58);    //00111010 CH A disabled. CH B enabled, polarity=LOW (Current=550mA).  --current step
      setSPIValue(22);    //00010110 CH A enabled, polarity=LOW (Current=550mA). CH B disabled. --next step
      setSPIValue(38);    //00100110 CH A enabled, polarity=LOW (Current=60mA). CH B disabled.  --park
      Serial.print("STEP2"); 
   }   

   if(POS_CUR_HS == 2) {
      setSPIValue(22);    //00010110 CH A enabled, polarity=LOW (Current=550mA). CH B disabled.   --current step
      setSPIValue(51);    //00110011 CH A disabled. CH B enabled, polarity=HIGH (Current=550mA). --next step
      setSPIValue(53);    //00110101 CH A disabled. CH B enabled, polarity=HIGH (Current=60mA).  --park
      Serial.print("STEP3"); 
   }   

   if(POS_CUR_HS == 3) { 
      setSPIValue(51);    //00110011 CH A disabled. CH B enabled, polarity=HIGH (Current=550mA).  --current step
      setSPIValue(31);    //00011111 CH A enabled (Current=550mA), polarity=HIGH. CH B disabled. --next step
      setSPIValue(47);    //00101111 CH A enabled (Current=60mA), polarity=HIGH. CH B disabled.  --park
      Serial.print("STEP4"); 
   }   
       
      if(POS_CUR_HS == 3) POS_CUR_HS=0; else POS_CUR_HS +=1;   
      Serial.print(" POS_CUR_HS=");Serial.print(POS_CUR_HS); 
      POS_CUR += POS_STEP_HS;
      Serial.print(" POS_CUR=");Serial.println(POS_CUR);
      delay(DELAY_L);
   }
}

void stepDownHalf(void) {
/*Half steps can be used here by using middle states (currently not used) - step 1.2, step 2.2, step 3.2, step 4.2.
  In this case both channels are enabled, use current max 550mA (avoid 900mA current, overheating risk exists).
*/

   if(POS_CUR > POS_STEP_MIN) {   
   //POS_CUR_HS direction 0 --> 3 --> 2 --> 1
    
   if(POS_CUR_HS == 0) {
      setSPIValue(31);    //00011111 CH A enabled, polarity=HIGH (Current=550mA). CH B disabled.  --current step
      setSPIValue(59);    //00111011 CH A disabled. CH B enabled, polarity=HIGH (Current=550mA). --next step
      setSPIValue(61);    //00111101 CH A disabled. CH B enabled, polarity=HIGH (Current=60mA).  --park
      Serial.print("STEP1"); 
   }

   if(POS_CUR_HS == 3) {
      setSPIValue(59);    //00111011 CH A disabled. CH B enabled, polarity=HIGH (Current=550mA). --current step
      setSPIValue(23);    //00010111 CH A enabled, polarity=LOW. CH B disabled (Current=550mA). --next step
      setSPIValue(39);    //00100111 CH A enabled, polarity=LOW. CH B disabled (Current=60mA).  --park
      Serial.print("STEP2");
   }   

   if(POS_CUR_HS == 2) {
      setSPIValue(23);    //00010111 CH A enabled, polarity=LOW. CH B disabled (Current=550mA).  --current step
      setSPIValue(58);    //00111010 CH A disabled. CH B enabled, polarity=LOW (Current=550mA). --next step
      setSPIValue(60);    //00111100 CH A disabled. CH B enabled, polarity=LOW (Current=60mA).  --park
      Serial.print("STEP3"); 
   }   

   if(POS_CUR_HS == 1) { 
      setSPIValue(58);    //00111010 CH A disabled. CH B enabled, polarity=LOW (Current=550mA).   --current step
      setSPIValue(31);    //00011111 CH A enabled, polarity=HIGH (Current=550mA). CH B disabled. --next step
      setSPIValue(47);    //00101111 CH A enabled, polarity=HIGH (Current=60mA). CH B disabled.  --park      
      Serial.print("STEP4"); 
   }      

      if(POS_CUR_HS == 0) POS_CUR_HS=3; else POS_CUR_HS -=1;
      
      Serial.print(" POS_CUR_HS=");Serial.print(POS_CUR_HS); 
      POS_CUR -= POS_STEP_HS;
      Serial.print(" POS_CUR=");Serial.println(POS_CUR);
      delay(DELAY_L);
   }
}

void readPOS_CUR(int ADDR) {
//Reads a byte from the EEPROM. Locations that have never been written to have the value of 255. 

  //Serial.println("Reading current position from internal EEPROM!"); 
  POS_CUR_SAVED = EEPROM.read(ADDR); 
  Serial.print("Reading DONE! Current position: ");Serial.println(POS_CUR_SAVED);
}

void writePOS_CUR(int ADDR, int VAL) {
//Write a byte to the EEPROM. The value is written only if differs from the one already saved at the same address. 

  //Serial.print("Writing current positon to internal EEPROM: "); Serial.println(POS_CUR);
  EEPROM.update(ADDR, VAL);
  Serial.println("Writing DONE!");
}

Video Demo #1 - Turning On/Off screen by ignition, power off delay Timer. Saving screen last position to internal memory (EEPROM)


Video Demo #2 - Closing screen manually. Saving screen last position to internal memory (EEPROM). Restoring last screen position from internal memory, Manually Opening screen.


Video Demo #3 - Using Step Open and Step Close button. Saving screen last position to internal memory (EEPROM). Restoring last screen position from internal memory.


Android applications (for customization, automation, power saving etc.):
1. Tasker
2. Gravity screen
3. Apex Launcher
4. Ultimate Rotation Control
5. Slider Widget (for Volume and Brightness)
Last edited by js_online on Fri Jan 01, 2016 8:16 pm, edited 13 times in total.

js_online
Newbie
Newbie
Posts: 25
Joined: Mon May 18, 2015 11:49 pm

Re: E85 / E86 BMW Z4 – Android tablet integration - INCOMPLE

Post by js_online » Tue May 19, 2015 8:23 pm

Transmitting video from board computer (MK4 without video module) to Integrated Tablet

1. Extracting sync from Green and converting RGsB video to composite
LM1881 Video Sync Separator is used to extract Sync from green (LM1881 datasheet).
LM1881 on picture below is soldered to Ambery 15khz RGB to Composite converter.
This converter delivers the most stable picture in NTSC mode.
Soldering LM1881 is described in more details in this article.

Image

Added timer relay to pass video green from ambery to LM1881 pin 2 few seconds later to get perfect sync. Delay is adjustable by trimmer on timer relay (timer relay pinning: + - are 12v from ignition, COM and NO are green from ambery and LM1881 pin 2 composite video in)

Image

2. Transmitting video to tablet
WiFi Video transmitter is used to deliver video from Ambery converter to Tablet.
On Tablet "WiFi AVIN" app is installed. "Tasker" app is used together with "WiFi Connect" to connect to video transmitter wireless network in the moment "WiFi AVIN" app is launched, and to disconnect from video transmitter wireless network after "WiFi AVIN" app is closed. Video transmitter wireless network is not set to "Autoconnect" in tablet Wi-Fi settings.

Image

3. Complete setup:
Image

Pin assignments at plug connector X18802 (white plug):
Pin - Description
1 - Video signal Navigation signal red - Video module or Navigation system --> to Ambery Video In RED, pin1
2 - Shield - Video module or Navigation system --> to Ambery Video In GND, pin6
3 - Video signal Navigation signal green - Video module or Navigation system --> to Ambery Video In GREEN, pin2 and LM1881 Composite Video In, pin 2
4 - Shield - Video module or Navigation system --> to Ambery Video In GND, pin7
5 - Video signal Navigation signal blue - Video module or Navigation system --> to Ambery Video In BLUE, pin3
6 - Shield - Video module or Navigation system --> to Ambery Video In GND, pin8
7 - LCD ground from video module/navigation control unit - Video module or Navigation system --> Not used in current setup
8 - Terminal 30 - ?Fuse F49? --> 12V ACC connected to Timer Input +12V, Timer output is used by all consumers (Tablet, Arduino, Motor supply etc.). Red wire on picture near X18802 white socket is +12V IGN (ignition). This wire is used as Timer Activator. This red wire is also linked to +12V Relay Ignition (12VRI) (see detailed Arduino picture in post above).
9 - Ground - Ground point --> GND (Timer Input - GND)
11 - K-bus signal - K-bus connector --> Not used in current setup
Pins 10, 12-18 are not used in X18802.

4. BC on tablet
Image

4. Screenshots from Android tablet
Image

Image

Image

Image

Currently experiencing 2 issues:
1. Right side of image is cut little bit (not critical)
2. Important: Green video signal should be passed to LM1881 pin 2 from Amebry after small delay (after 1-2secs). Otherwise black screen. It begins work if PAL-NSTC mode is switched, but main reason is delay. SOLVED. See info about timer relay with delayed on above.
Last edited by js_online on Fri Jun 12, 2015 11:46 pm, edited 11 times in total.

Post Reply