Volume controle

Controle the device volume from within your VB20xx application.
Tested with Friendlyarm Mini2440 running on win CE6.0 and Visual Basic 2008.

 Public Class Form1

    Public Declare Function waveOutSetVolume Lib "coredll.dll" (ByVal hwo As IntPtr, ByVal dwVolume As Long) As Integer
    Public Declare Function waveOutGetVolume Lib "coredll.dll" (ByVal hwo As IntPtr, ByRef pdwVolume As Long) As Integer

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        waveOutSetVolume(0, 40000) 'Sets the volume to 40000
    End Sub

    Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
        Dim i As Long
        waveOutGetVolume(0, i)
        Debug.WriteLine("Current volume setting: " & i)
    End Sub
End Class
How to replace Xbox360 Benq lens

Required tools: Philips screwdriver 00 & 0 ,flat 1 and soldering iron.

The Benq VAD6038 drive is used in some xbox360 units. The quality of this drive various very much due the lens unit. Some unit last forever, other break down within a month. If you have warranty bring it back to M$. Are there reasons that you can’t bring it back, we have here a Diy tutorial for you. New lens units are wide spread available on the net and will cost you between €20,- and €30,-.

The laser or also called lens is a very sensitive device for mechanical stress and static charge. Don’t use force and keep yourself discharged with a wristband. Don’t touch the optical lens with your fingers.
It’s not a difficult job, but if you don’t have experience in repairing fine mechanical component don’t do it and never blame me if you mess it up.
Opening the Xbox360 and removing the drive are not explained here, there are enough tutorials available on the net.

Lets get started
The tray must be open to get access to the lens, you can choose to open the tray by pushing the tray open button when your xbox is still in 1 piece or you can open later the tray by hand.

Step 1 Step 2 Step 3

First remove the 4 screws at the bottom (step 1) of the drive and cut the warranty seal . Now you can take the drive apart by removing the top and bottom metal case.
If you didn’t open the tray before then it’s time to do that now. On the front of the drive is just below the tray a small rubber wheel. It’s difficult to see on the picture (step 2) but you will see it. Turn the wheel gently to the right, the laser unit will be lowered and the tray will open slowly. If the tray is about 2cm open you can pull gently on the tray to fasten the opening process.
There it is, the lens that gives you all that problems(step 3).
To keep the rest of this tutorial clear put your drive just like I did, with the tray to the left.
Remove now the 2 clamps as marked in step 3, one in the upper right corner and the other in the lower left corner.

Step 4 Step 5 Step 6

Disconnect now the flat cable from the lens unit (keep yourself discharged !) by gently push the lock (step 4) to the right with a small screwdriver. Repeat this for the other lock, the flat cable will now come very easy lose (step 5).
Let’s remove now the driving unit by losing the screw and lifting it(step 6). Watch out that the spring will not jump away.

Step 7 Step 8 Step 9

Now we can remove the slide axles and the lens unit. First we must remove the back axle by lifting it up at the right side and push it 5mm to the north and then slide out the axle to the east(step 7). The clamp is the upper left corner (step 8) is still pressing on the axle so you feel a little bit resistance.
The lens unit can now easy be removed by lifting it in a 45 deg angle. Lift now the front axle up on the left side and pull the axle with the lens unit out to the west.

Disassembling is now finished, let’s put it back together.

Step 10 Step 11 Step 12

The lens is shipped with a short circuit to protect it against static electricity. Is the clump solder show on the picture(step 10), this must be removed otherwise the lens won’t work. It’s the best to remove the clump as finale step thus after connecting the flat cable.
Slide the lens unit on the axle and insert the axle angled under the clamp in the lower right corner to the east (step11). Hook the axle under the bracket at the left side and then place the clamp back in the lower left corner (step 12). The front axle is now finished.

Step 13 Step 14 Step 15

Let’s put back the back axle. This is the most difficult part to do, or maybe only to explain ?
Slide the axle from the east to the west trough the lens unit, then under the clamp in the upper left corner (Step 13). The axle will now hit a metal bracket, lift it gentle up so it can pass it (step 14). Sliding the axle further to the west it will meet a screw, lift it gently up again (step 15) to get it over. Almost finished.

Step 16 Step 17

Before we continue its important that the laser unit is now to the left of the pcb(printed circuit board) shown in (step 16) with the red line, so slide the lens unit to the east. Now we can place the back axle back on his final position by hooking it under the metal bracket in the upper right corner and placing back the clamp(Step 16). The lens unit should now slide over the axles, but due the pcb it slides only a few mm to the right and left. Place now back the driving unit by clicking it on the screw axle and screwing it to the lens unit. Connect the flat cable back to the lens unit by opening the clamp (step 17) and insert the cable. Discharge yourself before touching the cable. The flat cable should slide very easy in the connector. Close now the clamps and check of the cable is still inserted far enough.
Now remove carefully the solder clump as show in (step 10) with the soldering iron.
Place back the top and bottom metal case, screw it together with the 4 screws (step1) and you are ready.

Happy gaming.

I2C Eeprom programmer

What is it?
It’s an Eeprom programmer controlled by Bascom Avr and is capable of programming in circuit Eeprom’s up to 512Kb. Standard Intel Hex8 file is required.
Extended Linear Address Records for Eeprom’s bigger then 16bits addresses is not (yet) supported, but easy to implant.
I wrote it primary for my other application note RC2 sound / voice playback to upload the sound files to the i2c Eeprom.
Special thanks to Mark from Mcselec how has added in the vb6 an asm to intelhex routine so Atmel studio is not needed anymore.

Required tools
For the Pc side there’s an upload program that sends the Intel Hex file to the AVR.
Program is written in VB6-Sp6, source code is also available.

The code
Code is written and tested in Bascom license.
Download the Bascom source code here


'                       I2C Eeprom programmer
'Upload your Eeprom files through serial connection in the I2c Eeprom
'       No extended address supported, so max 512K Eeprom
'     By Evert Dekker 2008 i2cprogrammer@Evertdekker dotje com
'                Created with Bascom-Avr:

$regfile = "m128def.DAT"
$crystal = 16000000
$baud = 19200
$hwstack = 70
$swstack = 70
$framesize = 60

$lib "I2C_TWI.LBX"                                          'Setting up i2c hardware bus
Config Twi = 400000                                         'Hardware i2c bus speed
Config Scl = Portd.0                                        'TWI (i2c) ports on the Mega128
Config Sda = Portd.1
Const Addressw = &B10100000                                 'slave write address eeprom
Const Addressr = &B10100001                                 'slave read address eeprom

Dim Startbyte As Byte , Instring As String * 45 , Complete As Bit
Dim Temp As Byte , Temps As String * 3
Dim Bytecount As Byte , Addresshigh As Byte , Addresslow As Byte , Recordtype As Byte , Databyte(16) As Byte , Checksm As Byte
Dim Lus As Byte , Pos As Byte , Checksum_calc As Byte , Checksum_error As Bit

Enable Urxc
Enable Interrupts
On Urxc Bytereceived_isr

'=== Main  ===
If Complete = 1 Then                                        'Wait until the buffer is filled with one line
  Gosub Process_buffer                                      'Process the buffer
  Gosub Calculate_checksum                                  'Calculate the cheksum
     If Recordtype = &H01 Then                              'EOF finished, send a ACK and return
      Print "Y";
       If Checksum_error = 0 Then                           'If there's no error continue
         Select Case Recordtype                             'do something with the recordtype
            Case &H00                                       'Data byte
                Gosub Prog_eeprom                           'Recordtype &H00 = databyte, so lets programm the Eeprom
            Case &H02                                       'Extended Linear Address Records, not (yet) supported
         End Select
       Print "Y";                                           'Checksum ok, send a ACK
       Print "Z";                                           'Checksum error send a Nack
     End If
    End If
  Complete = 0 : Instring = ""                              'Reset the variable
End If

'=== Subroutines ===
    I2cstart                                                'start condition
    I2cwbyte Addressw                                       'slave address
    I2cwbyte Addresshigh                                    'Highaddress of EEPROM
    I2cwbyte Addresslow                                     'Lowaddress of EEPROM
       For Lus = 1 To Bytecount
         I2cwbyte Databyte(lus)                             'value to write
       Next Lus
    I2cstop                                                 'stop condition
    Waitms 10                                               'wait for 10 milliseconds

Temps = Mid(instring , 1 , 2) : Bytecount = Hexval(temps)   'Read the numbers of bytes
Temps = Mid(instring , 3 , 2) : Addresshigh = Hexval(temps) 'Read the high adress
Temps = Mid(instring , 5 , 2) : Addresslow = Hexval(temps)  'Read the low adress
Temps = Mid(instring , 7 , 2) : Recordtype = Hexval(temps)  'Read the recordtype
For Lus = 1 To Bytecount                                    'Process the number of data bytes
      Pos = Lus * 2
      Pos = Pos + 7
      Temps = Mid(instring , Pos , 2) : Databyte(lus) = Hexval(temps)       'Read the databytes
Next Lus
Pos = Pos + 2                                               'read the last byte
Temps = Mid(instring , Pos , 2) : Checksm = Hexval(temps)   'Read checksum

Temp = 0                                                    'Add up all the databytes
Temp = Temp + Bytecount
Temp = Temp + Addresshigh
Temp = Temp + Addresslow
Temp = Temp + Recordtype
   For Lus = 1 To Bytecount
    Temp = Temp + Databyte(lus)
   Next Lus
Checksum_calc = 256 - Temp                                  'taking its two's complement
   If Checksum_calc <> Checksm Then                         'Compare it with the readed value
    Checksum_error = 1
    Checksum_error = 0
   End If

Temp = Udr                                                  'get the binary value that came across
If Temp = &H0D Then                                         'Received CR = end of line, line complete
 If Len(instring) < 8 Then                                  'To short, startover again
   Complete = 0
   Instring = ""
   Complete = 1                                             'String is complete set the flag
 End If
End If

If Startbyte = &H3A Then                                    'we have previously received the start byte and this is now data
  If Temp > &H0F Then                                       'Add incoming data to buffer
     Instring = Instring + Chr(temp)
    If Len(instring) > 45 Then Instring = ""                'String is to long, reset and startover again
 End If
End If

If Temp = &H3A Then                                         'if we received an : then its the beginning of an new line.
   Startbyte = Temp
   Complete = 0
   Instring = ""
End If
RC2 Decoder sound / voice playback

What is it?

It’s an very simple, only 2 resistors and 1 condensator, sound playback. And it sounds amazing good, check the TheFinalResult.mp3 file.This is based on an article by Mariano Barron in the Circuit Cellar #180 July 2005. Due the copyright I can’t publish the article here. You can buy your copy at the Circuit Cellar website.
The software we need to encode the WAV files is free available from the Circuit cellar ftp server, in this file there is also a short description how it works.With the Rc Sound Encoder software we compress the WAV to RC2 coding. This coding will be stored in eeprom and played back with this simple “Soundcard” Every sample requires only 1 bit, so for 1 second 44,1kHz sound we need 2726 Bytes storage space. It’s not much but for most MCU too much to store in the flash or internal eeprom. Therefore we store the sound samples in an external i2c eeprom.



Schematic is very simple. I’m using a Mega128 running on 16MHz. I2c eeprom (24c256) is connected with the hardware i2c (scl/sda). Software i2c will not work, this is to slow, maybe it will work with 22050hz samples but I didn’t try that.In the upper right corner we have the Rc2 decoder and optional an low pass filter and a simple amplifier.

Even the timer isr calculation is simple Crystal/prescaler/sample rate = 16000000/1/44100 = 362 = &H016A .
If you like to use an other sample rate or crystal you need to recalculate the timer.

The document RC2-Howto.pdf describes how to make your own Eeprom file with your sound or speech, this document can be found in the Zip file. The zip contains also the used WAV files, the ready to run demo Eeprom hex file and some ASM files.

In all the routines are 16bits addressing used, therefore it’s not possible to use Eeprom’s larger then 512KB. If you change the routines you can use more then one 512KB i2c eeprom (you can hook up 4 to 1 i2c bus), but the RC-coder software uses also 16bits addresses and that’s something that we cannot change.

Required tools


The code
Code is written and tested in Bascom license.

'                      R2C Decoder voice playback
'     Playback sound and voice with very simple hardware 2xR 1xC
'        By Evert Dekker 2008 R2CDecoder@Evertdekker dotje com
'                   Created with Bascom-Avr:

$regfile = "m128def.DAT"
$crystal = 16000000
$baud = 19200
$hwstack = 50
$swstack = 50
$framesize = 40

$lib "I2C_TWI.LBX"                                          'Setting up i2c hardware bus
Config Twi = 400000                                         'Hardware i2c bus speed
Config Scl = Portd.0                                        'TWI (i2c) ports on the Mega128
Config Sda = Portd.1
Const Addressw = &B10100000                                 'slave write address eeprom
Const Addressr = &B10100001                                 'slave read address eeprom

Vp1 Alias Porta.1                                           'Voice pin 1
Vp2 Alias Porta.2                                           'Voice pin 2
Config Porta.1 = Output
Config Porta.2 = Output

Config Timer1 = Timer , Prescale = 1 , Compare A = Set , Clear Timer = 1       'Setting up the timer
Compare1a = &H016A                                          'Timer1 comparator
Enable Interrupts
Enable Compare1a
On Compare1a Timer1_int
Stop Timer1                                                 'Stop the timer, not yet needed

'==== Declaration
Declare Sub Read_eeprom_word(byval Adress As Word , Valueword As Word)
Declare Sub Playsample(byval Sample As Byte)
Declare Sub Read_eeprom_index

Dim Samples As Word , Start_byte(10) As Word , Lenght(10) As Word       'If you have more then 10 voices programmed, then incr this here.
Dim Bytetodo As Word , Outbyte As Byte
Dim Temp As Byte , Tempw As Word , Lus As Byte
Dim Bitcount As Byte , Tempadress2 As Byte

'=== Main ===
Read_eeprom_index                                           'Read the eeprom index because we need to know number of samples, startadress and lenght
Print Samples ; " Samples present in the eeprom"
For Lus = 1 To Samples
 Print Lus ; "e sample start at eeprom adress: &H" ; Hex(start_byte(lus)) ; " is &H" ; Hex(lenght(lus)) ; " bytes long."
Next For
Wait 3

For Lus = 1 To Samples
 Playsample Lus
Wait 1
Next Lus


'=== Sub routines ===
Sub Playsample(byval Sample As Byte)
Bytetodo = Lenght(sample)                                   'Number of bytes to be processed
Tempw = Start_byte(sample) * 2                              'Index is in word, need now bytes so *2
I2cstart                                                    'Generate start
I2cwbyte Addressw
Tempadress2 = High(tempw)                                   'High(adress)
I2cwbyte Tempadress2                                        'highbyte adress of EEPROM
Tempadress2 = Low(tempw)
I2cwbyte Tempadress2                                        'lowbyte adress of EEPROM
I2cstart                                                    'repeated start
I2cwbyte Addressr
Start Timer1                                                'Start the timer and therefore the playback
If Bitcount = 7 Then                                        '1 byte processed
   I2crbyte Outbyte , Ack                                   'Read byte from eeprom
    Decr Bytetodo                                           '1 byte less todo
    Bitcount = 0                                            'Reset bits processed
End If
Loop Until Bytetodo = 0                                     'Do until all the bytes from the sample are processed
Stop Timer1                                                 'Ready stop the timer
I2crbyte Temp , Nack                                        'read extra byte with Nack to finish the i2c bus
I2cstop                                                     'Stop i2c
Vp2 = 0 : Vp1 = 0                                           'Silence the voice pins
End Sub

Vp2 = Vp1                                                   'Voice pin2 is the previous setting of voice pin1
If Bitcount > 0 Then Shift Outbyte , Right , 1              'shift the bits out
Vp1 = Outbyte.0                                             'Set voice pin1
Incr Bitcount                                               'Next bit

Sub Read_eeprom_index                                       'Find the start adresse of each Voice. Adress is stored as word
      Read_eeprom_word 0 , Samples                          '1e Byte in the eeprom contens the number of programmed samples and is the low byte of the first sample
      Temp = Low(samples) : Temp = Temp -1                  '
      For Lus = 0 To Temp                                   'Loop the number of Samples found
          Tempw = Lus * 2                                   'Reading words, so steps 2
          Read_eeprom_word Tempw , Start_byte(lus + 1)      'Read the start adres of the samples
          Tempw = Start_byte(lus + 1)
          Tempw = Tempw * 2                                 'Reading words, so steps 2
          Read_eeprom_word Tempw , Lenght(lus + 1)          'Read the lenght of the sample from the eeprom
          Rotate Lenght(lus + 1) , Left , 8                 'Msb and Lsb are inverted so swap them
      Next Lus
End Sub

Sub Read_eeprom_word(byval Adress As Word , Valueword As Word)
   Local Tempadress As Byte , Valueh As Byte , Valuel As Byte,
   I2cstart                                                 'generate start
   I2cwbyte Addressw                                        'slave adsress
   Tempadress = High(adress)
   I2cwbyte Tempadress                                      'highbyte adress of EEPROM
   Tempadress = Low(adress)
   I2cwbyte Tempadress                                      'lowbyte adress of EEPROM
   I2cstart                                                 'repeated start
   I2cwbyte Addressr                                        'slave address (read)
   I2crbyte Valuel , Ack                                    'read byte
   I2crbyte Valueh , Nack
   I2cstop                                                  'generate stop
   Valueword = Makeint(valuel , Valueh)
End Sub


T-65 Upgrade


Back in the old days we had PTT, the dutch phone company. The only allowed phone to use was the one provided by the PTT. In the 80′ they allowed other brand of phones connected to there line, so the good old T-65 disappears to the garage.
Now the “retro” look is back in the interior design, so the T-65 is also trendy, but i wouldn’t work today anymore because it’s using puls dialing and modern pabx can only use tone dialing (DTMF). Cable, adsl modems and skype won’t work either with puls dialing.
On the net i found this simple schematic made by Frits k, it will upgrade the T-65 with DTMF and redial function. Check it out(sorry only dutch). Nice project to build.


Pcb back
Finished pcb
Pcb buildin
previous arrow
next arrow
Pcb back
Finished pcb
Pcb buildin
previous arrow
next arrow