Discover MakerZone

MATLAB and Simulink resources for Arduino, LEGO, and Raspberry Pi

Learn more

Discover what MATLAB® can do for your career.

Opportunities for recent engineering grads.

Apply Today

s-Function Builder Help

Asked by Guillermo on 30 Apr 2013

Hello all, I'm trying to create the S-function for the MCP4725 DAC. I've got it working on the Arduino IDE and the code looks like this (extracted from the Adafruit drivers to eliminate the need to copy the Adafruit Includes in the working directory):

****************************************

#include Wire.h

#include "math.h" // include the Math Library

#define DAC_ADD (0x60)

#define WriteOnly (0x40) //command to update AO only

#define WriteAndStore (0x60) //command to update AO and save AO setting to EEPROM

int a;

void setup(void) {

Serial.begin(9600);
Serial.println("Hello!");
Serial.println("DAC tester");
Serial.flush();
Wire.begin(); //join i2c bus as master

}

void loop () {

Serial.println("Enter value for leg 'a' from 0 - 4095, Press ENTER"); //asks for user input at serial monitor
while (Serial.available() == 0) ;  // Wait here until input buffer has a character
{
      //user input
    a = Serial.parseInt(); // new command in 1.0 forward
    Serial.print("a = "); Serial.println(a, DEC); //echos user input at the serial monitor
    int twbrback = TWBR;  //i2c specific and don't understand it
    TWBR = 12; // 400 khz //i2c specific and it sets the comm freq.
    Wire.beginTransmission(DAC_ADD); //tell the i2c device that data is comming to it
    Wire.write(WriteOnly); // first byte in message for MPC4725
    Wire.write(a / 16); //Second byte 
    Wire.write((a % 16) << 4); //third byte
    Wire.endTransmission(); //Tell device all instruction shave been trasnmitted
    TWBR = twbrback;   //i2c specific
  }

}

****************************************

NOTE that comments have been wrapped to the next line here. The code works and I can update the Analog Output of the board by entering a count value (0 - 4095) at the serial monitor.

I've tried to create the s function with s function builder but keep getting the following error:

****************************************

Error MCP4725_Output_v1.c: 82 missing parameter type

Error MCP4725_Output_v1.c: 196 type error in argument 2 to `MCP4725_Output_v1_Update_wrapper'; found `pointer to double' expected `int'

Error MCP4725_Output_v1.c: 196 insufficient number of arguments to `MCP4725_Output_v1_Update_wrapper' 3 errors, 0 warnings

C:\PROGRA~2\MATLAB\R2013A\BIN\MEX.PL: Error: Compile of 'MCP4725_Output_v1.c' failed.

****************************************

I put the following in the different s-function tabs

Discrete Update: if (xD[0]!=1) {

# ifndef MATLAB_MEX_FILE
   Wire.begin(); // start i2c bus
# endif   
// initialization done 
xD[0]=1;
}

Outputs: // wait until after initialization is done if (xD[0]==1) {

# ifndef MATLAB_MEX_FILE
    int twbrback = TWBR;
    TWBR = 0x0c; // 400 khz
    Wire.beginTransmission(DAC_ADD);
    Wire.write(WriteOnly);
    Wire.write(DAC_in[0] / 16);
    Wire.write((DAC_in[0 % 16) << 4);
    Wire.endTransmission();
    TWBR = twbrback;
  # endif
}

Libraries (include...):

#ifndef MATLAB_MEX_FILE

#include Arduino.h

#include math.h

// Include the following i2c libraries // pulled from Arduino ver 1.0

#include Wire.h

#include Wire.cpp

#include twi.h

#include twi.c

// DAC Address Defines

#define DAC_ADD 0x60

#define WriteOnly 0x40

#define WriteAndStore 0x60

  1. endif

Data Properties:

INPUT: DAC_in (1-D, 1, , real, off)

OUTPUT: none

PARAMETERS: none

DATA TYPE ATTR...: In_1: DAC_in (uint16, 12, checked, 3, 2^-3, 0)

For the data type I've tried all the settings available and none worked

I've also copied all the libraries to the working directory and I know this is working because I was able to run the Adxl345 I2c Driver for Arduino Mega that this thread inspired....

What am I doing wrong???

Thanks for the help...

2 Comments

Jordan Monthei on 13 May 2013

Your errors reference lines 82 and 196, what is the code on each of those lines?

Guillermo on 15 May 2013

OK, I got it working.

The problem is that for some reason the s-function needs a parameter. So I added a parameter named Par type int8 and initialized to 1. Why it needs this I don't know but it fixed the problem.

@ Jordan, at line 82 (missing parameter type error) there were two comas right after the other. " ...code... , , .....more code ..."

I tried to remove one of the comas and adding a type to the ....more code... which was the input but apparently the space between the comas needs another argument which turns out to be the parameter.

I'll paste the new code, also note that this editor removes the "<" and ">" from the posts so the libraries are listed wrong in the original post.

Guillermo

Products

1 Answer

Answer by Guillermo on 15 May 2013
Accepted answer

Init tab: Number of discrete states: 1 Sample mode: Discrete Sample time value: 0.1

Data Properties tab:

  1. Input ports: (u0, 1-D, 1, , real, off)
  2. No output ports
  3. Parameter: (par, int8, real) in the S-function parameters the value was initialized to 1
  4. Datatype attributes: (In_1: u0, int16, 8, unchecked, 9, 0.125, 0)

Libraries tab:

# ifndef MATLAB_MEX_FILE
#include <Arduino.h>
#include <math.h>
#include <Wire.cpp>
#include <Wire.h>
#include <twi.h>
#include <twi.c>
// DAC Address Defines
#define DAC_ADD 0x60
# endif

Outputs tab:

if (xD[0] == 1){
    # ifndef MATLAB_MEX_FILE
    int twbrback = TWBR;  //i2c specific and don't understand it
    TWBR = 12; // 400 khz //i2c specific and it sets the comm freq.
      Wire.beginTransmission(DAC_ADD); //tell the i2c device that data is comming to it
      Wire.write(64); // first byte in message for MPC4725
      Wire.write(u0[0] / 16); //Second byte 
      Wire.write((u0[0] % 16) << 4); //third byte
      Wire.endTransmission(); //Tell device all instruction shave been trasnmitted
      TWBR = twbrback;   //i2c specific
      # endif
  }

Discrete Update tab:

if (xD[0] != 1){
      # ifndef MATLAB_MEX_FILE
      Wire.begin(); //join i2c bus as master
      # endif
      xD[0] = 1;
  }

NOTES:

  1. the libraries need to be co-located in the same folder where the driver s-function is located (There's got to be a better way to manage this)
  2. don't forget to change the *wrapper.c file to .cpp
  3. edit the *wrapper.cpp file to add extern "C" before the void lines (find the s-function builder tutorial, it explains a good deal.)

1 Comment

Guillermo on 15 May 2013

Next on this is to try to get it to work on the Raspberry Pi substituting the Arduino Wire library with WiringPi libraries.

Crossing fingers.

Guillermo

Contact us