Counting and Timing a shock sensor

Got past the previous error and now this.

This guy apparently got past it but I’m not sure how to do what he did or if it even applies.

http://www.arduino.cc/cgi-bin/yabb2/YaB … 1285968999

I’m not sure what to think. Given the C++ file, I thought doing the OLEDFourBit lcd(pins, pins, pins …) would call the init function which would call the begin function. Maybe that’s not really happening. In the BFG’s main sketch, fermentationMonitor.pde, he does …

#include <OLEDFourBit.h>
#include "globals.h"
#include "enums.h"


void setup()
{
  lcdText[0][20]='\0';
  lcdText[1][20]='\0';
  lcdText[2][20]='\0';
  lcdText[3][20]='\0';

  pinMode(coolingPin, OUTPUT);
  pinMode(heatingPin, OUTPUT);
  pinMode(doorPin, INPUT);
  // analog pins are input by default
  
  analogReference(2); //set analog reference to internal 1.1V
  delay(100);
  lcd.begin(20, 4);
  lcd.clear(); 
  lcdPrintStationaryText();
  loadSettings(); //read previous settings from EEPROM
  
  lcdPrintMode();
  Serial.begin(9600);
  initFilters();
  initControl();
  updateSettings();
  serialFridgeMessage(ARDUINO_START);
}

Note the <> in the #include for the OLED instead of the " ". Also note he does an lcd.begin(20, 4) but never an OLEDFourBit lcd(pins, pins, pins …). So there’s something I’m not getting. I’d have thought he’d have to do the later to even use lcd.begin().

Given the error message about how “OLEDFourBit” doesn’t define a type, you might start by replacing the;

#include “OLEDFourBit.h”

in the test sketch with …

#include <OLEDFourBit.h>

There’s some rule about when to use which I may have gotten wrong. And I’m now pretty sure the test sketch has it wrong.

And then do an lcd.begin(20, 4) if that is insufficient.

Or perhaps the thing to do is ;

#include <OLEDFourBit.h>

OLEDFourBit lcd; // this is like the extern commented out and replaces the OLEDFourBit lcd(pins, pins, pins …)

lcd.init(12, 11, 5, 4, 9, 8 ); // also replaces the OLEDFourBit lcd(pins, pins, pins …)

lcd.begin(20, 4); // if the above still doesn’t work but I still think the lcd.init() should also call begin()

The <> are a step in the right direction as the OLEDFourBit now highlights orange like the other libraries.

However it is still giving the same error.

OLEDFourBit lcd; gives the same error.

lcd.init… doesn’t work at all.

lcd.begin(20,4); gives the error “expected constructor, destructor, or type conversion before ‘.’ token”

It looks as if Mee_n_Macs code never declares the lcd variable. Put this just before void setup():

OLEDFourBit lcd;

Dan

sspbass:
lcd.begin(20,4); gives the error “expected constructor, destructor, or type conversion before ‘.’ token”

This leads me to think the OLEDFourBit.h file isn’t being recognized somehow.

I"d have thought that

#include <OLEDFourBit.h>

OLEDFourBit lcd(12, 11, 5, 4, 9, 8 );

would be the same as

#include <OLEDFourBit.h>

OLEDFourBit lcd; 
lcd.init(12, 11, 5, 4, 9, 8 );

with the first being the proper way to do it. Somehow there’s a typo that’s the problem here.

I wonder if this is correct ?

#include <OLEDFourBit.h>

OLEDFourBit lcd; // this is the part I'm unsure of, shold this be a define ?
lcd(12, 11, 5, 4, 9, 8 );

Alternately I wonder if rewriting this part of the C++ file

#include "OLEDFourBit.h"

#include <stdio.h>
#include <string.h>
#include <inttypes.h>
#include "arduino.h"

OLEDFourBit::OLEDFourBit(uint8_t rs, uint8_t enable,
			     uint8_t d4, uint8_t d5, uint8_t d6, uint8_t d7)
{
  init(rs, enable, d4, d5, d6, d7);
}

to be …

#include "OLEDFourBit.h"

#include <stdio.h>
#include <string.h>
#include <inttypes.h>
#include "arduino.h"

OLEDFourBit::lcd(uint8_t rs, uint8_t enable,
			     uint8_t d4, uint8_t d5, uint8_t d6, uint8_t d7)
{
  init(rs, enable, d4, d5, d6, d7);
}

Wouldn’t eliminate the need to get lcd equated to OLEDFourBit (but then also req a change to the header file ?).

Then again that’s what I thought happened (in effect) when this was done ?

OLEDFourBit lcd(12, 11, 5, 4, 9, 8 );

Alright, lcd is just a variable, truly a pointer to an object. When you call lcd.method() the . means to dereference the pointer and then call the function.

As to why the constructor seems to be missed, I am not quite sure.

I will pull down the OLEDFourBit code a little later and see if I can’t get it to compile. Really you should be doing something like this:

#include <OLEDFourBit.h>

OLEDFourBit lcd;
lcd.init(rs, enable, d4, d5, d6 ,d7);

When you include a file, “” means to include a file in the local directory. Because you copied OLEDFourBit.h to your library directory you use <> to tell it to search the include paths that the Arduino software supplies.

I am surprised that OLEDFourBit lcd(rs, en, d4, d5, d6, d7); doesn’t work. I need to look at what the .h file is doing and if for some reason it is pre-defining the lcd variable. This could be why extern OLEDFourBit lcd was included before because the object is declared external to the code at hand.

Dan

Originally the …

extern OLEDFourBit lcd;

was in the BFG’s globals.h file. Interestingly I just found the part I’ve been missing (the initialization and …) in his globals.cpp file.

OLEDFourBit lcd(3, 4, 5, 6, 7, 8, 9);

So given the variable lcd is not external to the main sketch here ???

I really need to look at this code, I am making some pretty bad inferences from the code I have seen so far.

Alright, what is globals.h and .cpp actually doing? Is it needed for this project? If not, drop it and try instantiating an OLEDFourBit object yourself.

Dan

dkulinski:
I really need to look at this code, I am making some pretty bad inferences from the code I have seen so far.

Alright, what is globals.h and .cpp actually doing? Is it needed for this project? If not, drop it and try instantiating an OLEDFourBit object yourself.

Dan

And that’s just it, they were dropped. Only his OLED library is being used, appropriately modified to use only 6 pins vs his 7 and hopefully adapted for Arduino 1.0. The revised header and C++ files were :

Header:

#ifndef OLEDFourBit_h
#define OLEDFourBit_h

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

// commands
#define LCD_CLEARDISPLAY 0x01
#define LCD_RETURNHOME 0x02
#define LCD_ENTRYMODESET 0x04
#define LCD_DISPLAYCONTROL 0x08
#define LCD_CURSORSHIFT 0x10
#define LCD_FUNCTIONSET 0x28
#define LCD_SETCGRAMADDR 0x40
#define LCD_SETDDRAMADDR 0x80

// flags for display entry mode
#define LCD_ENTRYRIGHT 0x00
#define LCD_ENTRYLEFT 0x02
#define LCD_ENTRYSHIFTINCREMENT 0x01
#define LCD_ENTRYSHIFTDECREMENT 0x00

// flags for display on/off control
#define LCD_DISPLAYON 0x04
#define LCD_DISPLAYOFF 0x00
#define LCD_CURSORON 0x02
#define LCD_CURSOROFF 0x00
#define LCD_BLINKON 0x01
#define LCD_BLINKOFF 0x00

// flags for display/cursor shift
#define LCD_DISPLAYMOVE 0x08
#define LCD_CURSORMOVE 0x00
#define LCD_MOVERIGHT 0x04
#define LCD_MOVELEFT 0x00

// flags for function set
#define LCD_8BITMODE 0x10
#define LCD_4BITMODE 0x00
#define LCD_ENGLISH_JAPANESE   0x00
#define LCD_WESTERN_EUROPEAN_1 0x01
#define LCD_ENGLISH_RUSSIAN    0x02
#define LCD_WESTERN_EUROPEAN_2 0x03


class OLEDFourBit : public Print {
public:
  OLEDFourBit(uint8_t rs, uint8_t enable,
		uint8_t d4, uint8_t d5, uint8_t d6, uint8_t d7);
  
  void init(uint8_t rs, uint8_t enable,
	    uint8_t d4, uint8_t d5, uint8_t d6, uint8_t d7);
    
  void begin(uint8_t cols, uint8_t rows);

  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 void write(uint8_t);
  virtual size_t write(uint8_t);

  void command(uint8_t);
  
private:
  void send(uint8_t, uint8_t);
  void write4bits(uint8_t);
  void pulseEnable();
  void waitBusy();

  uint8_t _rs_pin; // LOW: command.  HIGH: character.
  uint8_t _enable_pin; // activated by a HIGH pulse.
  uint8_t _busy_pin;
  uint8_t _data_pins[4];

  uint8_t _displayfunction;
  uint8_t _displaycontrol;
  uint8_t _displaymode;
  uint8_t _initialized;
  uint8_t _currline;
  uint8_t _numlines;
};

#endif

C++

#include "OLEDFourBit.h"

#include <stdio.h>
#include <string.h>
#include <inttypes.h>
#include "arduino.h"

OLEDFourBit::OLEDFourBit(uint8_t rs, uint8_t enable,
			     uint8_t d4, uint8_t d5, uint8_t d6, uint8_t d7)
{
  init(rs, enable, d4, d5, d6, d7);
}

void OLEDFourBit::init(uint8_t rs, uint8_t enable,
			 uint8_t d4, uint8_t d5, uint8_t d6, uint8_t d7)
{
  _rs_pin = rs;
  _enable_pin = enable;
  _busy_pin = d7;
  
  _data_pins[0] = d4;
  _data_pins[1] = d5;
  _data_pins[2] = d6;
  _data_pins[3] = d7; 


  pinMode(_rs_pin, OUTPUT);
  pinMode(_enable_pin, OUTPUT);
  
  _displayfunction = LCD_FUNCTIONSET | LCD_4BITMODE;
   
  begin(20, 4);  
}

void OLEDFourBit::begin(uint8_t cols, uint8_t lines) {
  _numlines = lines;
  _currline = 0;
  
  pinMode(_rs_pin, OUTPUT);
  pinMode(_enable_pin, OUTPUT);
  
  digitalWrite(_rs_pin, LOW);
  digitalWrite(_enable_pin, LOW);
  
  // SEE PAGE 20 of NHD-0420DZW-AY5 
  delayMicroseconds(50000); // wait 50 ms just to be sure tha the lcd is initialized
  
  // Now we pull both RS and R/W low to begin commands
  
  for (int i = 0; i < 4; i++) {
    pinMode(_data_pins[i], OUTPUT);
    digitalWrite(_data_pins[i], LOW);
  }

  delayMicroseconds(100000);
  write4bits(0x03);
  delayMicroseconds(100000);
  write4bits(0x02);
  delayMicroseconds(10000);
  write4bits(0x02);
  delayMicroseconds(10000);
  write4bits(0x08);
   
  
  //command(0x28);
  delayMicroseconds(10000);
  
  command(0x08);	// Display off
  delayMicroseconds(10000);
	
  command(0x01);	// display clear
  delayMicroseconds(10000);

  command(0x06);	// Entry Mode Set:
  delayMicroseconds(10000);

	
  command(0x02);	// Home
  delayMicroseconds(10000);

  command(0x0C);	// display on/ cursor on/ cursor blink
  delayMicroseconds(10000);
	
	
}

/********** high level commands, for the user! */
void OLEDFourBit::clear()
{
  command(LCD_CLEARDISPLAY);  // clear display, set cursor position to zero
}

void OLEDFourBit::home()
{
  command(LCD_RETURNHOME);  // set cursor position to zero
}

void OLEDFourBit::setCursor(uint8_t col, uint8_t row)
{
  uint8_t row_offsets[] = { 0x00, 0x40, 0x14, 0x54 };
  if ( row >= _numlines ) {
    row = 0;  //write to first line if out off bounds
  }
  
  command(LCD_SETDDRAMADDR | (col + row_offsets[row]));
}

// Turn the display on/off (quickly)
void OLEDFourBit::noDisplay() {
  _displaycontrol &= ~LCD_DISPLAYON;
  command(LCD_DISPLAYCONTROL | _displaycontrol);
}
void OLEDFourBit::display() {
  _displaycontrol |= LCD_DISPLAYON;
  command(LCD_DISPLAYCONTROL | _displaycontrol);
}

// Turns the underline cursor on/off
void OLEDFourBit::noCursor() {
  _displaycontrol &= ~LCD_CURSORON;
  command(LCD_DISPLAYCONTROL | _displaycontrol);
}
void OLEDFourBit::cursor() {
  _displaycontrol |= LCD_CURSORON;
  command(LCD_DISPLAYCONTROL | _displaycontrol);
}

// Turn on and off the blinking cursor
void OLEDFourBit::noBlink() {
  _displaycontrol &= ~LCD_BLINKON;
  command(LCD_DISPLAYCONTROL | _displaycontrol);
}
void OLEDFourBit::blink() {
  _displaycontrol |= LCD_BLINKON;
  command(LCD_DISPLAYCONTROL | _displaycontrol);
}

// These commands scroll the display without changing the RAM
void OLEDFourBit::scrollDisplayLeft(void) {
  command(LCD_CURSORSHIFT | LCD_DISPLAYMOVE | LCD_MOVELEFT);
}
void OLEDFourBit::scrollDisplayRight(void) {
  command(LCD_CURSORSHIFT | LCD_DISPLAYMOVE | LCD_MOVERIGHT);
}

// This is for text that flows Left to Right
void OLEDFourBit::leftToRight(void) {
  _displaymode |= LCD_ENTRYLEFT;
  command(LCD_ENTRYMODESET | _displaymode);
}

// This is for text that flows Right to Left
void OLEDFourBit::rightToLeft(void) {
  _displaymode &= ~LCD_ENTRYLEFT;
  command(LCD_ENTRYMODESET | _displaymode);
}

// This will 'right justify' text from the cursor
void OLEDFourBit::autoscroll(void) {
  _displaymode |= LCD_ENTRYSHIFTINCREMENT;
  command(LCD_ENTRYMODESET | _displaymode);
}

// This will 'left justify' text from the cursor
void OLEDFourBit::noAutoscroll(void) {
  _displaymode &= ~LCD_ENTRYSHIFTINCREMENT;
  command(LCD_ENTRYMODESET | _displaymode);
}

// Allows us to fill the first 8 CGRAM locations
// with custom characters
void OLEDFourBit::createChar(uint8_t location, uint8_t charmap[]) {
  location &= 0x7; // we only have 8 locations 0-7
  command(LCD_SETCGRAMADDR | (location << 3));
  for (int i=0; i<8; i++) {
    write(charmap[i]);
  }
}

/*********** mid level commands, for sending data/cmds */

inline void OLEDFourBit::command(uint8_t value) {
  send(value, LOW);
  waitBusy();
}

//inline void OLEDFourBit::write(uint8_t value) {
inline size_t OLEDFourBit::write(uint8_t value) {
  send(value, HIGH);
  waitBusy();
  //return 1;
}

/************ low level data pushing commands **********/

// write either command or data
void OLEDFourBit::send(uint8_t value, uint8_t mode) {
  digitalWrite(_rs_pin, mode);
  
  write4bits(value>>4);
  write4bits(value);
}

void OLEDFourBit::pulseEnable(void) {
  digitalWrite(_enable_pin, HIGH);
  delayMicroseconds(100);    // enable pulse must be >450ns
  digitalWrite(_enable_pin, LOW);
}

void OLEDFourBit::write4bits(uint8_t value) {
  for (int i = 0; i < 4; i++) {
    pinMode(_data_pins[i], OUTPUT);
    digitalWrite(_data_pins[i], (value >> i) & 0x01);
  }
  delayMicroseconds(100);
  pulseEnable();
}

void OLEDFourBit::waitBusy(void) {
  delayMicroseconds(5000);
}

There’s a keyword file as well.

#######################################
# Syntax Coloring Map For OLEDFourBit
#######################################

#######################################
# Datatypes (KEYWORD1)
#######################################

OLEDFourBit	KEYWORD1

#######################################
# Methods and Functions (KEYWORD2)
#######################################

begin	KEYWORD2
clear	KEYWORD2
home	KEYWORD2
print	KEYWORD2
setCursor	KEYWORD2
cursor	KEYWORD2
noCursor	KEYWORD2
blink	KEYWORD2
noBlink	KEYWORD2
display	KEYWORD2
noDisplay	KEYWORD2
autoscroll	KEYWORD2
noAutoscroll	KEYWORD2
leftToRight	KEYWORD2
rightToLeft	KEYWORD2
scrollDisplayLeft	KEYWORD2
scrollDisplayRight	KEYWORD2
createChar	KEYWORD2

#######################################
# Constants (LITERAL1)
#######################################

And the test sketch should be (IMO) …

#include <OLEDFourBit.h>

// initialize the library with the numbers of the interface pins
// with the OLED library this also seems to do the init and begin calls
OLEDFourBit lcd(12, 11, 5, 4, 9, 8);

unsigned int count = 0;

void setup()
{
  lcd.clear();
  delay(5);
  lcd.setCursor(0, 0);
  delay(5);
  lcd.print("    Incrementing    ");
  delay(5);
  lcd.setCursor(0, 1);
  delay(5);
  lcd.print("     count test     ");
  delay(3000);
}

void loop()
{
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("Count = ");
  lcd.print(count);
  count++;
  delay(1000);
}

I’d have thought that instantiating the object “OLEDFourBit” using the variable lcd would be OK, just as it is when using the Arduino LCD library (LiquidCrystal). Now if some additional statement to declare lcd is needed, that’s OK too. But looking at the C++ code it seems to me that there’s a method, OLEDFourBit() which in turn calls the init() function which in turn calls the begin() function. Thus my thinking that there might need to be a

lcd.init(pins … pins)

statement. I guess an

lcd.OLEDFourBit(pins … pins)

would also work.

The latter will not work. What you are looking at is the constructor and it works in this manner (going to use a variable other than lcd):

OLEDFourBit oled(rs,enable, d4, d5, d6, d7);

That internally calls the init function so you get an object (oled in this case) that is initialized without having to call init specifically.

Dan

dkulinski:
The latter will not work. What you are looking at is the constructor and it works in this manner (going to use a variable other than lcd): OLEDFourBit oled(rs,enable, d4, d5, d6, d7);

That internally calls the init function so you get an object (oled in this case) that is initialized without having to call init specifically.

Dan

Yeah, I realized that after I wrote it. :doh:

I’ve now read some various articles and tutorials on “making a new Arduino class” and for the life of me I can’t see anything wrong with the test code in my prior post. It seems like there’s something fundamentally wrong such that the compiler says “NO”. But at this point it’s like re-re-proofreading your own writing, I’m just not going to see the obvious mistake staring me in the face.

@sspbass : could you try the test code above and see what the compiler complains about and post that again ? Maybe start fresh with the header, C++ and keyword files posted above too.

Same error.

I am still using the library files from when you added a B to the end of the file names.

Googling the error code yeilds a variety of “solutions”, some of which we already know about and have implemented. Others seem to be pre-Arduino 1.0 and other … just don’t make any sense. One example is the following …

http://arduino.cc/forum/index.php?topic=84412.0

??? char foo; ??? I don’t know about that but perhaps declaring lcd before the OLEDFourBits lcd(…); might fix the error as lcd will have been declared. I just don’t know what to declare it as. Perhaps it doesn’t matter ? I dunno. Try sticking a …

char lcd;

or

int lcd;

… someplace above the OLEDFourBits lcd(…); in the test sketch.

Actually if you do

char lcd;

And then

OLEDFourBit lcd;

You are just redeclaring lcd from one type to the other. Unfortunately I haven’t had a lot of time to look at this. Let me see what I can get going tonight since I can actually sit down and test it.

Dan

Ok, I think I found the error. OLEDFourBit requires 7 arguments for the constructor, you have 6. The reason you may not have seen this is that sspbass doesn’t see the whole error in his screenshot. You can expand the error window to see more.

The arguments are rs pin, rw pin, enable pin, d4 pin, d5 pin, d6 pin, d7 pin. Because this is wrong the lcd object is never constructed and hence the invalid references. I grabbed the source to the OLEDFourBit libraries (made a couple of changes to make it work with Arduino 1.0 software, need to make a couple more changes) but it is complete enough to show me that this is indeed the error.

Good luck!

Dan

The original versions of the library, as written by the BFG, did have 7 arguments. I thought I got rid of all references to the rw pin when I changed the C++ and header files. Did I miss something somewhere ?

Ah, I don’t have your modified files. That could definitely cause a problem for me. Still have sspbass expand his error window, I suspect I am not far off the case. Which post has your modifications?

Alright grabbed your files from page 34 of this thread, used your demo code and I get different errors.

OLEDFourBit_test.cpp.o: In function `__static_initialization_and_destruction_0’:

C:\Users\DAN~1.KUL\AppData\Local\Temp\build5482871838887402184.tmp/OLEDFourBit_test.cpp:8: undefined reference to `OLEDFourBit::OLEDFourBit(unsigned char, unsigned char, unsigned char, unsigned char, unsigned char, unsigned char)’

OLEDFourBit_test.cpp.o: In function `loop’:

C:\Users\DAN~1.KUL\AppData\Local\Temp\build5482871838887402184.tmp/OLEDFourBit_test.cpp:28: undefined reference to `OLEDFourBit::clear()’

C:\Users\DAN~1.KUL\AppData\Local\Temp\build5482871838887402184.tmp/OLEDFourBit_test.cpp:29: undefined reference to `OLEDFourBit::setCursor(unsigned char, unsigned char)’

OLEDFourBit_test.cpp.o: In function `setup’:

C:\Users\DAN~1.KUL\AppData\Local\Temp\build5482871838887402184.tmp/OLEDFourBit_test.cpp:14: undefined reference to `OLEDFourBit::clear()’

C:\Users\DAN~1.KUL\AppData\Local\Temp\build5482871838887402184.tmp/OLEDFourBit_test.cpp:16: undefined reference to `OLEDFourBit::setCursor(unsigned char, unsigned char)’

C:\Users\DAN~1.KUL\AppData\Local\Temp\build5482871838887402184.tmp/OLEDFourBit_test.cpp:20: undefined reference to `OLEDFourBit::setCursor(unsigned char, unsigned char)’

Obviously my settings aren’t quite there yet.

What about downrevving the version of the Arduino IDE? I don’t see a problem moving backwards to say 0023.

Dan