Need explanations about a code relative to MPU6050 - arduino-uno

Can anybody please explain me these code. I don't understand how I2C protocol is working.
#include<Wire.h>
const int MPU=0x68; // I2C address of the MPU-6050
int16_t AcX,AcY,AcZ,Tmp,GyX,GyY,GyZ; //int16_t is a 16bit integer. uint16_t is an unsigned 16bit integer
void setup(){
Wire.begin();
Wire.beginTransmission(MPU);
Wire.write(0x6B); // PWR_MGMT_1 register
Wire.write(0); // set to zero (wakes up the MPU-6050)
Wire.endTransmission(true);
Serial.begin(9600);
}
void loop(){
Wire.beginTransmission(MPU);
Wire.write(0x3B); // starting with register 0x3B (ACCEL_XOUT_H)
Wire.endTransmission(false);
Wire.requestFrom(MPU,14,true); // request a total of 14 registers
AcX=Wire.read()<<8|Wire.read(); // 0x3B (ACCEL_XOUT_H) & 0x3C (ACCEL_XOUT_L)
AcY=Wire.read()<<8|Wire.read(); // 0x3D (ACCEL_YOUT_H) & 0x3E (ACCEL_YOUT_L)
AcZ=Wire.read()<<8|Wire.read(); // 0x3F (ACCEL_ZOUT_H) & 0x40 (ACCEL_ZOUT_L)
Tmp=Wire.read()<<8|Wire.read(); // 0x41 (TEMP_OUT_H) & 0x42 (TEMP_OUT_L)
GyX=Wire.read()<<8|Wire.read(); // 0x43 (GYRO_XOUT_H) & 0x44 (GYRO_XOUT_L)
GyY=Wire.read()<<8|Wire.read(); // 0x45 (GYRO_YOUT_H) & 0x46 (GYRO_YOUT_L)
GyZ=Wire.read()<<8|Wire.read(); // 0x47 (GYRO_ZOUT_H) & 0x48 (GYRO_ZOUT_L)
Serial.print("AcX = "); Serial.print(AcX);
Serial.print(" | AcY = "); Serial.print(AcY);
Serial.print(" | AcZ = "); Serial.print(AcZ);
Serial.print(" | Tmp = "); Serial.print(Tmp/340.00+36.53); //equation for temperature in degrees C from datasheet
Serial.print(" | GyX = "); Serial.print(GyX);
Serial.print(" | GyY = "); Serial.print(GyY);
Serial.print(" | GyZ = "); Serial.println(GyZ);
delay(333);
}

The code opens a I2C connection to the device, transmits an address to read from, and then reads 14 bytes from the device, reassemblying them back into 7 16 bit integers.
I would recommend reading the documentation.

Related

Analog measurement incorrect on Teensy 2.0++

I have a Joystick wired up to my Teensy 2.0++ and I want to read the analog values from it.
I took this implementation from PJRC:
static uint8_t aref = (1<<REFS0); // default to AREF = Vcc, this is a 5V Vcc Teensy
void analogReference(uint8_t mode)
{
aref = mode & 0xC0;
}
// Mux input
int16_t adc_read(uint8_t mux)
{
#if defined(__AVR_AT90USB162__)
return 0;
#else
uint8_t low;
ADCSRA = (1<<ADEN) | ADC_PRESCALER; // enable ADC
ADCSRB = (1<<ADHSM) | (mux & 0x20); // high speed mode
ADMUX = aref | (mux & 0x1F); // configure mux input
ADCSRA = (1<<ADEN) | ADC_PRESCALER | (1<<ADSC); // start the conversion
while (ADCSRA & (1<<ADSC)) ; // wait for result
low = ADCL; // must read LSB first
return (ADCH << 8) | low; // must read MSB only once!
#endif
}
// Arduino compatible pin input
int16_t analogRead(uint8_t pin)
{
#if defined(__AVR_ATmega32U4__)
static const uint8_t PROGMEM pin_to_mux[] = {
0x00, 0x01, 0x04, 0x05, 0x06, 0x07,
0x25, 0x24, 0x23, 0x22, 0x21, 0x20};
if (pin >= 12) return 0;
return adc_read(pgm_read_byte(pin_to_mux + pin));
#elif defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB1286__)
if (pin >= 8) return 0;
return adc_read(pin);
#else
return 0;
#endif
}
I have my X and Y pins wired up to F1 and F0, and I want to retrieve values with the following code:
long map(long x, long in_min, long in_max, long out_min, long out_max) // map method shamelessy ripped from Arduino
{
return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}
joy_ly = map(analogRead(0), 0, 65535, 0, 255);
joy_lx = map(analogRead(1), 0, 65535, 0, 255);
I measured my Joystick with a multimeter and it works perfectly (around 2.43V on center, 0V on min, and 5V on max), but the center value always ends up being very close to zero.
Is there anything I'm doing wrong?
NOTE: This is an at90usb1286 chip.
The ADC max value is 1024, not 65535.

Issue while reading data from I2c Slave device with PIC16F886

I am newbie to Pic Programming, I am using MPLAb & Hitech compiler to execute above code. I am trying to Interface PIC16F886 with ISL12022M Real time I2C device. i copied code example written for DS1307 interface with 16F887A PIC. I have capable to inteface Basic functionality with above . In below code While write into ISL12022M o could able to see data what i have send in memory register But as when Trying to read rtc time i could able to read last memory write value From SSPBUF. let me know any error in below code.
once I2c read value should be displayed on 4 digit seven segment display.
I think I am doing Misatake in this part. while Reading data i m just sending address so whatever last written in address it displaying.
#include <htc.h>
#include <stdio.h>
#include<pic.h>
#include<stdint.h>
#define _XTAL_FREQ 40000000
unsigned int i=0;
unsigned int k=0;
unsigned int count;
#define Pulse RA5
#define LED RC0
#define LED1 RC2
#define CONTROLREG 0xFF
#define SDA RC4 // Data pin for i2c
#define SCK RC3 // Clock pin for i2c
#define SDA_DIR TRISC4 // Data pin direction
#define SCK_DIR TRISC3 // Clock pin direction
#define DP RA4
#define I2C_SPEED 100 // kbps
unsigned short int cnt, num,Dgt=0;;
unsigned short int temp1,temp2,temp3;
unsigned short sec;
unsigned short min;
unsigned short hour;
unsigned short date;
unsigned short month;
unsigned short year;
unsigned short day;
unsigned short int temp=0;
unsigned short r_data;
#define Seg1 0x01
#define Seg2 0x02
#define Seg3 0x04
#define Seg4 0x08
void SetSeg(unsigned short data, unsigned short segno)
{
switch(data)
{
case 0: PORTB = 0x3F; break;
case 1: PORTB = 0x06; break;
case 2: PORTB = 0x5B; break;
case 3: PORTB = 0x4F; break;
case 4: PORTB = 0x66; break;
case 5: PORTB = 0x6D; break;
case 6: PORTB = 0x7D; break;
case 7: PORTB = 0x07; break;
case 8: PORTB = 0x7F; break;
case 9: PORTB = 0x6F; break;
default : PORTB = 0X00; break;
}
if(segno==1)
{
PORTA = Seg4;
}
if(segno==2)
{
PORTA = Seg3;
}
if(segno==3)
{
PORTA = Seg2;
}
if(segno==4)
{
PORTA = Seg1;
}
}
void Delay(int k)
{
int j;
for(j=0;j<k;j++);
}
void InitI2C(void)
{
SDA_DIR = 1; // Make SDA and
SCK_DIR =0; // SCK pins input
SSPCON = 0b00111000; //enables port for i2c
SSPCON2 = 0b00000000;
SSPADD = 10; // 100KHz = 8MHz/4(SSPADD+1)
// SSPSTAT = 0b11000000; // Slew rate disabled
}
void i2c_waitForIdle(void)
{
unsigned int i2ctimeout;
while(1)
{
i2ctimeout++;
if(i2ctimeout > 10)
{
i2ctimeout = 0;
return;
}
}
}
void I2C_Start(void)
{
SEN = 1; // Send start bit
i2c_waitForIdle();
/* while(!SSPIF); // Wait for it to complete
SSPIF = 0; // Clear the flag bit*/
}
void I2C_ReStart(void)
{
RSEN = 1; // Send Restart bit
i2c_waitForIdle();
/* while(!SSPIF); // Wait for it to complete
SSPIF = 0; // Clear the flag bit
while(RSEN==1);*/
}
void I2C_Stop(void)
{
PEN = 1; // Send stop bit
i2c_waitForIdle();
}
void I2C_Send_ACK(void)
{
ACKDT = 0; // 0 means ACK
ACKEN = 1; // Send ACKDT value
i2c_waitForIdle();
}
void I2C_Send_NACK(void)
{
ACKDT = 1; // 1 means NACK
ACKEN = 1; // Send ACKDT value
i2c_waitForIdle();
}
unsigned char I2C_Write( unsigned char i2cWriteData )
{
i2c_waitForIdle();
SSPBUF = i2cWriteData;
return (!ACKSTAT); // function returns '1'
}
int I2C_Read( unsigned char ack )
{
unsigned char i2cReadData;
//unsigned int i2cReadData;
i2c_waitForIdle();
RCEN = 1;
SDA=1;
SCK=1;
i2c_waitForIdle();
i2cReadData = SSPBUF;
SCK=0;
i2c_waitForIdle();
SCK=1;
if(ack)
{
ACKDT = 0;
}
else
{
ACKDT = 1;
}
ACKEN = 1; // send acknowledge sequence
return( i2cReadData );
}
unsigned int bcdtodecimal(unsigned int bcd)
{
unsigned int decimal;
decimal = (((bcd & 0xF0) >> 4) * 10) + (bcd & 0x0F);
return decimal;
}
void Init_ISL12022M(void)
{
I2C_Start(); // Start I2C communication
I2C_Write(0XD0); //Write Device Address
I2C_Write(0X08); //
I2C_Write(0X41); // Write 0x00 to Control register to disable SQW-Out
I2C_Stop(); // Stop I2C communication after initilizing
}
unsigned int Write_ISL12022M(unsigned short address, unsigned short w_data)
{
I2C_Start(); // Start I2C communication
I2C_Write(0XD0);
I2C_Write(address); //write address to write data
I2C_Write(w_data); //write data into hexadecimal
I2C_Stop();//stop I2C communication
return(w_data);
}
unsigned short Read_ISL12022M(unsigned short address)
{
I2C_Start();
I2C_Write(address); //address 0x68 followed by direction bit (0 for write, 1 for read) 0x68 followed by 0 --> 0xD0
I2C_Write(address);
I2C_ReStart();
I2C_Write(0xD1); //0x68 followed by 1 --> 0xD1
r_data=I2C_Read(0);
I2C_Stop();
return(r_data);
}
void SetDateTime()
{
I2C_Start();
I2C_Write(0xD0);
I2C_Write(0x00);
sec= Write_ISL12022M(0X00, 12); //01 sec
min = Write_ISL12022M(0X01,52); //01 sec
hour = Write_ISL12022M(0X02,9); //01 sec
day= Write_ISL12022M(0X03,7); //01 sec
date = Write_ISL12022M(0X04, 29); //01 sec
month =Write_ISL12022M(0X05,07); //01 sec
year = Write_ISL12022M(0X06,17); //01 sec
I2C_Stop();
}
void RTC_GetDateTime()
{
I2C_Start(); // Start I2C communication
I2C_Send_ACK();
sec = I2C_Read(1); // read second and return Positive ACK
I2C_Send_ACK();
min = I2C_Read(1); // read minute and return Positive ACK
I2C_Send_ACK();
hour= I2C_Read(0); // read hour and return Negative/No ACK
I2C_Send_ACK();
day = I2C_Read(1); // read weekDay and return Positive ACK
I2C_Send_ACK();
date= I2C_Read(1); // read Date and return Positive ACK
I2C_Send_ACK();
month=I2C_Read(1); // read Month and return Positive ACK
I2C_Send_ACK();
year =I2C_Read(0); // read Year and return Negative/No ACK
I2C_Send_ACK();
I2C_Stop(); // Stop I2C communication after reading the Date
}
void interrupt isr(void)
{
if(TMR1IF==1)
{
TMR1H=0xF6; // Load the time value(0xBDC) for 100ms delay
TMR1L=0x18; //Timer1 Interrupt for 65000
TMR1IF=0; // Clear timer interrupt flag
Dgt++;
if(Dgt>=5)
{
Dgt=0;
LED=!LED;
}
}
}
void Timer1_Interrupt()
{
INTCON = 0b00000000;
PIE1=0b00000001;
PIR1=0x01;
TMR1H=0x0B;
TMR1L=0xDC;
T1CON=0x31;
}
void Init_Controller()
{
cnt=100;
TRISC=0b01000000; // Intialize INput & output pheripherals
TRISB=0b10000000;
PORTB = 0b00000000;
TRISA=0b0000000;
ADCON0 = 0b00000000;
ANSEL = 0b00000000;
Timer1_Interrupt();
}
void main(void)
{
Init_Controller();
/* GIE=1;
PEIE=1;
TMR1IE=1; */
InitI2C();
Init_ISL12022M();
SetDateTime();
while(1)
{
RTC_GetDateTime();
SetSeg(year/ 10,2);
SetSeg(year%10,1);
}
}
The lines like:
I2C_Write(0XD0); //Write Device Address
are not a valid device addresses. Use 0xDE (or 0xAE for User SRAM)
From the datasheet:
Following a start condition, the master must output a Slave Address Byte. The 7 MSBs are the device identifiers. These bits are “1101111” for the RTC registers and “1010111” for the User SRAM.

Raspbery pi fails writing to memory to initialize the function alt0

I am trying to write a raspy driver for pin 4.
while setting the alt0 function, raspy hangs, i have to restart it again.
#define RPI_DQ_GPIO_PIN 4
#define FUN_ALT0_SET 0x4
ds18b20_gpio_function(RPI_DQ_GPIO_PIN, FUN_ALT0_SET);
and
extern inline void ds18b20_gpio_function(u8 pin, u16 gpio_fun)
{
u32 val;
void __iomem *base_addr = (void __iomem *)(0xf2200000);
u8 offset = (pin / 10) * 4;
pin = (pin % 10) * 3;
val = gpio_fun << pin;
printk("ds18b20_gpio_function : pin = %d, val = %x, base_address + offset = %x\n", pin, val, base_addr + offset);
write_to_reg(val, base_addr + offset);
}
and
inline void write_to_reg(u32 b, volatile void __iomem *addr)
{
printk(KERN_INFO "write_to_reg : address = %x, b = %ld\n", addr, b);
__raw_writel(b, addr);
mb();
}
I got this virtual address of ioremap after dmesged of default gpio driver.
How can i solve it ?
Any help will be appreciated.
Thanks,

AVR Atmega8 ADC input causes Crash

i am trying to Read an Voltage Level via a ADC0 of my ATmega8, because of querying a 1 Pin 4x4 Matrix Keypad. The Problem is everytime I apply a Voltage to the ADC higher than GND the Atmega is stopping to do his work. The PWM outputs are still working, but communication via i2c is impossible and the LCD is clear.
My wiring is simple, AREF & AVCC are set to 5V, GND is set to GND and PC0 is my Input. Is there anything I fail to Notice? Thank You for your help.
Here is my Code:
void Initialisierung(void)
{
char text [2];
lcd_init();
cli();
//### TWI
init_twi_slave(SLAVE_ADRESSE); //TWI als Slave mit Adresse slaveadr starten
sei();
lcd_setcursor( 0, 1 );
lcd_string(">Booting...");
lcd_setcursor( 0, 2 );
itoa (SLAVE_ADRESSE,text,16);
lcd_string("I2C Adress=0x");
lcd_string(text);
for (int Index=0; Index<85; ++Index) {
rxbuffer[Index] = 0x20;
}
rxbuffer[81]=0xFF;
rxbuffer[82]=0xFF;
rxbuffer[83]=0xFF;
rxbuffer[84]=0xFF;
}
//update LCD
void lcd_update(void){
for (int o=1;o<=4; o++)
for (int i=1; i<=20; i++){
lcd_setcursor( i-1, o );
lcd_data(rxbuffer[i+((o-1)*20)]);
}
}
An here is the main function:
int main(void)
{
DDRC &= ~(1 << PC0);
PORTC &= ~(1 << PC0);
Initialisierung();
DDRB = (1 << DDB1) | (1 << DDB2);
OCR1A = eeprom_read_word(&brightness); // PWM einstellen,
OCR1B = eeprom_read_word(&contrast);
ICR1 = 1000; // TOP-wert
TCCR1A = (1<<COM1A1) | (1<<COM1B1) | (1<<WGM11); // 2-Kanal "non-inverting"
TCCR1B = (1<<WGM13)|(1<<WGM12) | (1<<CS11);
//Initialize ADC
ADCSRA = (1<<ADEN) | (1<<ADPS2) | (1<<ADPS0);
ADMUX=0x00;
unsigned int adc_value=0; // Variable to hold ADC result
char text[2];
while(1)
{
ADCSRA |= (1<<ADSC); // Start conversion
while (ADCSRA & (1<<ADSC)); // wait for conversion to complete
adc_value = ADCW; //Store ADC value
itoa (adc_value,text,16);
lcd_setcursor( 0,4 );
lcd_string(text);
for (int Index=0; Index<85; ++Index) {
txbuffer[Index] = rxbuffer[Index];
}
uint16_t brightness_i2c=0;
uint16_t contrast_i2c=0;
brightness_i2c=(rxbuffer[81]<<8)|(rxbuffer[82]);
contrast_i2c=(rxbuffer[83]<<8)|(rxbuffer[84]);
if (rxbuffer[0]==1){
lcd_update();
rxbuffer[0]=4;
}else if(brightness_i2c!=eeprom_read_word(&brightness) && brightness_i2c!=0xFFFF){
eeprom_write_word(&brightness,brightness_i2c);
OCR1A = eeprom_read_word(&brightness);
}else if (contrast_i2c!=eeprom_read_word(&contrast) && contrast_i2c!=0xFFFF){
eeprom_write_word(&contrast,contrast_i2c);
OCR1B = eeprom_read_word(&contrast);
}else{
for (uint8_t i=0; i<50; i++) _delay_ms(10);
lcd_setcursor( 19, 4 );
lcd_data(0xFF);
for (uint8_t i=0; i<50; i++) _delay_ms(10);
lcd_setcursor( 19, 4 );
lcd_data(0x20);
}
}
}
I finally got it:
I setup the ADC with interrupts but not freerunning:
ADCSRA =(1<<ADEN)|(1<<ADPS2)|(1<<ADPS1)|(1<<ADIE)| (1<<ADPS0);
And call the ADC everytime at the end of my While loop:
ADCSRA |= (1<<ADSC);
Here is the Code for the ISR:
ISR(ADC_vect)
{
char text[5];
itoa (ADC,text,16);
lcd_setcursor( 0,4 );
lcd_string(text);
}
Thanks for your time ;)

Logical error in comparing character recieved in USART

I Want to compare the character recieved via RX pin of ATMEGA 8. WHy doesn't the comparison work?
int main()
{
DDRB = 0XFF;
UCSRB = (1<<RXEN);
UCSRC = (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0);
UBRRL = 0X33;
char r;
while (1)
{
while(!(UCSRA&(1<<RXC)));
r = UDR;
if(r=='r') PORTB = 0XFF;
}
return 0;
}
Sample code for easy setting baud_rate
#define F_CPU 8000000UL // Chip CPU frequency here, prevents default 1MHz
#define USART_BAUDRATE 19200UL // Baud_rate here, baudrates: 300, 600, 1200, 2400, 4800, 9600, 19200, 38400, 57600, 115200, 230400, 460800, 921600
#define BAUD_PRESCALE (((F_CPU / (USART_BAUDRATE * 16UL))) - 1)
#include <avr/io.h>
int main(void) {
DDRB = 0XFF;
UBRRL = BAUD_PRESCALE; // baud to low byte of the UBRR register
UBRRH = (BAUD_PRESCALE >> 8); // baud to high byte of the UBRR register
UCSRB = (1<<RXEN);
UCSRC = (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0);
char r;
while(1) {
//TODO:: Please write your application code
while(!(UCSRA&(1<<RXC)));
r = UDR;
if(r=='r') PORTB = 0XFF;
}
return 0;
}

Resources