Pages

2011-05-19

Temperature sensors characteristics

 Sensor
 Temperature
range,°C
 Accuracy
in °C
 Cost
 Robustness
Thermocouple -270 to +2600 1
 Low
 Very high
RTD -200 to +600 0.2
 Medium
 High
Thermistor -50to +200 0.2
 Low
 Medium
Integrated circuit -40 to +125
 1
 Low
Low


2011-05-12

HD44780 LCD: Pin Configuration of the HD44780 LCD Module

HD44780 is one of the most popular LCD controllers used in many LCD modules in industrial
and commercial applications and also by hobbyists. The module is monochrome and
comes in different shapes and sizes. Modules with character lengths of 8, 16, 20, 24, 32, and
40 can be selected. Depending on the model chosen, the display provides a 14-pin or a 16-pin
connector to interface to the external world. Table 4.15 shows the pin configuration and pin
functions of a typical 14-pin LCD.

VSS is the 0 V supply or ground. VDD pin should be connected to the positive supply. Although
the manufacturers specify a 5-V DC supply, the modules will usually work with as low as 3 V
or as high as 6 V.
Pin 3 is named as VEE, and this is the contrast control pin. This pin is used to adjust the contrast
of the display and it should be connected to a DC supply. A potentiometer is usually
connected to the power supply with its wiper arm connected to this pin and the other leg of
the potentiometer connected to the ground. This way, the voltage at the VEE pin and hence the
contrast of the display can be adjusted as desired.


Pin 4 is the Register Select (RS), and when this pin is LOW, data transferred to the LCD is treated
as commands. When RS is HIGH, character data can be transferred to and from the module.

 Pin 5 is the Read/Write (R/W) pin. This pin is pulled LOW to write commands or character
data to the LCD module. When this pin is HIGH, character data or status information can be
read from the module.

Pin 6 is the Enable (EN) pin that is used to initiate the transfer of commands or data between
the module and the microcontroller. When writing to the display, data is transferred only on
the HIGH to LOW transition of this pin. When reading from the display, data becomes available
after the LOW to HIGH transition of the enable pin, and this data remains valid as long
as the enable pin is at logic HIGH.

Pins 7–14 are the eight data bus lines (D0–D7). Data can be transferred between the microcontroller
and the LCD module either using a single, 8-bit byte or as two, 4-bit nibbles. In the
latter case, only the upper four data lines (D4–D7) are used. The 4-bit mode has the advantage
that fewer I/O lines are required to communicate with the LCD.

1 VSS Ground
2 VDD +ve supply
3 VEE Contrast
4 RS Register select
5 R/W Read/write
6 EN Enable
7 D0 Data bit 0
8 D1 Data bit 1
9 D2 Data bit 2
10 D3 Data bit 3
11 D4 Data bit 4
12 D5 Data bit 5
13 D6 Data bit 6
14 D7 Data bit 7

2011-05-10

SDCard: Standard SD Card Pin Configuration


SD Mode
1 CD/DAT3 Card detect/Data line
2 CMD Command response
3 Vss/Ground
4 Vdd Supply voltage
5 CLK
6 Vss/Ground
7 DAT0 Data line
8 DAT1 Data line
9 DAT2 Data line

SPI Mode
1 Chip select
2 Data in
3 Vss
4 Vd
5 CLK
6 Vss
7 Data out
8 Reserved
9 Reserved

2011-05-05

Microchip PIC: Usting Timer 1 in Capture Mode

The hardware and software in this memo comprise an engine control monitor and alarm. The purpose is to monitor the tachometer signals from an engine. If the period pf the pulses drop below 1ms, the engine is running too fast and a red LED lights up for alarm.

We relies on the capture interrupt event to do all of the work. Following are the steps its is executing:
  • Read capture signal and store the result as end_time. CCP_I is a CCS PIC compiler variable that is provided as way to read the 16-bits capture register;
  • Using end_time a a previously stored beginning Timer 1 count (start_time), the actual period of was is calculated in timer ticks. The Timer 1 overflow interrupt value is used to account for any counter overflow that may have taken place during the measurement period. The calculation for the number of tick is:
Pulse_ticks = overflow_count*0x10000-start_time+end_time
  •  Comparing the actual pulse_ticks to 2500 to see if the engine is running too fast. The limit is when actual time of the waveform's periode is less than 1ms, inditcating a high engine spped problem. The 2500 limit was calculated this way:
1ms/(1/(4 MHz/4)) = 2500
  • Adjusting the output LED according to the current reading;
  • Finally, saving end_time for the current pulse as start_time for the newt pulse and clearing the overflow_count for the next pulse calculation.
Source code example:

2011-04-27

Microchip PIC: Using TIMER0

In this memo Timer 0 is operated in 8-bit mode. The time for an interrupt is given by:


where Prescaler is the selected prescaler value, and TMR0L is the value loaded into timer register TMR0L to generate timer interrupts every Time period.

In our application the clock frequency is 4MHz, that is, clock period = 0.25µs, and Time = 5ms. Selecting a prescaler value of 32, the number to be loaded into TMR0Lcan be calculated as follows:
Thus, TMR0L should be loaded with 100. The value to be loaded into TMR0 control register T0CON can then be found as:
Thus, T0CON register should be loaded with hexadecimal 0xC4. The next register to be configured is the interrupt control register INTCON, where we will disable priority based interrupts and enable the global interrupts and TMR0 interrupts:
Taking the don’t-care entries (X) as 0, the hexadecimal value to be loaded intoregister INTCON is 0xA0.

When an interrupt occurs, the program automatically jumps to the interrupt service routine. Inside this routine we have to reload register TMR0L, reenable the TMR0 interrupts, and clear the TMR0 interrupt flag bit. Setting INTCON register to 0x20 reenables the TMR0 interrupts and at the same time clears the TMR0 interrupt flag.

The operations to be performed can thus be summarized as follows:
In the main program:
  • Load TMR0L with 100
  • Set T0CON to 0xC4
  • Set INTCON to 0xA0
  • Increment the counter with 1-second delays
In the interrupt service routine:
  • Re-load TMR0L to 100
  • Refresh displays
  • Set INTCON to 0x20 (reenable TMR0 interrupts and clear timer interrupt flag)
Source code example:

      2011-04-08

      DotNet: Using Sockets in C#

      • Using TcpListener for creating a TCP server:
      using System;
      using System.Threading;
      using System.Net;
      using System.Net.Sockets;
      using System.IO;
      private Socket connection; // Socket for accepting a connection
      private Thread readThread; // Thread for processing incoming messages
      private NetworkStream socketStream; // network data stream
      private BinaryWriter writer; // facilitates writing to the stream
      private BinaryReader reader; // facilitates reading from the stream
      readThread = new Thread( new ThreadStart( RunServer ) );
      readThread.Start();
      public void RunServer()
      {

      TcpListener listener; 
      // Step 1: create TcpListenerIPAddress local = IPAddress.Parse( "127.0.0.1" );listener = new TcpListener( local, 50000 ); 
      // Step 2: TcpListener waits for connection requestlistener.Start(); 
      // Step 3: establish connection upon client requestwhile ( true ){
      // accept an incoming connectionconnection = listener.AcceptSocket(); 
      // create NetworkStream object associated with socketsocketStream = new NetworkStream( connection ); 
      // create objects for transferring data across streamwriter = new BinaryWriter( socketStream );reader = new BinaryReader( socketStream ); 
      // Step 4: read string data sent from client 

      // Step 5: close connectionwriter.Close();reader.Close();socketStream.Close();connection.Close();
      }
      }






      2011-03-31

      SQL Server: DB Restore

      • Restoring a DB:
      RESTORE DATABASE AdventureWorks
      FROM AdWorksDevice
      WITH RECOVERY
      • Restoring Differential Backups in Simple Recovery Mode
      RESTORE DATABASE AdventureWorks
      FROM DISK='D:\SQLBackups\AWFull.bak'
      WITH NORECOVERY -- We aren't done with our Restore process
       Then
      RESTORE DATABASE AdventureWorks
      FROM DISK='D:\SQLBackups\AWDiff.bak'
      WITH NORECOVERY
      Finally
      RESTORE DATABASE AdventureWorks
      WITH RECOVERY

      SQL Server: DB Backup - Part 2

      • Creating a Backup Device
      EXEC sp_adddumpdevice @devtype='disk',
      @logicalname='AWBackup',
      @physicalname='D:\backup\AWBackup1.bak'

      EXEC sp_adddumpdevice @devtype='tape',
      @logicalname='AWTapeBackup',
      @physicalname='\\.\tape0'
      • Removing a Backup Device
      Sp_dropdevice @logicalname='AWBackup'  
      This command only removes the backup device definition—it doesn’t automatically delete the files contained therein. Use this command to remove all the files in addition tothe device definition: 
      Sp_dropdevice @logicalname='AWBackup', @devfile='DELFILE'
      • Managing Backup Devices
      BACKUP DATABASE AdventureWorks
      TO AWBackup
      WITH EXPIREDATE = '12/05/2007'
      or
      BACKUP DATABASE AdventureWorks
      TO AWBackup
      WITH RETAINDAYS=7
      The first option causes that specific backup to be removed after December 5, 2007at midnight. The second option forces that particular backup to be
      removed after seven days have passed.

      2011-03-10

      SQL Server: DB Backup

      • Transaction log backup:
      USE [master]
      BACKUP LOG [AdventureWorks]
      TO DISK = N'C:\AdventureWorks_LOG.TRN' WITH NOFORMAT,
      NOINIT,
      NAME = N'AdventureWorks-
      Transaction log backup.BAK'
      GO
      • Backup data file:
      USE [master]
      BACKUP DATABASE [AdventureWorks]
      TO DISK = N'C:\AdventureWorks_DATAS.BAK' WITH NOFORMAT,
      NOINIT,
      NAME = N'AdventureWorks-Backup data file.BAK'
      GO
      • Differential Backup
       In this example, AW.dif contains all the changes made since the last full backup. You can use it during the restore process in addition to transaction log backups. First, restore the full backup, then restore the latest differential, then restore any transaction logs that
      follow it.
      BACKUP DATABASE Adventureworks TO DISK = 'D:\data\AW.dif' WITH DIFFERENTIAL,INIT
      • Mirrored Backup (SQL Server 2005)
      BACKUP DATABASE AdventureWorks TO DISK='D:\data\AW.bak
      MIRROR TO DISK = 'E:\data\AW.bak'
      MIRROR TO DISK = 'F:\data\AW.bak'
      WITH INIT,CHECKSUM,CONTINUE_ON_ERROR
      •  BATCH Script
      sqlcmd
      -S MYSERVER\SQLEXPRESSINSTANCENAME -U sa -P MYPASSWORD
      -Q "BACKUP DATABASE [AdventureWorks] TO DISK = N'C:\AdventureWorks_DATAS.BAK'
      WITH NOFORMAT, NOINIT,
      NAME = N'AdventureWorks-Backup.BAK'"
      Or
      SET J=%date:~-10,2%
      SET A=%date:~-4%
      SET M=%date:~-7,2%
      SET H=%time:~0,2%
      SET MN=%time:~3,2%
      SET S=%time:~-5,2%

      IF "%time:~0,1%"==" " SET H=0%HEURE:~1,1%

      SET REPERTOIRE=C:\Repertoire_Sauvegarde\

      SET FICHIER=%REPERTOIRE%\Nom_de_mon_fichier_%J%_%M%_%A%_A_%H%_%MN%_%S%.bak

      IF NOT exist "%REPERTOIRE%" md "%REPERTOIRE%"

      cd C:\Program Files\Microsoft SQL Server\90\Tools\Binn

      sqlcmd -S NOM_DU_SERVEUR\SQLEXPRESS -Q "BACKUP DATABASE NOM_DE_LA BASE TO DISK = N'%FICHIER%' WITH INIT, NAME = N'Sauvegarde automatique de la base de données', STATS = 1" 

      2011-03-08

      C++: Using Inserter Iterators

      An inserter iterator is an iterator that can add new elements to the sequence containers vector < T > ,
      deque < T > , and list < T > . There are three templates that create inserter iterators:
      •  back_insert_iterator < T > — inserts elements at the end of a container of type T . The container
        must provide the push_back() function for this to work.
      • front_insert_iterator < T > — inserts elements at the beginning of a container of type T .
        This depends on push_front() being available for the container.
      • insert_iterator < T > — inserts elements starting at a specifi ed position within a container
        of type T . This requires that the container has an insert() function that accepts an iterator
        as the fi rst argument, and an item to be inserted as the second argument.
      The constructors for the fi rst two types of inserter iterators expect a single argument specifying the
      container in which elements are to be inserted. For example:
      list < int > numbers;
      front_insert_iterator < list < int > > iter(numbers);
      *iter = 99;  // front_inserter(numbers) = 99;
      The constructor for an insert_iterator < T > iterator requires two arguments:
      insert_iterator < vector < int > > iter_anywhere(numbers, numbers.begin());
      The second argument to the constructor is an iterator specifying where data is to be inserted — the
      start of the sequence, in this instance. You can use this iterator in exactly the same way as
      the previous one. Here ’ s how you could insert a series of values into a vector container using this iterator:
      for(int i = 0 ; i < 100 ; i++)
      *iter_anywhere = i + 1;
      This loop inserts the values from 1 to 100 in the numbers container at the beginning. After
      executing this, the fi rst 100 elements will be 100 , 99 , and so on, through to 1 .
      You could also use the inserter() function to achieve the same result:
      for(int i = 0 ; i < 100 ; i++)
      inserter(numbers, numbers.begin()) = i + 1;
      The first argument is the container, and the second is an iterator identifying the
      position where data is to be inserted. The inserter iterators can be used in conjunction with
      the copy() algorithm in a particularly useful way. Here ’ s how you could read values from cin and
      transfer them to a list < T > container:
      list < double > values;
      cout < < "Enter a series of values separated by spaces"
      < < " followed by Ctrl+Z or a letter to end:" < < endl;
      istream_iterator < double > input(cin), input_end;
      copy(input, input_end, back_inserter < list < double > > (values));

      2011-02-21

      C++: Prevent the compiler from doing implicit type conversion

      Use the keyword explicit on the constructor. Forcing explicit conversions is usefull
      to make the programmers aware of the conversion. This is especially interesting for
      time consuming conversions.
      struct A
      {
      A() {}
      };

      struct B
      {
      B() {}
      B(const A &a) {}
      };

      struct C
      {
      C() {}
      explicit C(const A &a) {}
      };

      void fb(B b) { /* ... */ }

      void fc(C c) { /* ... */ }

      void function()
      {
      A a;
      B b;
      C c;
      fb(a); // ok, conversion is implicit
      fc(a); // error
      fc(C(a)); // ok, conversion is explicit
      }

      2011-02-07

      C++ MFC: Catching Windows Events

      •     LRESULT DefWindowProc(UINT message, WPARAM wParam, LPARAM lParam)
          {
              switch(message)
              {
                  case WM_COPY:
                  case WM_PASTE:
                      break;
                  default:
                      return
      __super::DefWindowProc(message, wParam, lParam);
                      break;
              }
              return 0;
          }

      •     LRESULT WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
          {
              switch(message)
              {
                  case WM_COPY:
                  case WM_PASTE:
                      break;
                  default:
                      return
      __super::WindowProc(message, wParam, lParam);
                      break;
              }
              return 0;
          }

      •     BOOL PreTranslateMessage(MSG* pMsg)
          {
              if (pMsg->message==258 && LOWORD(pMsg->wParam)==22)
              //if (pMsg->message == WM_COPY || pMsg->message == WM_PASTE)
              {
                  // handle the paste however you want to here
                  pMsg->wParam=0;
                  pMsg->message=0;
                  return TRUE;
              }
              return
      __super::PreTranslateMessage(pMsg);
          }

      •     BOOL OnCommand(WPARAM wParam, LPARAM lParam)
          {
              switch (LOWORD(wParam))
              {
                  case WM_CUT:
                  case WM_COPY:
                  case WM_PASTE:
                      return TRUE;
                      break;
                  default:
                      return __super::OnCommand(wParam, lParam);
                      break;
              }   
          }