I cannot compile using pca 9539 library - arduino

I was trying to to find a library for NXP PCA9539PW IC, but the one i found it's either outdated and i'm not able to fix it or i couldn't find another.
I need to control 11 inputs using this IC, i already soldered pull up resistors for each of them but I cannot make my IDE to compile using the following library.
I currently struggle with : https://github.com/AD0ND/PCA9539 (i know it's for esp but on pull requests somebody made some modifications that might work). I couldn't make it work on my arduino uno.
Can you guys please suggest me how to make it work or if it's another library available ?
Thank you

It's terrible library, it seems they renamed files from clsPCA9539.* to PCA9539.* and forgot to change include. You'll have to change #include "clsPCA9539.h" to #include "PCA9539.h" in file PCA9539.cpp
Next thing are A0-A7 and B0-B7 definitions in file PCA9539.h are colliding with Arduino's analog input aliases and B* are even worst as they are #defines. You can either change those, or just use 0..15 directly. Eg:
enum {
A0, A1, A2, A3, A4, A5, A6, A7,
B0, B1, B2, B3, B4, B5, B6, B7
};
to:
enum {
PCA_A0, PCA_A1, PCA_A2, PCA_A3, PCA_A4, PCA_A5, PCA_A6, PCA_A7,
PCA_B0, PCA_B1, PCA_B2, PCA_B3, PCA_B4, PCA_B5, PCA_B6, PCA_B7
};
And in the example use those new aliases:
ioport.pinMode(PCA_A0, OUTPUT); // instead of A0
After those changes the library will be compilable on Uno (but I don't have any PCA9539, so I can't test it)
EDIT: I completely forgot they have also constructor completely wrong:
PCA9555::PCA9555(uint8_t address) { should be PCA9539::PCA9539(uint8_t address) {

Related

Initial EEPROM contents in Atmega644

I am working on a project using a Atmega644 and want to include EEPROM data in the initial programming.
I am using MPLAB X and the XC8 compiler (version 2.31) and for programming I am using a PICkit4.
I know that the xc8 compiler for PIC MCUs has the __EEPROM_DATA() macro, that would be pretty much perfect for my usecase. The AVR version of the compiler, however does not appear to have this macro (I tried both with and without CCI syntax...), as it does not recognize the call and just throws an error when trying to compile.
I have looked through the manual for the compiler, but it does not list any macros/functions to do this.
I tried adding the macro myself, by copying it from the PIC compiler to a header in my project, but it seems to contain assembly instructions that do not exist on the atmega and I couldn't even find those in documentation for the PIC (Otherwise I would have tried to find an equivalent instruction and replace them)...
Is there another way to include the initial EEPROM data in the project, so it gets written to the mcu during programming?
__EEPROM_DATA() macro is supported only for 8-bit PIC baseline and mid-range devices. There is also __eeprom qualifier to position variables in EEPROM. But none of these are for AVR chips.
Microchip supports AVR chips in XC8 using avr headers. There is an eeprom header which has some macros defined. One of these macros is EEMEM. You can use it to set EEPROM values at programming time. Here is how you use it:
#include <avr/eeprom.h>
char EEMEM nums[] = { 1, 2, 3, 4, 5 };
There is good information regarding the usage of this macro in this and this SO answers. Make sure to have a look at them.
I also recommend you to take a look at MPLAB XC8 C Compiler User's Guide for AVR MCU in case you didn't know about it.

Arduino ESP32 TwoWire "method" doesn't work

I have trouble using two sensors on two I2C interfaces.
The problem is, that I when I try to replace the Wire.begin() with something like this: I2C.begin(21, 22), my sensor QMC5883L returns for x, y and z 0. I included the Wire library manually and created a TwoWire object:
#include <Wire.h>
TwoWire I2C = TwoWire(0);
When I tried this, I commented the _wire->begin() in the library, It worked with the commented line and with Wire.begin() in the sketch, but when I try to replace Wire.begin() with I2C.begin(21, 22) it doesn't work anymore.
The reason, why this should work is that I want to create 2 interfaces like that and then give them to the compass.begin(&I2C) method. In the library I have this:
void QMC5883LCompass::init(TwoWire *theWire){
_wire = theWire;
_wire->begin(); // this is the line I commented, when getting the zeros...
_writeReg(0x0B,0x01);
setMode(0x01,0x0C,0x10,0X00);
}
Did I forget something?
Problem is that when calling _wire->begin() is actually calling the default definition (from Wire.h):
bool begin(int sda=-1, int scl=-1, uint32_t frequency=0);
Default parameters -1 for SDA/SCL means default pins, wich overwrites the ones you added in the first begin(...)
Presuming you are using https://github.com/mprograms/QMC5883LCompass, the solution is to subclass QMC5883LCompass and override the void QMC5883LCompass::init() or create a new init(...) with your specific needs.

ESP8266 "ovf" when doing small double maths

I'm using a Wemos D1 based on the ESP8266 wifi chip with the Arduino C framework to do some simple small math.
As far as I can gather, double precision is available so I'm using it - with a maximum of something like 1.8*10^103.
But I'm getting an ovf when I try to calculate a number around 5*10^8.
Any ideas please?
void setup(){
Serial.begin(9600);
while(!Serial);
Serial.println("Hit any key to start math");
double te = 6800;
double res = te * te;
Serial.println(res);
te = 68000;
res = te * te;
Serial.println(res);
te = 680000;
res = te * te;
Serial.println(res);
}
void loop(){
}
Prints
46240000.00
ovf
ovf
Arduino does supports 4-byte double data type. and your code is indeed produced a valid double value that is not overflow (ovf).
The problem that you see has to do with the way Arduino implement Serial.print() function which is almost like a half-cooked hack to support floating-point and is not as reliable as vprintf() that is available in avr-libc. You can see the source code here which print ovf for anything bigger than 4294967040.0 or smaller than -4294967040.0. I thought that ESP8266 Arduino Core has fixed this instead of inheriting the ugly implementation of Arduino Serial.print(), but apparently not.
Luckily the ESP8266 Arduino Core does have a Serial.printf() method that provide better floating point rendering. This code will shows that your number is indeed a valid number for double data type.
void setup(){
Serial.begin(9600);
while(!Serial);
double te = 68000;
double res = te * te;
Serial.println(res); //this will produce 'ovf'
Serial.printf("Result=%f\n", res); //this will produce correct 4624000000.000000
}
Please noted that Serial.printf() is ESP8266 specific implementation to support full floating point vprintf() in the standard library. It is not available for standard Arduino Boards.
For Arduino boards, there is a way to use sprintf() which inherits from vprintf() to print the correct floating point with some twist on linker options during code compilation process. I have a blog post Do you know Arduino - sprintf() and floating point talk about how to do that.

ATtiny85 I2C SSD1306 screen not working

I have been on this issue for more than 3 days now after I got my SSD1306 I2C in the mail. I have a Tiny Programmer from Sparkfun, which I use with a breadboard.
This is my pin layout: pin2-->SDA, pin3-->SCL. The documentation on the SSD1306 Arduino library states that I have to use these pins even though I know the SDA is pin5 and SCL is pin7. The power and ground are being jumped to the OLED from the Tiny Programmer.
The main issue I am having is that the OLED is not coming on or displaying the text.
The code I am using for this is:
/**
* Attiny85 PINS
* ____
* RESET -|_| |- 3V
* SCL (3) -| |- (2)
* SDA (4) -| |- (1)
* GND -|____|- (0)
*
* Atmega328 PINS: connect LCD to A4/A5
*/
#include "ssd1306.h"
void setup() {
/* Replace the line below with ssd1306_128x32_i2c_init() if you need to use 128x32 display */
ssd1306_128x64_i2c_init();
ssd1306_fillScreen(0x00);
ssd1306_charF6x8(0, 0, "Line 1. text");
ssd1306_charF6x8(0, 1, "Line 2. Bold text", STYLE_BOLD);
ssd1306_charF6x8(0, 2, "Line 3. Italic text", STYLE_ITALIC);
ssd1306_charF12x16(0, 3, "Line 4. Double size", STYLE_BOLD);
}
void loop() {
}
There is no error message when I compile this and I honestly have no idea what's going on.
I have tried swapping the SDA and SCL and still nothing. I have even used the actual SDA and SCL pins and still nothing. I feel that I am out of options and/or the OLED is broken. I'm just seeing if there is anything else I can do before I try to get a replacement for this? Thank you.
I think you have to use pins 5 and 7 with the attiny85. You also need to use tinywirem.h for I2C communication.
The ATTiny85 I2C pins are pin5(PB0) SDA and pin7(PB2) SCL, the SSD1306 library seems to think they are pin3(PB4) SDA and pin2(PB3) SCL, the demos even have an diagram of an ATTtiny within them showing the incorrect pins. I have used the official pins with no luck. Using the pins they suggest did actually run but just so slowly most would think it was not working. It took minutes to start clearing the screen, and even longer to actually clear it.
I have used the U8g2 library instead, the init entry for the Digispark ATTiny85 works OK for the u8x8 helloworld demo though I could not get many of the demos to compile for the ATTiny85. I am still looking for a better solution.

Spartan 3 Starter Kit Constraints File

I am not sure if this is the right stack exchange website to post this on, but if it isn't please move it to the appropriate one.
I am facing a small problem in writing my constraints file for the spartan 3 starter kit.
I have read the documentation provided by Xilinx (the manufacturer) and ive been searching online for a few weeks without any luck.
What i am trying to do is link my Netlist interface to any of the 3 40-pin-headers on the board. (See image below)
Usually its very simple, if say i want to interface a button or a led on the board, i just read the connection name on the board, for example one of the buttons is M13 and write in the UCF file something like this :
NET "BTN0" LOC = "M13";
As you can see on the image the headers are named A1, A2 and B1 on the board, but oddly enough, none of the following worked :
NET "TestOutputLine" LOC = "A1(0)"; -- The (0) is to reference a single line on an array
NET "TestOutputBus" LOC = "A1"; -- The bus is of equal dimension of A1 (which is 40)
The errors i got meant that either the target (specified by LOC) does not exist or that the assignment is invalid.
I hope you have some ideas for me.
Thanks in advance
EDIT :
Here is the output from ISE :
ConstraintSystem:59 - Constraint <NET "TestOutputBus" LOC = "A1";>
[circuit.ucf(12)]: NET "TestOutputBus" not found. Please verify that:
1. The specified design element actually exists in the original design.
But i am pretty sure that TestOutputBus exists, as a matter of fact there is nothing else in my design right now, and the correct top level unit is being used.
EDIT2 :
I updated my UCF file, right now it's like this :
NET "TestOutputBus(0)" LOC = "A1(0)";
NET "TestOutputBus(1)" LOC = "A1(1)";
But i get a different error now in mapping :
MapLib:30 - LOC constraint A1:0 on TestOutputBus<0> is invalid: No such
site on the device. To bypass this error set the environment variable
'XIL_MAP_LOCWARN'.
MapLib:30 - LOC constraint A1:1 on TestOutputBus<1> is invalid: No such
site on the device. To bypass this error set the environment variable
'XIL_MAP_LOCWARN'.
Solution :
In order to get the pins 5 and 6 mapped to TestOutputBus(0) and TestOutputBus(1) respectively what i had to use was this :
NET "TestOutputBus(0)" LOC = "N7"; -- A1 pin 5
NET "TestOutputBus(1)" LOC = "L5"; -- A1 pin 6
Note that pins 0 are not mappable thats why i used pins 5 and 6, here are the tables that show the mappable pins for all headers and their LOCs.
As it turns out, there is an address for each usable pin of each header of the FPGA.
The datasheet (http://forums.xilinx.com/xlnx/attachments/xlnx/Spartan/3411/1/S3BOARD_RM.pdf) was helpful especially pages 49 - 51
I copied this from my earlier comment to your question so it would be an actual answer and not just a comment.
You should have LOC constraints in your UCF file for every port on your top-level module. So if you have a 40-bit-wide bus as an input or output at the top level then you should also have 40 separate LOC constraints in your UCF file to make sure that the logical bus in your top-level schematic actually gets mapped to the correct pins on your FPGA. If you are only using two pins, then you can declare the bus to be 2-bits wide and use 2 LOC constraints. The FPGA will treat all unused pins as inputs and ignore them.
I once got the original ConstraintSystem:59 net xyz not found error when i accidentally selected one of my modules as a top module. The pins declared in UCF could not be found in the port declaration of wrong module.
Also i get this error when i have some pin declared in UCF but ommit it in port declaration of top module.

Resources