Interfacing MCP4651-502E digital potentiometer using I2C - arduino

I am using two MCP4651 dual digital potentiometers, which I want to control from Arduino Uno thru I2C. Here's datasheet for MCP4651, so you don't have to look for it: http://www.farnell.com/datasheets/1789212.pdf
I would also attach PCB schematic, but I don't have enough reputation.
I am trying to write my value into the wiper 1 register like on page 49 of datasheet. But every command I try, I get not acknowledged. I also attached screenshot of the oscilloscope.
Here's my code:
#include <Wire.h>
void setup()
{
Wire.begin();
}
void loop()
{
Wire.beginTransmission(40);
Wire.write(0b10010000);
Wire.write(0b10000000);
Wire.endTransmission(40);
delayMicroseconds(500);
}
The I2C protocol clearly works, or I would not get acknowledged address and I tried both potentiometers, both wipers, writing, incrementing and decrementing. Not a single success. If anyone knows what am I doing wrong, I would be grateful.

Page 49 of the datasheet details the general call details.
The general call commands are detailed on page 48. These commands are used when you are using the general call address (0) to communicate with all the devices at the same time.
You are trying to communicate with a single device on the bus, so you should pay attention to the commands detailed starting at page 51 and in particular Table 7-1, 7-2 and Figure 7-1.

Related

Problem with serial communication between Arduino Mega2560 and ESP32

Good morning everyone.
I am trying to establish serial communication between an arduino mega and an esp32, in both I am using hardware serials.
In the arduino the uart3 in the esp the uart2. I have checked the pin connections several times.
I also adapted the arduino's tx signal to the esp32 with a level shifter.
Essentially I need to send a string to the esp32.
The code of the arduino is as follows:
String InvioDatiESP() {
String da_passare = ("hello!!!");
return(da_passare);
}
void setup() {
Serial.begin(9600);
Serial3.begin(115200);
}
void loop() {
Serial3.println(InvioDatiESP());
Serial.println(InvioDatiESP());
delay(1000);
}
I create the string in a function since it is a reduced version of the actual code in which the string is to be composed.
The code of Esp32 is as follows:
#define RXp2 16
#define TXp2 17
void setup() {
Serial.begin(115200);
Serial2.begin(115200, SERIAL_8N1, RXp2, TXp2);
}
void loop() {
Serial.println(Serial2.readString());
}
I correctly set the boudrate in both serial ports on the IDE to verify communication.
The thing I notice that makes me doubt that the problem is related only to the ESP32 reading the string is that in the serial port of the ESP32 in the IDE while the program is running, blank lines are printed on the screen exactly every 1000ms, as if the data is received but not interpreted correctly.
How could I solve this in your opinion?
Thanks in advance for the answers!
SOLVED, the lever shifter was disturbing the signal too much, seen with the oscilloscope, I used a resistive divider and everything works perfectly, thank you all the same!
EDIT: Can you try to lower the boudrate? Check to see if with a lower one it will start decoding properly.
Your problem is not with the code, it's with the hardware. The arduino Mega2560 is using 5V logic level and ESP32 is using 3.3V.
You need to do some level shifting to be able to communicate.
You can take a look at this article to learn more about it.
Hope it helps.

I2C OLED will not turn on or display

I have started using the Arduino language instead of the pyFirmata version. I am using an Arduino UNO. I have run into the same problem, and that is that the OLED won't work. I've tried 2 different OLEDs, one from UCTRONICS and one from HiLetGo. They are both I2C 128x64 OLEDs, and the UCTRONICS one is yellow and blue while the HiLetGo one is all white. I've tried 2 different codes, one that I made and one example from the ssd1306 library. There are no errors, the OLEDs just don't light up. The board is alco connected to 4 touch sensors I am using for the same project but they have nothing wrong with them (yet). I have troubleshooted for a while now, and I have been able to pinpoint where the error is (probably) located. This is my code: (even though the ssd1306 I2C 128x64 example also doesn't work.) I also do not want suggestions that require extra hardware that I don't have, like an RTC (even though it is not related to this that was the only example I could come up with) This is my code: (even though the ssd1306 I2C 128x64 example also doesn't work.)
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define OLED_RESET 4
#define sw 128
#define sh 64
Adafruit_SSD1306 display(sw, sh, &Wire, OLED_RESET);
void setup() {
Serial.begin(9600);
Wire.begin();
display.begin(SSD1306_SWITCHCAPVCC, 0x78);
display.cp437(true);
pinMode(A4, OUTPUT);
}
void loop() {
digitalWrite(A4, HIGH);
display.clearDisplay();
display.setTextColor(WHITE);
display.setTextSize(1);
display.setCursor(0, 0);
display.println("test");
Serial.println("test");
digitalWrite(A4, LOW);
}
Like always, I only have 1 week to fix this so help would be greatly appreciated.
Your I2C address setting appears wrong. Arduino's Wire library (doc) uses 7 bit address. The last bit is read/write bit and Wire automatically takes care of it. So, you want to chop off the least significant bit and set the address to 0x3C instead of 0x78.
Adafruit_SSD1306 library actually uses 0x3C as a default address. See the declaration and notes for begin() in .h and .cpp files.
For more info, I suggest looking at SSD1306 data sheet. Here is the I2C data format. See how slave address is formatted.
Yes, these displays can be very annoying. I have experienced it myself.
First, go to the website of the supplier and see if they suggest any specific libraries to use. Some of the main issues I encountered are:
The supply voltage of the screen is not the standard 5V you expected but higher or lower. If it's lower or you supplied 5V to a 3.3V power in you might even have damaged or broke the display.
You switched the SDA/SDL wires up, forgot to connect some wires or have a faulty ground. Does the backlight work?
The library uses the wrong clockspeed
The I2C address the display is listening on differs from the one used in the library (this is the most common one for me)
It's not every time the fault of hardware, check the program as well. Load example test program and try again. https://iotforgeeks.com/i2c-oled-display-not-working/ helped me to resolve the same issue.

I2C between EEPROM and Arduino working, not with STM32

This is driving me nuts for a couple of days now, so maybe you guys can give me some insights into what is going wrong.
I'm trying to read some data from an EEPROM (24LC16B) with an STM32(F0), but it just doesn't let me. I've tried an Arduino, which worked and does still work, so I do know that the wiring is correct.
This is my function to read the EEPROM data. (It is cut down to the very basis, just for testing): (Pastebin of my I2C_setup function)
uint16_t readEEPROMData(uint16_t deviceAddress, int memAddress){
// Wait while I2C peripheral is not ready
I2C_WaitForFlag(I2C_ISR_BUSY);
// Start I2C write transfer for 2 bytes, do not end transfer (SoftEnd_Mode)
I2C_TransferHandling(I2C1, 0xA2, 2, I2C_SoftEnd_Mode, I2C_Generate_Start_Write);
I2C_WaitForFlag(I2C_ISR_TXIS);
// For testing purpose, be sure to generate a stop command...
I2C_TransferHandling(I2C1, 0xA2, 0, I2C_AutoEnd_Mode, I2C_Generate_Stop);
return I2C_COMM_STATUS;
}
Here's an pastebin of the Arduino library I used.
I've used a logic analyzer to see how the communication is going, and now I really don't understand it. Here's a printscreen of the working Arduino version:
And here's a printscreen of the STM32 communication:
Logic analyzer exports (viewable with Saleae Logic)
As you can see, I'm using the same address (although I had to use 0xA2 with the STM32), and there are no weird things happening, besides the NACK. So what could possible be wrong?
Confirm if all bus timing requirement are satisfied.
Confirm if their is adequate delay after every write cycle (5 mS)
Confirm is bus capacitance falls under permissible limit of I2C (400 pF - Theoretically).
Confirm if the correct VCC is supplied
As mentioned by you are interfacing EEPROM with MCU using cable you need to conform on capacitance.
You can use an oscilloscope to check if their are any distortion in waveform. You can use a LCR meter to check the capacitance.
Try reducing bus speed 25kHz to 50 kHz and check waveform.
Try increasing the strength of pull resister.
The problem with the wrong VCC capacity (4.2v instead of 5v for example) is, that the timing can be different to. (not fully verified, but it fixed the problem)

How to control a motor with two inputs using arduino

I am using an arduino uno and I am trying to control a motor with two inputs which I found in a small car I used to have as a child.
I connected the first pin of the motor to the arduino ground and the second one to the VCC and the motor started turning.
However, when I write the following code the motor doesn't work.
void setup() {
pinMode(8,OUTPUT);
digitalWrite(8,HIGH);
}
void loop() {
}
(I have connected the first pin of the motor to the ground and the second one to pin 8 of arduino).
Does anybody know why that happens?
You can only get a certain amount of current from an Arduino output pin. In general, you can light an LED with a direct connection to an output pin, but motors require more current. A detailed discussion is here.
To control a device such as a motor which needs more current than the output pin can provide directly, you can use an external transistor. You can buy circuits that implement this idea, such as this Motor Shield for Arduino.
This is not how Arduino is supposed to work with power consuming stuff (like mhopeng said, you may use LED in such a scheme, but not something more consuming): a motor should be between GND and 5V and if you want to control it, you have to use a transistor connected to an output pin.
I had a similar question once, it may be of help, too. Also, it may be a good idea to ask further questions at arduino.SE.

Sending output from arduino to picaxe

I am doing a class project involving an Arduino Uno and a Picaxe 14m2.
I am in the middle of attempting to code a program for the Arduino Uno that will allow me to send and output value to the input on the Picaxe.
So in layman's, this is what I wish to achieve:
I want the Arduino to check a sensor, and if the sensor returns a specific value. (- I know this part, but not the next.) I then want the Arduino to send a value (HIGH, or 1 .. something like that) as an output to one of the Picaxe input pins. I then need the Picaxe to notice a value has been sent, and then do something else.
Any help would be appreciated.
Thanks.
If you are looking for that, you may want to specify what kind of PICAXE you have.
Since there is a difference in the types of these chips.
After that you may wanna look over the datasheet of the PICAXE so that you can find the instructions set and the type of program memory you have, "EEPROM....".
After that:
List your Is/Os, inputs and outputs.
Set your source code editor.
Write the source code and burn it to the PICAXE program
memory.(C, Assembly...)
Write your Arduino code, setting the Is/Os and telling the
Arduino how to deal with the signals in and out.(C language)
Make a circuit diagram for the hardware you are going to connect
between both chips.
Don't forget to see the loading effects on both the Arduino and
the PICAXE, because you don't want to burn your project hardware
after all.
Test your project and note that you will have to troubleshoot
both software and hardware whenever a problem occurs.
I suggest that you use the Oscilloscope to test the signals going in or coming out of both circuits + the sensor's signal.
For any extra thing you need the PICAXE to do, use If statements, because they are not so technical to implement and they are easy to write and troubleshoot.
For your scheme, you are actually making the Arduino give instructions to the PICAXE through a variable signal coming from a sensor.
^send me feedback and I will help more.
You will probably want to look into using UART (aka Serial) or i2c communication.
Serial communication should work with any PICAXE and Arduino, While i2c Will only work if you are using the X2 Series PICAXE Chips. i2c's main advantage is when using multiple slave devices (plus the master device, i.e. more than just 2 devices total) in which you can use the same two wires for up to around 128 devices. Serial (UART) communication is simpler, and only needs one wire (plus a common ground) to send data one way, it is what i'll show for the rest of this answer
Here is the manual entry for serial input for the PICAXE, and Here's the entry for serial output from the Arduino. The code you will need given your question will be something like the following:
For the arduino:
void setup(){
Serial.begin(9600);
}
void loop(){
if (conditionMet){ //whatever the condition is in your code
int bytesSent = Serial.write(“HIGH”); //send the string “HIGH"
}
}
and for the PICAXE:
main:
serin 6, T9600, ("HIGH") 'uses qualifier to look for exact message "HIGH"
'do whatever when criteria met
goto main

Resources