B4R Question SPI Library

Discussion in 'B4R Questions' started by atiaust, May 11, 2018.

Similar threads

B4R Tutorial Arduino - PC File Transfer
B4R Library [code module] SPI
Wish SPI Library
B4R Library rMCP2515
B4R Question Is there a SPI B4R library?
  1. atiaust

    atiaust Active Member Licensed User

    Hi All,

    Does anyone know if the SPI library for B4R was ever added?

    I am trying to read data from a MCP3551 22bit A2D converter which has a SPI interface.

    Anyone had any experience with this device?

    Thanks
     
  2. Erel

    Erel Administrator Staff Member Licensed User

    Johan Hormaza likes this.
  3. atiaust

    atiaust Active Member Licensed User

    Thanks Erel,

    I did look at the code module but I do not know how to use it.

    I have the SPI connected to a WEMOS D1 mini using D5 as SCK, D8 as SS and D6 as MISO.

    Is there some code or tutorial showing how to assign the pins and access the code module?

    Any help gratefully appreciated.

    Thanks
     
  4. Roycefer

    Roycefer Well-Known Member Licensed User

    There are two methods in that code module that show how to use the code module with a DAC and an ADC.
     
  5. atiaust

    atiaust Active Member Licensed User

    Thanks Roycefer,

    I should have been a little clearer with my question.

    I can see the two methods but not clear on the IO for the SPI device.

    Can you tell me if the pin assignments in the code below are correct or am I missing something.

    Code:
    Sub Process_Globals
        
    'These global variables will be declared once when the application starts.
        'Public variables can be accessed from all modules.
        Public Serial1 As Serial
        
    Private D1 As D1Pins
        
    Private SCK As Pin
        
    Private SS As Pin
        
    Private MISO As Pin
    '   
    End Sub

    Private Sub AppStart
        Serial1.Initialize(
    115200)
        
    Log("AppStart")
    '   
        SCK.Initialize(D1.D5, SCK.MODE_OUTPUT)
        SS.Initialize(D1.D8, SS.MODE_OUTPUT)
        MISO.Initialize(D1.D6, MISO.MODE_INPUT)
        AddLooper(
    "Looper1")
    End Sub

    Sub looper1
        SPI.adcSingleChannelRead(SS,??)
    End Sub
    Thanks
     
  6. Roycefer

    Roycefer Well-Known Member Licensed User

    You will have to check the documentation for your board to find the SPI pins.
     
  7. atiaust

    atiaust Active Member Licensed User

    Hi Roycefer,

    The pins in the code above are the SPI pins for the WEMOS D1 mini.

    I am unsure of how to actually read the SPI device using your module.

    Is it something like:
    Dim Result as Double = SPI.adcSingleChannelRead(SS, readAddress) What is the readAddress?
     
    Last edited: May 11, 2018
  8. Roycefer

    Roycefer Well-Known Member Licensed User

    The SPI.adcSingleChannelRead method is for an MCP3008 which is an 8-channel ADC. That means you need to pass the channel's address to the ADC and the ADC will pass the analog value it read on that channel back to you.

    You are using an MCP3551 which only has one channel. I don't think the SPI.acSingleChannelRead method will work for this device. You will need to read the MCP3551's datasheet to see what it expects. If you can find some Arduino code that interfaces with the MCP3551 we can probably convert that to work with B4R and the SPI code module.
     
  9. atiaust

    atiaust Active Member Licensed User

    Here is some Arduino code. I will try to get this to work using Arduino.

    Code:
    /*
    pins:
     cs=
    8
     sdo/rdy=
    12
     sck=
    13
    */

    #include <SPI.h>

    unsigned char sspin=
    8; //cs pin

    union{
            int32_t value;
            uint8_t aa[
    4];
        
    } c ;
        

    void setup(void){
    pinMode(12,INPUT);  //to check ready pin
    pinMode(sspin,OUTPUT);
    digitalWrite(sspin,HIGH);//for single conversion
    SPI.begin();
    SPI.setBitOrder(MSBFIRST);
    SPI.setDataMode(SPI_MODE3);
    SPI.setClockDivider(SPI_CLOCK_DIV16);//max. speed of chip is 5 Mhz
    Serial.begin(9600); 

    }

    void loop(void){
     
    digitalWrite(sspin,LOW);

    while(digitalRead(12)){
     
      digitalWrite(sspin,LOW);
                        
                        }
    c.aa[2]=SPI.transfer(0x00);
    c.aa[1]=SPI.transfer(0x00);
    c.aa[0]=SPI.transfer(0x00);
    c.aa[3]=0x00;
    digitalWrite(sspin,HIGH);
    //check if overflow has occured
    if((c.aa[2]&(1<<6))|(c.aa[2]&(1<<7))){
      c.aa[2]&=~(1<<6);
      Serial.println(c.value);
    }
    //check if sign bit is affected. if so, since it is two's compliment,
    // substract it from 2^N
    else if(c.aa[2]&(1<<5)){
    c.value=0x400000-c.value;
    Serial.println(c.value);
    }

    else{
    Serial.println(c.value);
    }
      delay(10);

    }
    I have the spec sheet for the MCP3551 but it is too big to upload.

    Thanks for your assistance.
     
  10. Roycefer

    Roycefer Well-Known Member Licensed User

    Add these two subs to the SPI code module:
    Code:
    Public Sub MCP3551Read(clckSpeed As Int, chipSelectPin As Pin) As Long
        chipSelectPin.DigitalWrite(
    True)
        BeginTransaction(clckSpeed,MSBFIRST,SPI_MODE(
    3))
        chipSelectPin.DigitalWrite(
    False)
        
    Dim b(4As Byte
        b(
    2) = Transfer(0x00)
        b(
    1) = Transfer(0x00)
        b(
    0) = Transfer(0x00)
        b(
    3) = 0x00
        chipSelectPin.DigitalWrite(
    True)
        
    Dim res As Long = 0
        EndTransaction
        
    Dim r As RandomAccessFile
        
    If UintToBoolean( Bit.Or( Bit.And(b(2),Bit.ShiftLeft(1,6)), Bit.And(b(2),Bit.ShiftLeft(1,7)) )) Then
            b(
    2) = Bit.And(b(2),Bit.Not(Bit.ShiftLeft(1,6)))
            
    Dim r As RandomAccessFile
            r.Initialize(b,
    True)
            res = r.ReadLong32(
    0)
        
    Else if UintToBoolean(Bit.And(b(2),Bit.ShiftLeft(1,5))) Then
            r.Initialize(b,
    True)
            res = r.ReadLong32(
    0)
            res = 
    0x400000-res
        
    End If
        
    Return res
    End Sub

    Public Sub UintToBoolean(u As UInt) As Boolean
        
    Return u<>0
    End Sub
    Note that this isn't tested. You will have to test and debug it yourself. This is just a literal translation of the Arduino code you posted. But it should get you started on the right path.
     
    Erel likes this.
  11. atiaust

    atiaust Active Member Licensed User

    Thanks Roycefer,

    I have added it in to the app as suggested.

    I need to get the device that provides the analog signal to the MCP3551 working correctly before I can test it.

    Thanks for your assistance. I will let you know the outcome.
     
Loading...