Hack to the Future

A team of ASU students hacked a DeLorean to recreate the iconic movie scene
A team of ASU students hacked a DeLorean to recreate the iconic movie scene

A talented group of hackers thrilled participants of the Hardware Weekend hack-a-thon with their mods to a classic DeLorean DMC-12. Sponsor hackster.io provided the car in honor of the Hack to the Future themed event, which was hosted by Local Motors in Chandler. Special effects installed by the team included cool blue LED lighting throughout the car, and dual alcohol burners with electronic ignition. The complex lighting, fuel pump and ignition systems were controlled by a chipKIT uC32 and Motor Control Shield from Digilent.

The weekend event was a big success, with 16 teams competing for various prizes. There were several creative and impressive projects, but the DeLorean hack promised to be most dramatic. After a few test runs in the late afternoon, final adjustments were made to ensure an effective demo for the judges. The team took a much needed break, as the other presentations continued inside.

Finally, it time for the DeLorean demonstration. A crowd of spectators gathered as the hack was described in detail. Under cover of darkness, the DeLorean’s throaty engine roared to life. The signature gull wing doors closed, and the DMC-12 rumbled far down the lane and turned into position. There was a moment of anticipation, before the machine accelerated for its run past the crowd, spraying fire and leaving a long burning trail on the tarmac. During ignition, the cabin lighting flashed red to add that final touch.

Congratulations to the Smoke and Mirrors team from Arizona State University, including Cody Van Cleve, Frank Ross, Eric Person, Caleb Carlson, Josh Kosar, Deep Patel and Carly Thalman, for their excellent chipKIT-based hack and First Place win at the Hardware Weekend Series hack-a-thon.

VN:F [1.9.22_1171]
Rating: 10.0/10 (3 votes cast)
VN:F [1.9.22_1171]
Rating: +2 (from 2 votes)

How to Restore a chipKIT Bootloader

How to connect a PICkit 3 programmer, leaving the Power Jack and USB port accessible
How to connect a PICkit 3 programmer, leaving the Power Jack and USB port accessible

Did you know that chipKIT boards can also be used as generic embedded controllers? chipKIT-compatible boards can be programmed not only with MPIDE or UECIDE, but also in several other IDEs using programming languages such C, C++, Pascal or Basic. When using another IDE such as MPLAB X, the chipKIT bootloader may become erased or over-written, which is fine, if you plan to stick with that environment. However, if you want to use MPIDE or UECIDE again after your bootloader has been erased, you’ll need to restore the chipKIT bootloader. To do so, you can follow the Restore Your chipKIT Bootloader Guide with step-by-step instructions and lots of pictures. Knowing how to do this might save you from a massive headache ūüėČ

Good luck!

VN:F [1.9.22_1171]
Rating: 9.8/10 (4 votes cast)
VN:F [1.9.22_1171]
Rating: +1 (from 1 vote)

Webinar – Introducing the chipKIT Pi Expansion Board for the Raspberry Pi

Watch while Marc McComb of Microchip Technology provides an overview of the new chipKIT Pi Expansion Board for the Raspberry Pi¬ģ. The board was co-developed by element14 and Microchip to enable anyone to easily create 3V Arduino‚ĄĘ compatible applications for their Raspberry Pi, using a 32-bit, high-performance PIC32 MCU in a prototyping-friendly package. Marc, an admin of this site, manages the academic and chipKIT Embedded Platform programs for Microchip.

VN:F [1.9.22_1171]
Rating: 8.0/10 (5 votes cast)
VN:F [1.9.22_1171]
Rating: 0 (from 0 votes)

Serial Communication – I2C EEPROM using MPLAB X IDE

Overview:

In this project you will learn to use a basic functionality of chipKIT board, which is to use serial communication I2C bus to read and write values from EEPROM memory. I2C bus is a master slave bus, which communicates data from the processor on chipKIT board to other peripherals. More description on I2C communication can be found on the Wikipedia website and on EEPROM can be found here. The configuration is done though MPLAB X IDE.

Hardware Used:

To do the serial communication project, you require the following hardware devices.
  • chipKIT Uno 32
  • chipKIT Basic IO shield
  • PICkit¬ģ 3 In-Circuit Debugger/Programmer
  • USB cable
  • 6 pin header to connect chipKIT board and PICkit¬ģ 3

Reference:

The reference guide for each board, schematics and other resources are available on their individual homepages:

Procedure:

  1. Connect the hardware devices. The PICkit¬ģ 3 should be connected to the chipKIT Uno32 board through a suitable header and use the USB cable to connect the PICkit¬ģ 3 to your PC.
  2. Make sure that the jumper settings for JP4 on chipKIT Uno32 board is configured as SPI Slave Select input mode. You can find the jumper settings in chipKIT Uno32 board reference manual from the Digilent website. Also, ensure that the jumpers JP6/JP8 are configured to be used as I2C communication lines.
  3. Place the IO shield on top of the Uno32 board with a bit of a firm press.
  4. Once the hardware setup is made and¬†the device drivers are updated for PICkit¬ģ 3 on your computer, launch MPLAB X¬†(Start>All Programs>Microchip>MPLAB X IDE>MPLAB X IDE vx.xx¬†on Window¬ģ Machines).
  5. Create a new project through¬†File>New Project.¬†In the pop up new project window, select¬†Standalone Project¬†¬†under¬†Projects¬†¬†and click¬†Next.¬†Under¬†Family¬†scroll and select¬†32-bit MCUs (PIC32). Note the processor number from the chipKIT board’s reference manual and enter it under the¬†Device¬†¬†option. Click¬†Next.
  6. Select PICkit3 in the Hardware Tools, click Next. Select XC32 (v1.20) under Compiler Toolchains, click Next. Give a project name to create the project.
  7. In the Project tab on the left side of the MPLAB X IDE, right click on Source Files > New > C Main File.. and give a file name for main source code. Once the dot c file opens, select all the codes in the file and replace it with the codes below.
    #include 
    
    #pragma config FPLLMUL = MUL_20, FPLLIDIV = DIV_2, FPLLODIV = DIV_1, FWDTEN = OFF
    #pragma config POSCMOD = HS, FNOSC = PRIPLL, FPBDIV = DIV_1
    #define SYS_FREQ (80000000L)
    
    #define GetSystemClock()           (SYS_FREQ)
    #define GetPeripheralClock()       (SYS_FREQ/1)
    #define GetInstructionClock()      (SYS_FREQ)
    #define I2C_CLOCK_FREQ             5000
    
    // EEPROM Constants
    #define EEPROM_I2C_BUS              I2C1
    #define EEPROM_ADDRESS              0x50        // 0b1010000 Serial EEPROM address
    
    /*******************************************************************************
      Function:
        BOOL StartTransfer( BOOL restart )
    
      Summary:
        Starts (or restarts) a transfer to/from the EEPROM.
    
      Description:
        This routine starts (or restarts) a transfer to/from the EEPROM, waiting (in
        a blocking loop) until the start (or re-start) condition has completed.
    
      Precondition:
        The I2C module must have been initialized.
    
      Parameters:
        restart - If FALSE, send a "Start" condition
                - If TRUE, send a "Restart" condition
    
      Returns:
        TRUE    - If successful
        FALSE   - If a collision occured during Start signaling
    
      Example:
        
        StartTransfer(FALSE);
        
    
      Remarks:
        This is a blocking routine that waits for the bus to be idle and the Start
        (or Restart) signal to complete.
      *****************************************************************************/
    
    BOOL StartTransfer( BOOL restart )
    {
        I2C_STATUS  status;
    
        // Send the Start (or Restart) signal
        if(restart)
        {
            I2CRepeatStart(EEPROM_I2C_BUS);
        }
        else
        {
            // Wait for the bus to be idle, then start the transfer
            while( !I2CBusIsIdle(EEPROM_I2C_BUS) );
    
            if(I2CStart(EEPROM_I2C_BUS) != I2C_SUCCESS)
            {
                DBPRINTF("Error: Bus collision during transfer Start\n");
                return FALSE;
            }
        }
    
        // Wait for the signal to complete
        do
        {
            status = I2CGetStatus(EEPROM_I2C_BUS);
    
        } while ( !(status & I2C_START) );
    
        return TRUE;
    }
    
    /*******************************************************************************
      Function:
        BOOL TransmitOneByte( UINT8 data )
    
      Summary:
        This transmits one byte to the EEPROM.
    
      Description:
        This transmits one byte to the EEPROM, and reports errors for any bus
        collisions.
    
      Precondition:
        The transfer must have been previously started.
    
      Parameters:
        data    - Data byte to transmit
    
      Returns:
        TRUE    - Data was sent successfully
        FALSE   - A bus collision occured
    
      Example:
        
        TransmitOneByte(0xAA);
        
    
      Remarks:
        This is a blocking routine that waits for the transmission to complete.
      *****************************************************************************/
    
    BOOL TransmitOneByte( UINT8 data )
    {
        // Wait for the transmitter to be ready
        while(!I2CTransmitterIsReady(EEPROM_I2C_BUS));
    
        // Transmit the byte
        if(I2CSendByte(EEPROM_I2C_BUS, data) == I2C_MASTER_BUS_COLLISION)
        {
            DBPRINTF("Error: I2C Master Bus Collision\n");
            return FALSE;
        }
    
        // Wait for the transmission to finish
        while(!I2CTransmissionHasCompleted(EEPROM_I2C_BUS));
    
        return TRUE;
    }
    
    /*******************************************************************************
      Function:
        void StopTransfer( void )
    
      Summary:
        Stops a transfer to/from the EEPROM.
    
      Description:
        This routine Stops a transfer to/from the EEPROM, waiting (in a
        blocking loop) until the Stop condition has completed.
    
      Precondition:
        The I2C module must have been initialized & a transfer started.
    
      Parameters:
        None.
    
      Returns:
        None.
    
      Example:
        
        StopTransfer();
        
    
      Remarks:
        This is a blocking routine that waits for the Stop signal to complete.
      *****************************************************************************/
    
    void StopTransfer( void )
    {
        I2C_STATUS  status;
    
        // Send the Stop signal
        I2CStop(EEPROM_I2C_BUS);
    
        // Wait for the signal to complete
        do
        {
            status = I2CGetStatus(EEPROM_I2C_BUS);
    
        } while ( !(status & I2C_STOP) );
    }
    
    // ****************************************************************************
    // ****************************************************************************
    // Application Main Entry Point
    // ****************************************************************************
    // ****************************************************************************
    
    int main(void)
    {
        UINT8               i2cData[10];
        I2C_7_BIT_ADDRESS   SlaveAddress;
        int                 Index;
        int                 DataSz;
        UINT32              actualClock;
        BOOL                Acknowledged;
        BOOL                Success = TRUE;
        UINT8               i2cbyte;
    
        // Initialize debug messages (when supported)
        DBINIT();
    
        // Set the I2C baudrate
        actualClock = I2CSetFrequency(EEPROM_I2C_BUS, GetPeripheralClock(), I2C_CLOCK_FREQ);
        if ( abs(actualClock-I2C_CLOCK_FREQ) > I2C_CLOCK_FREQ/10 )
        {
            DBPRINTF("Error: I2C1 clock frequency (%u) error exceeds 10%%.\n", (unsigned)actualClock);
        }
    
        // Enable the I2C bus
        I2CEnable(EEPROM_I2C_BUS, TRUE);
    
        //
        // Send the data to EEPROM to program one location
        //
    
        // Initialize the data buffer
        I2C_FORMAT_7_BIT_ADDRESS(SlaveAddress, EEPROM_ADDRESS, I2C_WRITE);
        i2cData[0] = SlaveAddress.byte;
        i2cData[1] = 0x05;              // EEPROM location to program (high address byte)
        i2cData[2] = 0x40;              // EEPROM location to program (low address byte)
        i2cData[3] = 0xAA;              // Data to write
        DataSz = 4;
    
        // Start the transfer to write data to the EEPROM
        if( !StartTransfer(FALSE) )
        {
            while(1);
        }
    
        // Transmit all data
        Index = 0;
        while( Success && (Index < DataSz) )
        {
            // Transmit a byte
            if (TransmitOneByte(i2cData[Index]))
            {
                // Advance to the next byte
                Index++;
    
                // Verify that the byte was acknowledged
                if(!I2CByteWasAcknowledged(EEPROM_I2C_BUS))
                {
                    DBPRINTF("Error: Sent byte was not acknowledged\n");
                    Success = FALSE;
                }
            }
            else
            {
                Success = FALSE;
            }
        }
    
        // End the transfer (hang here if an error occured)
        StopTransfer();
        if(!Success)
        {
            while(1);
        }
    
        // Wait for EEPROM to complete write process, by polling the ack status.
        Acknowledged = FALSE;
        do
        {
            // Start the transfer to address the EEPROM
            if( !StartTransfer(FALSE) )
            {
                while(1);
            }
    
            // Transmit just the EEPROM's address
            if (TransmitOneByte(SlaveAddress.byte))
            {
                // Check to see if the byte was acknowledged
                Acknowledged = I2CByteWasAcknowledged(EEPROM_I2C_BUS);
            }
            else
            {
                Success = FALSE;
            }
    
            // End the transfer (stop here if an error occured)
            StopTransfer();
            if(!Success)
            {
                while(1);
            }
    
        } while (Acknowledged != TRUE);
    
        //
        // Read the data back from the EEPROM.
        //
    
        // Initialize the data buffer
        I2C_FORMAT_7_BIT_ADDRESS(SlaveAddress, EEPROM_ADDRESS, I2C_WRITE);
        i2cData[0] = SlaveAddress.byte;
        i2cData[1] = 0x05;              // EEPROM location to read (high address byte)
        i2cData[2] = 0x40;              // EEPROM location to read (low address byte)
        DataSz = 3;
    
        // Start the transfer to read the EEPROM.
        if( !StartTransfer(FALSE) )
        {
            while(1);
        }
    
        // Address the EEPROM.
        Index = 0;
        while( Success & (Index < DataSz) )
        {
            // Transmit a byte
            if (TransmitOneByte(i2cData[Index]))
            {
                // Advance to the next byte
                Index++;
            }
            else
            {
                Success = FALSE;
            }
    
            // Verify that the byte was acknowledged
            if(!I2CByteWasAcknowledged(EEPROM_I2C_BUS))
            {
                DBPRINTF("Error: Sent byte was not acknowledged\n");
                Success = FALSE;
            }
        }
    
        // Restart and send the EEPROM's internal address to switch to a read transfer
        if(Success)
        {
            // Send a Repeated Started condition
            if( !StartTransfer(TRUE) )
            {
                while(1);
            }
    
            // Transmit the address with the READ bit set
            I2C_FORMAT_7_BIT_ADDRESS(SlaveAddress, EEPROM_ADDRESS, I2C_READ);
            if (TransmitOneByte(SlaveAddress.byte))
            {
                // Verify that the byte was acknowledged
                if(!I2CByteWasAcknowledged(EEPROM_I2C_BUS))
                {
                    DBPRINTF("Error: Sent byte was not acknowledged\n");
                    Success = FALSE;
                }
            }
            else
            {
                Success = FALSE;
            }
        }
    
        // Read the data from the desired address
        if(Success)
        {
            if(I2CReceiverEnable(EEPROM_I2C_BUS, TRUE) == I2C_RECEIVE_OVERFLOW)
            {
                DBPRINTF("Error: I2C Receive Overflow\n");
                Success = FALSE;
            }
            else
            {
                while(!I2CReceivedDataIsAvailable(EEPROM_I2C_BUS));
                i2cbyte = I2CGetByte(EEPROM_I2C_BUS);
            }
    
        }
    
        // End the transfer (stop here if an error occured)
        StopTransfer();
        if(!Success)
        {
            while(1);
        }
    
        // Validate the data read
        if( i2cbyte != 0xAA )
        {
            DBPRINTF("Error: Verify failed\n");
        }
        else
        {
            DBPRINTF("Success\n");
        }
    
        // Example complete
        while(1);
    }
  8. In the above program, the EEPROM is being written with a value AA and read from the memory to verify if it written correctly. To verify the result access the watch window from Window > Debugging > Watches or you can use the shortcut key Alt+Shift+2. In the watch window panel that opens on the MPLAB X IDE, enter the new watch as i2cbyte, in the blank <Enter new watch> area.
  9. In the program editor window, put a breakpoint by clicking on the line number  on the while statement near the end of the program.
  10. Click on Debug Project icon shown below,                                                 analogread mplab3
  11. Once the program halts its execution at the line with the breakpoint, click on Watches window below the code area. You can observe the output value being reflected in the i2cbyte variable as shown below.serialcomm1
This verifies the operation of writing into and reading from EEPROM memory through the I2C serial communication. To get more information on working of I2C serial communication visit the wikipedia website by clicking here. In our application EEPROM on the IOshield is the slave device and PIC controller on chipKIT Uno32 board acts as the master device. 
VN:F [1.9.22_1171]
Rating: 3.6/10 (8 votes cast)
VN:F [1.9.22_1171]
Rating: 0 (from 0 votes)

Analog Read using MPLAB X IDE

Overview:

In this project you will learn to use a basic functionality of chipKIT board in MPLAB X IDE, which is to read an analog value and output the corresponding digital reading for it. A potentiometer is a  three-terminal resistor with a sliding contact that forms an adjustable voltage divider. Using a potentiometer measuring instrument, you could measure the electric potential. In this example we use the potentiometer in the chipKIT Basic IO shield. Find the same project using MPIDE here.

Hardware Used:

To do the analog read project, you require the following hardware devices.

  • chipKIT Uno 32
  • chipKIT Basic IO shield
  • PICkit¬ģ 3 In-Circuit Debugger/Programmer
  • USB cable
  • 6 pin header to connect chipKIT board and PICkit¬ģ 3

Reference:

The reference guide for each board, schematics and other resources are available on their individual homepages:

Procedure:

  1. Connect the hardware devices. The PICkit¬ģ 3 should be connected to the chipKIT Uno32 board through a suitable header and use the USB cable to connect the PICkit¬ģ 3 to your PC.
  2. Place the IO shield on top of the Uno32 board with a bit of a firm press. A0-potentiometer of the IO shield will be used as peripheral for Uno32 board, in this excercise.
  3. Once the hardware setup is made and¬†the device drivers are updated for PICkit¬ģ 3 on your computer, launch MPLAB X¬†(Start>All Programs>Microchip>MPLAB X IDE>MPLAB X IDE vx.xx¬†on Window¬ģ Machines ).
  4. Create a new project through¬†File>New Project.¬†In the pop up new project window, select¬†Standalone Project¬† under Projects¬† and click¬†Next.¬†Under¬†Family¬†scroll and select¬†32-bit MCUs (PIC32). Note the processor number from the chipKIT board’s reference manual and enter it under the¬†Device¬† option. Click Next.
  5. Select PICkit3 in the Hardware Tools, click Next. Select XC32 (v1.20) under Compiler Toolchains, click Next. Give a project name to create the project.
  6. In the Project tab on the left side of the MPLAB X IDE, right click on Source Files > New > C Main File.. and give a file name for main source code. Once the dot c file opens, select all the codes in the file and replace it with the codes below.
    #include <plib.h>
    #include <xc.h>
    
    #pragma config FPLLMUL = MUL_20, FPLLIDIV = DIV_2, FPLLODIV = DIV_1, FWDTEN = OFF
    #pragma config POSCMOD = HS, FNOSC = PRIPLL, FPBDIV = DIV_1
    #define SYS_FREQ (80000000L)
    
    unsigned int channel4;	// conversion result as read from result buffer
    unsigned int offset;	// buffer offset to point to the base of the idle buffer
    
    int main(void)
    {
        // Configure the device for maximum performance but do not change the PBDIV
        // Given the options, this function will change the flash wait states and
        // enable prefetch cache but will not change the PBDIV. The PBDIV value
        // is already set via the pragma FPBDIV option above..
        SYSTEMConfig(SYS_FREQ, SYS_CFG_WAIT_STATES | SYS_CFG_PCACHE);
    
        // configure and enable the ADC
        CloseADC10();    // ensure the ADC is off before setting the configuration
    
        // define setup parameters for OpenADC10
                    // Turn module on | ouput in integer | trigger mode auto | enable autosample
        #define PARAM1  ADC_MODULE_ON | ADC_FORMAT_INTG | ADC_CLK_AUTO | ADC_AUTO_SAMPLING_ON
    
        // define setup parameters for OpenADC10
                    // ADC ref external    | disable offset test    | disable scan mode | perform 2 samples | use dual buffers | use alternate mode
        #define PARAM2  ADC_VREF_AVDD_AVSS | ADC_OFFSET_CAL_DISABLE | ADC_SCAN_OFF | ADC_SAMPLES_PER_INT_9 | ADC_ALT_BUF_OFF | ADC_ALT_INPUT_OFF
    
        // define setup parameters for OpenADC10
        //                   use ADC internal clock | set sample time
        #define PARAM3  ADC_CONV_CLK_INTERNAL_RC | ADC_SAMPLE_TIME_15
    
        // define setup parameters for OpenADC10
        // do not assign channels to scan
        #define PARAM4    SKIP_SCAN_ALL
    
        // define setup parameters for OpenADC10
                    // set AN2 as analog inputs
        #define PARAM5    ENABLE_AN2_ANA
    
            // use ground as neg ref for A | use AN2 for input A
    
         // configure to sample AN2
        SetChanADC10( ADC_CH0_NEG_SAMPLEA_NVREF | ADC_CH0_POS_SAMPLEA_AN2); // configure to sample AN2
        OpenADC10( PARAM1, PARAM2, PARAM3, PARAM4, PARAM5 ); // configure ADC using parameter define above
    
        EnableADC10(); // Enable the ADC
    
      while ( ! mAD1GetIntFlag() ) { } // wait for the first conversion to complete so there will be vaild data in ADC result registers
    
        // the result of the conversion is available in channel4.
        while (1)
        {
    
            channel4 = ReadADC10(0);          // read the result of channel 4 conversion from the idle buffer
    
        }
    
        return 0;
    }
  7. To read the potentiometer value, access the watch window from Window > Debugging > Watches or you can use the shortcut key Alt+Shift+2. In the watch window panel that opens on the MPLAB X IDE, enter the new watch as channel4, in the blank <Enter new watch> area as shown below in the figure.                                                                                                                                                          analogread mplab1
  8. In the program editor window, put a breakpoint by clicking on the line number after the code line
     channel4 = ReadADC10(0);          // read the result of channel 4 conversion from the idle buffer
    That is on the line with the closing braces of the while loop. This should create a red box in the number line as shown in the figure below,                                                     analogread mplab2
  9. Click on Debug Project icon shown below,                                                 analogread mplab3
  10. Once the program halts its execution at the line with the breakpoint, click on Watches output window, right click on the expand button under Value column and select Display value column as > Decimal. The value that appear in this column for channel4 variable corresponds to the potentiometer reading which is read in the range of 0 to 1023. A value 0 corresponds to 0 volts and a value 1023 corresponds to 3.3 volts.
  11. Now, click on Continue button from the top pane and observe the value of channel4 to change and reflect the potentiometer reading as described before.
  12. If you would like to change the potentiometer knob and see a different value, then, change the potentiometer knob and click on the Reset button on the top pane. This will initialize the variables back to zero. Clicking on the Play button on the top pane, will get your changed  potentiometer value on the Watches window. Below is a screenshot showing the potentiometer value for 3.3 volts being read in the Watch window.  analogread mplab4
VN:F [1.9.22_1171]
Rating: 5.7/10 (6 votes cast)
VN:F [1.9.22_1171]
Rating: +2 (from 2 votes)

Serial Communication – I2C Temperature sensor output to OLED

Overview:

In this project you will learn to use a basic functionality of chipKIT board, which is to use serial communication I2C bus to measure the room temperature and output the corresponding digital reading for it. I2C bus is a master slave bus, which communicates data from the processor on chipKIT board to other peripherals. More description on I2C communication can be found on the Wikipedia website.

Hardware Used:

The hardware used in this tutorial will be a chipKIT Uno32 along with a chipKIT Basic I/O Shield both manufactured by Digilent Inc.

Reference:

The reference guide for each board, schematics and other resources are available on their individual homepages:

Procedure:

  1. Go to the¬†chipKIT Basic I/O Shield homepage mentioned in¬†the reference¬†section.¬†Download the¬†zip file that contains libraries and documentation for using the Basic I/O Shield‚ĄĘ with the chipKIT MPIDE. Open the downloaded zip folder and copy the three IOShield folders in it. These three folders have the libraries and example programs for EEPROM, OLED and Temperature Sensor peripherals on IO shield.
  2. Now open the drive where you installed the mpide software, inside your mpide folder navigate through hardware > pic32 > libraries and paste the three IOShield folders in it.
  3. Close your mpide software, for the libraries to get included and the changes to take effect.
  4. On restarting the mpide software and navigating through File > Examples; you can find IOShieldEEPROM, IOShieldOled and IOShieldTemp folders with their demo examples being included.
  5. As an initial test, you can run the existing example code for temperature sensor peripheral of the IO Shield. To do this navigate through and open File > Examples > IOShieldOled > IOShield_Oled_Demo. 
  6. Once the new sketch is opened, click the Verify button and this will compile successfully unless the library file is not included properly.
  7. Make sure you connect the Uno32 board via the mini-B connector on board to an available port on your computer.
  8. Place the IO shield on top of the Uno32 board with a bit of a firm press.
  9. Once connected, in your MPIDE window, select Tools>Board>chipKIT UNO32 to identify the UNO32 Board as the target
  10. Next, select Tools>Serial Port>COMxx. This will depend on which port was assigned to the chipKIT UNO32 Board when first connected.
  11. To load your sketch onto the chipKIT UNO32 board’s Microcontroller, press the Upload button. This will compile your sketch (check for errors) and then send to the Microcontroller. Unless you type your own code in the sketch, you wouldn’t need to verify them before uploading.
  12. Once the code is done uploading, open the serial monitor from the toolbar and after a few seconds of delay the temperature will be displayed in Celsius and Fahrenheit as shown below, tempsensor1
  13. As a next step, the Organic LED present in the IO shield can be used to display the temperature.
  14. Make sure that the jumper settings for JP4 on chipKIT Uno32 board is configured as SPI Slave Select input mode. You can find the jumper settings in chipKIT Uno32 board reference manual from the Digilent website. Also, ensure that the jumpers JP6/JP8 are configured to be used as I2C communication lines.
  15. To make the temperature be displayed on OLED, create a new sketch, save it by giving a name and insert the code below in the sketch space.
    #include <IOShieldTemp.h>
    #include <IOShieldOled.h>
    #include <Wire.h>
    
    int tensc = 0;
    int onesc = 0;
    int dot_tensc = 0;
    int dot_onesc = 0;
    int tensf = 0;
    int onesf = 0;
    int dot_tensf = 0;
    int dot_onesf = 0;
    int tempC=0;
    int tempF=0;
    
    void setup()
    {
      IOShieldOled.begin();
      IOShieldOled.displayOn();
      IOShieldTemp.config(IOSHIELDTEMP_ONESHOT | IOSHIELDTEMP_RES12);
    }
    void loop() 
    {
      float tempf, tempc;
      //Get Temperature in Celsius.
      tempc = IOShieldTemp.getTemp();
    
      // Convert the result to Fahrenheit.
      tempf = IOShieldTemp.convCtoF(tempc);
    
      //parse data for temperature in celcius
      tempC=tempc*100;
      dot_onesc = tempC%10;
      tempC = tempC/10;
      dot_tensc = tempC%10;
      tempC = tempC/10;
      onesc = tempC%10;
      tempC = tempC/10;
      tensc = tempC%10;
    
      //convert data to ASCII for temperature in celcius
       tensc = tensc+48;
       onesc = onesc+48;
       dot_tensc = dot_tensc+48;
       dot_onesc = dot_onesc+48;
    
      //parse data for temperature in Fahrenheit
      tempF=tempf*100;
      dot_onesf = tempF%10;
      tempF = tempF/10;
      dot_tensf = tempF%10;
      tempF = tempF/10;
      onesf = tempF%10;
      tempF = tempF/10;
      tensf = tempF%10;
    
      //convert data to ASCII for temperature in Fahrenheit
       tensf = tensf+48;
       onesf = onesf+48;
       dot_tensf = dot_tensf+48;
       dot_onesf = dot_onesf+48;
    
      //Clear the virtual buffer
      IOShieldOled.clearBuffer();
    
      //Draw a rectangle over wrting then slide the rectagle
      //down slowly displaying all writing
        IOShieldOled.clearBuffer();
        IOShieldOled.setCursor(0, 0);
        IOShieldOled.putString("Tempertaure is");
        IOShieldOled.setCursor(0, 2);
        IOShieldOled.putChar(tensc);
        IOShieldOled.setCursor(1, 2);
        IOShieldOled.putChar(onesc);
        IOShieldOled.setCursor(2, 2);
        IOShieldOled.putString(".");
        IOShieldOled.setCursor(3, 2);
        IOShieldOled.putChar(dot_tensc);
        IOShieldOled.setCursor(4, 2);
        IOShieldOled.putChar(dot_onesc);
        IOShieldOled.setCursor(6, 2);
        IOShieldOled.putString(" Degrees C");
        IOShieldOled.setCursor(0, 3);
        IOShieldOled.putChar(tensf);
        IOShieldOled.setCursor(1, 3);
        IOShieldOled.putChar(onesf);
        IOShieldOled.setCursor(2, 3);
        IOShieldOled.putString(".");
        IOShieldOled.setCursor(3, 3);
        IOShieldOled.putChar(dot_tensf);
        IOShieldOled.setCursor(4, 3);
        IOShieldOled.putChar(dot_onesf);
        IOShieldOled.setCursor(6, 3);
        IOShieldOled.putString(" Degrees F");
    
      delay(100);
    }
  16. In this code, the floating point values of temperature in celcius and fahrenheit are received, separated into digits by parsing the value and each digit is expressed in ASCII, aligning the position on OLED screen.
  17. To get more details on each function used with respect to OLED, open the IOShieldOLED folder which you downloaded from Digilent website and refer IOShield Library – Oeld.pdf. The same apply for functions for TEMP sensor too.
  18. To get the display, verify the code and upload it to the board. Once uploaded, you can see the temperature value displayed on OLED.
VN:F [1.9.22_1171]
Rating: 7.3/10 (3 votes cast)

Analog read serial on OLED

Overview:

In this project you will learn to use a basic functionality of chipKIT board, which is to read a analog value and output the corresponding digital reading for it. A potentiometer is a  three-terminal resistor with a sliding contact that forms an adjustable voltage divider. Using a potentiometer measuring instrument, you could measure the electric potential.

Hardware Used:

The hardware used in this tutorial will be a chipKIT Uno32 along with a chipKIT Basic I/O Shield both manufactured by Digilent Inc.

Reference:

The reference guide for each board, schematics and other resources are available on their individual homepages:

Procedure:

  1. Open MPIDE software on your PC and go to File > Examples > Basics > AnalogReadSerial to open the code which reads the analog signal on serial window.
  2. The code should look like this:
    /*
    AnalogReadSerial
    Reads an analog input on pin 0, prints the result to the serial monitor
    
    This example code is in the public domain.
    */
    
    void setup() {
    Serial.begin(9600);
    }
    
    void loop() {
    int sensorValue = analogRead(A0);
    Serial.println(sensorValue, DEC);
    }
    The function Serial.begin(), sets the data rate in bits per second (baud rate) for serial data transmission. In this case, the baud rate for communication between the computer and the chipKIT board is set to 9600. Using analogRead function, enables the chipKIT board to read the input voltage at port A0 ranging from 0 to 3.3 volts into values ranging from 0 to 1023 (as chipKIT board has a 10 bit A/D converter in it). Serial.println function, prints in a new line each time the values from sensorValue variable in decimal format.
  3. Make sure you connect the Uno32 board via the mini-B connector on board to an available port on your computer.
  4. Place the IO shield on top of the Uno32 board with a bit of a firm press. LEDs and A0-potentiometer of the IO shield will be used as peripherals for Uno32 board, in this excercise.
  5. Once connected, in your MPIDE window, select Tools>Board>chipKIT UNO32 to identify the UNO32 Board as the target
  6. Next, select Tools>Serial Port>COMxx. This will depend on which port was assigned to the chipKIT UNO32 Board when first connected.
  7. To load your sketch onto the chipKIT UNO32 board‚Äôs Microcontroller, press the upload button. This will compile your sketch (check for errors) and then send to the Microcontroller. Unless you type your own code in the sketch, you wouldn’t need to verify them before uploading.
  8. Once the code is done uploading, open the serial monitor from the toolbar shown below,                                                                                                                analogread96
  9. A new serial monitor window will appear as shown below,                                                                          analogread2
  10. The potentiometer on IO shield which provides input voltage to analog input A0 of UNO32 board, can be turned to get the varying voltage levels. Serial monitor window will show the decimal value change (between 0 to 1023) correspondingly.
  11. As a next step, the Organic LED present in the IO shield can be used to display the potentiometer values. For this, go to the chipKIT Basic I/O Shield homepage mentioned in Reference section.
  12. Download the¬†zip file that contains libraries and documentation for using the Basic I/O Shield‚ĄĘ with the chipKIT MPIDE. Open the downloaded zip folder and copy the three IOShield folders in it. These three folders have the libraries and example programs for EEPROM, OLED and Temperature Sensor peripherals on IO shield.
  13. Now open the drive where you installed the mpide software, inside your mpide folder navigate through hardware > pic32 > libraries and paste the three IOShield folders in it.
  14. Close your mpide software, for the libraries to get included and the changes to take effect.
  15. On restarting the mpide software and navigating through File > Examples; you can find IOShieldEEPROM, IOShieldOled and IOShieldTemp folders with their demo examples being included.
  16. You can run the IOShield_Oled_Demo example as a new sketch, with the existing hardware setup, to observe the change in OLED display of IO shield.
  17. To make the ADC values display on OLED, create a new sketch, save it by giving a name and insert the code below in the sketch space.
    #include <IOShieldOled.h>
    
    int adc_data = 0;
    int thousands = 0;
    int hundreds = 0;
    int tens = 0;
    int ones = 0;
    
    void setup()
    {
      IOShieldOled.begin();
      IOShieldOled.displayOn();
    }
    
    void loop()
    {
      adc_data = analogRead(0);
    
      //parse data
      ones = adc_data%10;
      adc_data = adc_data/10;
      tens = adc_data%10;
      adc_data = adc_data/10;
      hundreds = adc_data%10;
      adc_data = adc_data/10;
      thousands = adc_data%10;
    
      //convert data to ASCII
       thousands = thousands+48;
       hundreds = hundreds+48;
       tens = tens+48;
       ones = ones+48;
    
      //Clear the virtual buffer
      IOShieldOled.clearBuffer();
    
      //Draw a rectangle over wrting then slide the rectagle
      //down slowly displaying all writing
        IOShieldOled.clearBuffer();
        IOShieldOled.setCursor(0, 0);
        IOShieldOled.putString("Analog read");
        IOShieldOled.setCursor(0, 1);
        IOShieldOled.putString("result is");
        IOShieldOled.setCursor(0, 3);
        IOShieldOled.putChar(thousands);
        IOShieldOled.setCursor(1, 3);
        IOShieldOled.putChar(hundreds);
        IOShieldOled.setCursor(2, 3);
        IOShieldOled.putChar(tens);
        IOShieldOled.setCursor(3, 3);
        IOShieldOled.putChar(ones);
    
      delay(100);
    
    }
  18. The above code gets the decimal valued data from the potentiometer in the IO shield, separates each number by modulo operation, converts the decimals into ASCII characters which are suitable OLED to read and displays it in OLED by assigning the cursor position.
  19. To get more details on each function used with respect to OLED, open the IOShieldOLED folder which you downloaded from Digilent website and refer IOShield Library – Oeld.pdf
  20. To get the display, verify the code and upload it to the board. Once uploaded, you can see the potentiometer value displayed on OLED. Turn the knob, to get values changing correspondingly.
VN:F [1.9.22_1171]
Rating: 8.0/10 (3 votes cast)
VN:F [1.9.22_1171]
Rating: +1 (from 1 vote)

chipKIT Software SPI Library

This article on chipKIT software SPI library is written by Gene Apperson, Digilent Inc.

At Digilent we have been working to extend the chipKIT software framework beyond its original Arduino-inspired roots. Recent enhancements enable the framework to be used with many different systems based on PIC32 MCUs. In order to support arbitrary hardware configurations, we implemented a general-purpose Serial Peripheral Interface (SPI) library that does not rely on dedicated hardware peripherals. The Software SPI (SoftSPI) library allows the creation of any number of software based (bit-banged) SPI ports.

Serial Peripheral Interface (SPI) is a four wire synchronous serial interface used by many integrated circuits and electronic devices. SPI devices can operate as either master slave devices. The four SPI signals are generally referred to as Slave Select (SS), Master Out, Slave In (MOSI), Master In, Slave Out (MISO), and Serial Clock (SCK). A master device generates SS, MOSI and SCK, and receives MISO. A slave device receives SS, MOSI, and SCK and generates MISO. The SS signal is used to enable the slave device, and this signal is only significant for slave devices. A master device can use any general purpose I/O pin to generate SS to enable a slave.

The SoftSPI library only supports operation as an SPI master device.

An SPI transaction begins with the master device bringing SS low. When the slave sees SS go low it becomes enabled and waits for the master to send data. The master shifts data out on MOSI and simultaneously shifts data in on MISO. The slave device receives data from the master on its MOSI pin and simultaneously sends data to the master on its MISO pin. Each time the master sends a byte to the slave, it simultaneously receives a byte from the slave. The master generates the clock signal (SCK) that is used to control the shifting of the data in both the master and the slave.

SPI devices can operate using one of four data transfer modes, and one of two shift directions. The transfer modes specify the idle state of the clock signal (idles high or idles low) the active edge of the clock, and the phase relationship between the active edge of the clock signal and the data. The modes are generally called mode 0 through mode 3. The shift direction specifies whether the data is shifted most significant bit first (shift left), or least significant bit first (shift right). The SoftSPI library header file defines symbols used to specify the transfer mode and shift direction. Refer to documentation for the SPI slave device being used to determine the transfer mode and shift direction to use. Most SPI devices use mode 0 with shift left.

The SoftSPI library defines an object class (SoftSPI) that is used to create a separate object instance for each desired SPI port. Each instance of the SoftSPI object class uses four specified digital pins for the SPI signals. The SoftSPI object class supports all four transfer modes, both shift directions, and setting the frequency of the clock signal.

To use the SoftSPI library, an object instance variable of the SoftSPI object class must be created:

/* Declare an instance of the SPI interface object */
SoftSPI    spi;

The object instance is initialized using functions to set mode, shift direction and clock speed. In this example, a 6uS delay between bytes is specified to accommodate a joystick peripheral:

/* Define digital pins for the SoftSPI port to use*/
#define  pinSS    24
#define  pinMOSI  25
#define  pinMISO  26
#define  pinSCK   27

/* Initialize the SPI port */
spi.begin(pinSS, pinMOSI, pinMISO, pinSCK);
spi.setSpeed(250000);
spi.setMode(SSPI_MODE0);
spi.setDirection(SSPI_SHIFT_LEFT);
spi.setDelay(6);  /* delay 6uS between bytes */

Data can then be transferred to a slave device by calling the various data transfer functions. This example communicates with Digilent’s PmodJSTK peripheral:

{
uint8_t    rgbSnd[5];
uint8_t    rgbRcv[5];
int      ib;
/* Initialize the transmit buffer */
for (ib = 0; ib < 5; ib++) {
rgbSnd[ib] = 0x50 + ib;
}
rgbSnd[0] = fbLedPmod + 0x80;  // First byte sets the LEDs

/* Bring SS low to begin the transaction */
spi.setSelect(LOW);

/* Wait 10us for Pmod to become ready */
Delay10us();

/* Send the data to the Pmod and get the response */
spi.transfer(5, rgbSnd, rgbRcv);

/* Bring SS high to end the transaction */
spi.setSelect(HIGH);
}
The SoftSPI Library is included with versions of the Multi-Platform IDE (MPIDE) dated 12/15/2011 or later. Complete documentation is available here.
VN:F [1.9.22_1171]
Rating: 10.0/10 (2 votes cast)
VN:F [1.9.22_1171]
Rating: 0 (from 0 votes)

Guide to making contributed libs cross platform

  • Eliminate processor and/or chip specific code.
  • If processor and chip specific code can not be eliminated use #ifdefs to encapsulate your processor or chip specific code.
  • Test your changes on as many platforms as possible.
  • Send a patch to the maintainer.
  • If the maintainer is unwilling to accept changes, fork!
VN:F [1.9.22_1171]
Rating: 5.0/10 (3 votes cast)
VN:F [1.9.22_1171]
Rating: 0 (from 0 votes)