How to output data?

i have a working 8 char 16-segment display that I will be doubleing up to make a 16 char display.

Currently it runs from a MAX6955 chip that I have sampled and solderedto a breakout board.

I have found very little documentation on how to "write" to this chip.

As it is I2C, I have to send data to each digit register seperately, Currently I have a string, which I have seperated using

for( int x = 0; x<[i]string[/i].length(); x++){
  [i]string[/i].charAt(x)
  if(x == 0) {
    digit0 = x;
  }
  else if (x == 1) {
    digit1 = x;
  }
  etc...
  // now all the digits are loaded with wat they have to be show them;
  show();
}

Show() is a simple function that consists of:

void show() {
  Wire.beginTransmission(maxAddress);
  Wire.write(0x20) //first char register;
  Wire.write(digit0); 
  Wire.write(digit1);
  Wire.write(digit2);
  Wire.write(digit3);
  Wire.write(digit4);
  Wire.write(digit5);
  Wire.write(digit6);
  Wire.write(digit7);
  Wire.endTransmission();
}

Ideailly I want to write a libary for this so I can give back to the community, but I want to create a function whereby I can call what I want to display like you can in LCD by calling:

lcd.print("Hello");

There has to be a way of breaking down the input to do it, I will not always be wanting to use strings, as it is going to display raw variables also such as temperature, pressure and fluid levels.

I have tried reading the LCD libary but I cannot find where it breaks down what is fead to it and sends it to the display.

You might want to google for liudr's examples.

Hi, thanks for the nudge, I have found sprintf | LiuDr Electronic Solutions LLC Official Blog, and when I get home from work will give this a try...

Many thanks for the pointer

Jimmy

I could not get this working, but while doing a bit more of a dig through the LCD libary, I found the following files...

print.h and print.cpp

How can I implement them as they have all the hard work done of detecting if it is a float, or a int or whatever?

I know I have to use

include print.h

but how can I tie that into a function for now, and then into a libary?

The section of the LCD libary I can find that does this is as below:

class LiquidCrystal : public Print {
public:
  LiquidCrystal(uint8_t rs, uint8_t enable,
		uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3,
		uint8_t d4, uint8_t d5, uint8_t d6, uint8_t d7);
  LiquidCrystal(uint8_t rs, uint8_t rw, uint8_t enable,
		uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3,
		uint8_t d4, uint8_t d5, uint8_t d6, uint8_t d7);
  LiquidCrystal(uint8_t rs, uint8_t rw, uint8_t enable,
		uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3);
  LiquidCrystal(uint8_t rs, uint8_t enable,
		uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3);

  void init(uint8_t fourbitmode, uint8_t rs, uint8_t rw, uint8_t enable,
	    uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3,
	    uint8_t d4, uint8_t d5, uint8_t d6, uint8_t d7);
    
  void begin(uint8_t cols, uint8_t rows, uint8_t charsize = LCD_5x8DOTS);

  void clear();
  void home();

  void noDisplay();
  void display();
  void noBlink();
  void blink();
  void noCursor();
  void cursor();
  void scrollDisplayLeft();
  void scrollDisplayRight();
  void leftToRight();
  void rightToLeft();
  void autoscroll();
  void noAutoscroll();

  void createChar(uint8_t, uint8_t[]);
  void setCursor(uint8_t, uint8_t); 
  virtual size_t write(uint8_t);
  void command(uint8_t);
  
  using Print::write;
private:
  void send(uint8_t, uint8_t);
  void write4bits(uint8_t);
  void write8bits(uint8_t);
  void pulseEnable();

  uint8_t _rs_pin; // LOW: command.  HIGH: character.
  uint8_t _rw_pin; // LOW: write to LCD.  HIGH: read from LCD.
  uint8_t _enable_pin; // activated by a HIGH pulse.
  uint8_t _data_pins[8];

  uint8_t _displayfunction;
  uint8_t _displaycontrol;
  uint8_t _displaymode;

  uint8_t _initialized;

  uint8_t _numlines,_currline;
};

I just dont get how I can make this / the stuff in print.h and print.cpp take what is given to it and format it to an 8 char string to display

in essance I wnat to be able to do this

//pins to use
//a0 - temp pin
//a4 a5 - I2C bus
//d3 - mode button

int tempPin = A0;
int modeBtn = 3;

void setup() {
  //pinmodes
  pinMode(tempPin, INPUT);
  pinMode(modeBtn, INPUT);
  
  //perform i2c Max6955 initilsation here
}

void loop() {
  float temp = temp();
  maxPrint(temp);
  delay(1000);
}

void temp() {
  //get the temp from tmp36
  float temp = 13.42;
  return temp;
}

void maxPrint(any_var_type, what_to_print) {
  //collect to string
  //now parse the string to seperate into chars
  //and store in variables
  //and finally send over i2c bus
}

but what I wnat to send may be floats, strings, or other var types.

I can do it on LCDs so I know it is possible, but not sure how to implement it.

Any help is aprechiated.

Jimmy

How can I implement them as they have all the hard work done of detecting if it is a float, or a int or whatever?

Look at the Print class. Specifically, look at the print() method. Notice that there is not one print() method, but several print() methods - each taking a different type. The output of each of the print methods is some data sent to the destination device, using a series of calls to the write() method.

Note that the write method is virtual.

Typically, the class that derives from Print implements it's own write() methods to send the data to a specific device.

You could create a class that derives from Print, and let the print() methods do all the work of converting the int, float, etc. to strings, and make your write() method(s) actually display the characters on your device.

Hi,

Many thanks for the pointer, have you got any sample code at all?

I hate asking to be spoon fed but I have never played with C at all only ever used PHP and even then I shied away from classes...

Actually I would not class it as spoon fed, more fork, as holes are good lol

Any nudges in the right direction even just what to google I will be very appreciative of as I am totally lost.

Once I have it in a string form, I can split it down no problem and then write, using the folowing

Wire.beginTransmission(maxAddress);
Wire.write(0x20); //first address

for( int x = 0; x< 8; x++;) { //loop thorugh the display and send to maxchip
  Wire.write(string.charAt(x));
}

Wire.endTransmission();

Many thanks for the help so far.

Jimmy

The LiquidCrystal class is derived from the Print class. Look at LiquidCrystal.h and LiquidCrystal.cpp for an example of how to define your class. Change the stuff that is specific to an LCD to stuff that is specific to your device. Leave the rest alone.

Ive been working on this on and of for a week now and i'm not getting anywhere, I have tried removing all the LCD stuff and I either get errors (too numourous to post) or I get nothing.

This is the core function of my program, Once I have it in a string I can do anything I want with it.

I gave up breifley and moved onto dtostrf which works, but is only for floats.

How can I make a function that will take an input of any variable and convert it to a string?

Can anyone help with a snippet of code that will do this?

How can I make a function that will take an input of any variable and convert it to a string?

You can't. That was my point from the very beginning. You can, using a class, have several functions of the same name, each of which takes a different kind of variable and converts it to a string.

There is, of course, no reason to invent such a class, since the Print class already exists.

PaulS:
Look at the Print class. Specifically, look at the print() method. Notice that there is not one print() method, but several print() methods - each taking a different type. The output of each of the print methods is some data sent to the destination device, using a series of calls to the write() method.

Note that the write method is virtual.

Typically, the class that derives from Print implements it's own write() methods to send the data to a specific device.

You could create a class that derives from Print, and let the print() methods do all the work of converting the int, float, etc. to strings, and make your write() method(s) actually display the characters on your device.

So I think I get you (in a sence).

PaulS:
The LiquidCrystal class is derived from the Print class. Look at LiquidCrystal.h and LiquidCrystal.cpp for an example of how to define your class. Change the stuff that is specific to an LCD to stuff that is specific to your device. Leave the rest alone.

So is it a case of defineing a write() and putting my push to the device in there?

If so I have spent a couple of hours looking at the liquidCrystall where it does this, and I have updated my class to the following two files

On the output (display) I am getting the letter that represents the length of the string...

I think this is the last bit now.

The 3 files I have to test with are as below:

//max6955.ino

#include <Wire.h>
#include <max6955.h>

Maxim6955 max1(0x60);


void setup() {
  max1.begin(1);
}

void loop() {
  max1.clear();
  delay(500);
  max1.write("jimmy is now having a hard time trying to get this thing to work");
  delay(1000);
}
//max6955.h
#ifndef Maxim
#define Maxim

#include "arduino.h"
#include <inttypes.h>
#include "Print.h"


class Maxim6955 : public Print {
 public:
   Maxim6955(uint8_t address); //constructor
   void begin(uint8_t test);
   void clear();

   virtual size_t write(uint8_t);
   using Print::write;

 private:
   void send(uint8_t);
   uint8_t _address;
   uint8_t _off;
};

#endif
//max6955.cpp

#include <stdio.h>
#include <string.h>
#include <inttypes.h>
#include <Wire.h>
#include "Arduino.h"
#include "max6955.h"

Maxim6955::Maxim6955(uint8_t address) {
  _address = address;
  _off = 0x00;
}

void Maxim6955::begin(uint8_t testMode) {
  //start configuring the display
  Wire.beginTransmission(_address);
  Wire.write(0x01);        // Write to the decode resgister;
  Wire.write(0b11111111); //decode all digits 1 is decode 0 gives direct access
  Wire.write(0x01);       //Intensity default, guess I should take this from a pin to see where the dash lights are at...
  Wire.write(0x07);       // hex easiest way of seeing which digits to scan (all 8 is 0x07)
  Wire.write(0x01);       // Control Reg 0x01 is shutdown off
  Wire.endTransmission();
  
  
  //device setup to accept charectures now, are we doing a display test?
  
  if(testMode == 1) {
    
    //test is wanted, this lightsup all segments for 1.5 seconds then turns off
    Wire.beginTransmission(_address);
    Wire.write(0x07);     //TestRegister
    Wire.write(0x01);     //Turn it on
    Wire.endTransmission();
    
    delay(1500); //delay 1.5 seconds
    
    Wire.beginTransmission(_address);
    Wire.write(0x07);     //TestRegister
    Wire.write(_off);     //Turn it off
    Wire.endTransmission();
  }
  
  else {
    Wire.beginTransmission(_address);
    Wire.write(0x07);     //TestRegister
    Wire.write(_off);     //Turn it off
    Wire.endTransmission();

    
  } //end test;
  
  
} //END BEGIN





/******************* High Level commands */

void Maxim6955::clear() {
  //manual function to clear display
  
  Wire.beginTransmission(_address);
  Wire.write(0x20);     //TestRegister
  Wire.write(32);       //"space" Char
  Wire.write(32);       //"space" Char
  Wire.write(32);       //"space" Char
  Wire.write(32);       //"space" Char
  Wire.write(32);       //"space" Char
  Wire.write(32);       //"space" Char
  Wire.write(32);       //"space" Char
  Wire.write(32);       //"space" Char
  Wire.endTransmission();
}


inline size_t Maxim6955::write(uint8_t value) {
  send(value);
  return value;
  return 1; // assume sucesss
}


// write the output over the i2c bus
void Maxim6955::send(uint8_t value) {
  //write to the i2c bus
  Wire.beginTransmission(_address);
  Wire.write(0x20);
  //for(uint8_t x=0; x<sizeof(value) - 1; x++){
    Wire.write(value);
  
  //}
  Wire.endTransmission();
}

The for loop in the write() method here does not work as expected, but this is because I am not getting the string output, only the length of the string.

I cannot find where this is going wrong.

  return value;
  return 1; // assume sucesss

Time to read up on what return does.

  max1.write("jimmy is now having a hard time trying to get this thing to work");

You do not have a write() method that takes a string. You shouldn't have a write() method that take a string. You shouldn't be using write() with strings at all. You should be using print() with strings.

The for loop in the write() method here does not work as expected, but this is because I am not getting the string output, only the length of the string.

There is no for loop in the write() method, so I have no idea what you are talking about.

PaulS:

  return value;

return 1; // assume sucesss



Time to read up on what return does.

Will do, but I forgot to remove the "return value" bit.

  max1.write("jimmy is now having a hard time trying to get this thing to work");

You do not have a write() method that takes a string. You shouldn't have a write() method that take a string. You shouldn't be using write() with strings at all. You should be using print() with strings.

I have changed this to print now

The for loop in the write() method here does not work as expected, but this is because I am not getting the string output, only the length of the string.

There is no for loop in the write() method, so I have no idea what you are talking about.

This for loop is in the .cpp file in the class : this bit (like a noob this is send() not write :roll_eyes:);

// write the output over the i2c bus
void Maxim6955::send(uint8_t value) {
  //write to the i2c bus
  Wire.beginTransmission(_address);
  Wire.write(0x20);
  //for(uint8_t x=0; x<sizeof(value) - 1; x++){
    Wire.write(value);
  
  //}
  Wire.endTransmission();
}

However I have now added a delay into the write(), and this is displaying the output on one digit, so I need to start a string and then read each of the characters into this, as it looks like it sends one at a tyme, so one byte at a time.

void Maxim6955::send(uint8_t value) {

So, this function takes a byte. Why is it you think you need to loop to send one byte?

I thought it would send the full string that was printed, nence the loop to breack it down into the component characters of the string, which I could then go though, I am trying to make this build up a full string in the send() sections.

Or I could create a new function that will start the Wire transmission, and then the bit that outputs, then one that ends the transmission.

I prefer the idea of the first though.

Next thing to investigate is to see what how to build a string from the write() or the send().

Many thanks for the pointers so far.