fix wire & add pwm

This commit is contained in:
MikuQ.com 2016-09-15 16:51:13 +08:00
parent 0227bb63aa
commit e5fdcb17d3
15 changed files with 270 additions and 60 deletions

View File

@ -2,6 +2,7 @@
#define _MIKUDUINO_H_
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "MikuPi.h"

View File

@ -32,7 +32,7 @@ int UTF8toGB2312(char *sourcebuf,char *destbuf)
return 0;
}
uint8 Miku_Oled::buf[OLED_BUFFER_LENGTH+1];
uint8_t Miku_Oled::buf[OLED_BUFFER_LENGTH+1];
const char logo[]={
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
@ -120,12 +120,7 @@ Miku_Oled::Miku_Oled()
showLogo();
}
void Miku_Oled::oled_sendCommand(int c)
{
Wire.write((uint8)0,(uint8)c);
}
void Miku_Oled::setEncoding(uint8 code)
void Miku_Oled::setEncoding(uint8_t code)
{
encoding=code;
}
@ -144,6 +139,9 @@ void Miku_Oled::display()
{
Wire.beginTransmission(0x3c);
Wire.write(poscode,6);
Wire.endTransmission();
Wire.beginTransmission(0x3c);
Wire.write(buf,1025);
Wire.endTransmission();
}
@ -182,12 +180,12 @@ void Miku_Oled::showLogo(void)
memcpy(buffer, logo, 1024);
}
void Miku_Oled::showBMP(uint8 *bmp)
void Miku_Oled::showBMP(uint8_t *bmp)
{
memcpy(buffer, bmp, 1024);
}
void Miku_Oled::setPos(uint8 x,uint8 y)
void Miku_Oled::setPos(uint8_t x,uint8_t y)
{
if ((x>128)||(y>64))
return;
@ -195,7 +193,7 @@ void Miku_Oled::setPos(uint8 x,uint8 y)
ypos=y;
}
void Miku_Oled::drawPoint(uint8 x,uint8 y,uint8 c)
void Miku_Oled::drawPoint(uint8_t x,uint8_t y,uint8_t c)
{
if ((x>128)||(y>64))
return;
@ -204,9 +202,9 @@ void Miku_Oled::drawPoint(uint8 x,uint8 y,uint8 c)
int m=y%8;
if (c==0)
buffer[p]&=~(uint8)(1<<m);
buffer[p]&=~(uint8_t)(1<<m);
else
buffer[p]|=(uint8)(1<<m);
buffer[p]|=(uint8_t)(1<<m);
}
void Miku_Oled::drawText(char* txt)
@ -221,10 +219,10 @@ void Miku_Oled::drawText(char* txt)
FILE *fphzk;
fphzk=fopen("/usr/share/fonts/mikupi.font","rb");
int i,r,rr;
uint8 out[32];
uint8_t out[32];
for(i=0;i<strlen(mytxt);i++)
{
uint8 x=*(mytxt+i);
uint8_t x=*(mytxt+i);
if (x<161)
{
if (x==10)
@ -248,7 +246,7 @@ void Miku_Oled::drawText(char* txt)
for(r=0;r<16;r++)
{
uint8 xxx=*(out+r);
uint8_t xxx=*(out+r);
for(rr=0;rr<8;rr++)
drawPoint(xpos+rr,ypos+r,xxx&(1<<(7-rr)));
}
@ -269,7 +267,7 @@ void Miku_Oled::drawText(char* txt)
for(r=0;r<16;r++)
{
uint8 xxx=*(out+r*2);
uint8_t xxx=*(out+r*2);
for(rr=0;rr<8;rr++)
drawPoint(xpos+rr,ypos+r,xxx&(1<<(7-rr)));
xxx=*(out+r*2+1);

View File

@ -73,17 +73,17 @@ class Miku_Oled {
void display(void);
void showLogo(void);
void clearDisplay(void);
void showBMP(uint8*);
void setPos(uint8,uint8);
void drawPoint(uint8,uint8,uint8);
void showBMP(uint8_t*);
void setPos(uint8_t,uint8_t);
void drawPoint(uint8_t,uint8_t,uint8_t);
void drawText(char*);
void setEncoding(uint8);
void setEncoding(uint8_t);
private:
void oled_sendCommand(int);
static uint8 buf[];
uint8 *buffer;
uint8 xpos,ypos;
uint8 encoding;
static uint8_t buf[];
uint8_t *buffer;
uint8_t xpos,ypos;
uint8_t encoding;
};

114
MikuPWM.cpp Executable file
View File

@ -0,0 +1,114 @@
#include "MikuPWM.h"
#include "Wire.h"
/*
*MikuPWM.cpp:
*
* Welcome to MikuQ.com! MikuDuino for BananaPi
*
* by MikuQ(i@mikuq.com)
*
* https://github.com/bpiq/MikuPi
*
*/
#define WIRE Wire
MikuPWM::MikuPWM(uint8_t addr) {
_i2caddr = addr;
}
void MikuPWM::begin(void) {
WIRE.begin();
reset();
}
void MikuPWM::reset(void) {
write8(PCA9685_MODE1, 0x0);
}
void MikuPWM::setPWMFreq(float freq) {
//Serial.print("Attempting to set freq ");
//Serial.println(freq);
freq *= 0.9; // Correct for overshoot in the frequency setting (see issue #11).
float prescaleval = 25000000;
prescaleval /= 4096;
prescaleval /= freq;
prescaleval -= 1;
uint8_t prescale = round(prescaleval);
//uint8_t prescale = floor(prescaleval + 0.5);
uint8_t oldmode = read8(PCA9685_MODE1);
uint8_t newmode = (oldmode&0x7F) | 0x10; // sleep
write8(PCA9685_MODE1, newmode); // go to sleep
write8(PCA9685_PRESCALE, prescale); // set the prescaler
write8(PCA9685_MODE1, oldmode);
delay(5);
write8(PCA9685_MODE1, oldmode | 0xa1); // This sets the MODE1 register to turn on auto increment.
// This is why the beginTransmission below was not working.
// Serial.print("Mode now 0x"); Serial.println(read8(PCA9685_MODE1), HEX);
}
void MikuPWM::setPWM(uint8_t num, uint16_t on, uint16_t off) {
//Serial.print("Setting PWM "); Serial.print(num); Serial.print(": "); Serial.print(on); Serial.print("->"); Serial.println(off);
WIRE.beginTransmission(_i2caddr);
WIRE.write(LED0_ON_L+4*num);
WIRE.write(on);
WIRE.write(on>>8);
WIRE.write(off);
WIRE.write(off>>8);
WIRE.endTransmission();
}
// Sets pin without having to deal with on/off tick placement and properly handles
// a zero value as completely off. Optional invert parameter supports inverting
// the pulse for sinking to ground. Val should be a value from 0 to 4095 inclusive.
void MikuPWM::setPin(uint8_t num, uint16_t val, bool invert)
{
// Clamp value between 0 and 4095 inclusive.
val = min(val, 4095);
if (invert) {
if (val == 0) {
// Special value for signal fully on.
setPWM(num, 4096, 0);
}
else if (val == 4095) {
// Special value for signal fully off.
setPWM(num, 0, 4096);
}
else {
setPWM(num, 0, 4095-val);
}
}
else {
if (val == 4095) {
// Special value for signal fully on.
setPWM(num, 4096, 0);
}
else if (val == 0) {
// Special value for signal fully off.
setPWM(num, 0, 4096);
}
else {
setPWM(num, 0, val);
}
}
}
uint8_t MikuPWM::read8(uint8_t addr) {
WIRE.beginTransmission(_i2caddr);
WIRE.write(addr);
WIRE.endTransmission();
WIRE.requestFrom((uint8_t)_i2caddr, (uint8_t)1);
return WIRE.read();
}
void MikuPWM::write8(uint8_t addr, uint8_t d) {
WIRE.beginTransmission(_i2caddr);
WIRE.write(addr);
WIRE.write(d);
WIRE.endTransmission();
}

41
MikuPWM.h Executable file
View File

@ -0,0 +1,41 @@
#ifndef _MikuPWM_H
#define _MikuPWM_H
#define PCA9685_SUBADR1 0x2
#define PCA9685_SUBADR2 0x3
#define PCA9685_SUBADR3 0x4
#define PCA9685_MODE1 0x0
#define PCA9685_PRESCALE 0xFE
#define LED0_ON_L 0x6
#define LED0_ON_H 0x7
#define LED0_OFF_L 0x8
#define LED0_OFF_H 0x9
#define ALLLED_ON_L 0xFA
#define ALLLED_ON_H 0xFB
#define ALLLED_OFF_L 0xFC
#define ALLLED_OFF_H 0xFD
#include <stdint.h>
#include <math.h>
#include "MikuPi.h"
class MikuPWM {
public:
MikuPWM(uint8_t addr = 0x40);
void begin(void);
void reset(void);
void setPWMFreq(float freq);
void setPWM(uint8_t num, uint16_t on, uint16_t off);
void setPin(uint8_t num, uint16_t val, bool invert=false);
private:
uint8_t _i2caddr;
uint8_t read8(uint8_t addr);
void write8(uint8_t addr, uint8_t d);
};
#endif

View File

@ -32,7 +32,7 @@
extern char *i2cDevice;
extern const int bPinTowPin[41];
#define VERSION "0.30"
#define VERSION "0.31"
extern const char *piModelNames [7] ;
extern const char *piModelFullNames [7];

View File

@ -24,9 +24,9 @@ float Miku_SHT2x::GetTemperature(void)
return (-46.85 + 175.72 / 65536.0 * (float)(readSensor(eTempHoldCmd)));
}
uint16 Miku_SHT2x::readSensor(uint8 command)
uint16_t Miku_SHT2x::readSensor(uint8_t command)
{
uint16 result;
uint16_t result;
Wire.beginTransmission(eSHT2xAddress);
Wire.write(command);

View File

@ -17,7 +17,7 @@ typedef enum {
class Miku_SHT2x
{
private:
uint16 readSensor(uint8 command);
uint16_t readSensor(uint8_t command);
public:
float GetHumidity(void);

View File

@ -1,12 +1,15 @@
#ifndef _MIKU_TYPES_H_
#define _MIKU_TYPES_H_
typedef unsigned char uint8;
typedef unsigned short uint16;
typedef unsigned long uint32;
#include <stdint.h>
typedef signed char int8;
typedef signed short int16;
typedef signed long int32;
#define min(a,b) ((a)<(b)?(a):(b))
#define max(a,b) ((a)>(b)?(a):(b))
#define abs(x) ((x)>0?(x):-(x))
#define constrain(amt,low,high) ((amt)<(low)?(low):((amt)>(high)?(high):(amt)))
#define round(x) ((x)>=0?(long)((x)+0.5):(long)((x)-0.5))
#define radians(deg) ((deg)*DEG_TO_RAD)
#define degrees(rad) ((rad)*RAD_TO_DEG)
#define sq(x) ((x)*(x))
#endif

View File

@ -13,6 +13,16 @@ gcc -Wall -o blink blink.cpp -lMikuDuino
sudo ./blink
</code></pre>
or
<pre><code>
cd examples
make
sudo ./blink
</code></pre>
more help: https://help.mikuduino.com/
<pre><code>
+-----+-----+---------+------+---+- MikuPi -+---+------+---------+-----+-----+
| CPU | wPi | Name | Mode | V | Physical | V | Mode | Name | wPi | CPU |
@ -49,6 +59,7 @@ sudo ./blink
5.(2016-06-24) add MikuOLED
6.(2016-06-25) modify Uncle Li's BadApple
7.(2016-07-02) add oled.drawText support ascii & gb2312
8.(2016-09-15) fix wire class & add pwm class
upload

View File

@ -2,6 +2,7 @@
#include <unistd.h>
#include <fcntl.h>
#include <linux/i2c-dev.h>
#include <string.h>
/*
*Wire.cpp:
@ -14,12 +15,17 @@
*
*/
#include "MikuPi.h"
#include "MikuDuino.h"
#include "Wire.h"
uint8 TwoWire::rxBuffer[BUFFER_LENGTH];
uint8 TwoWire::rxBufferIndex = 0;
uint8 TwoWire::rxBufferLength = 0;
uint8_t TwoWire::rxBuffer[BUFFER_LENGTH];
uint8_t TwoWire::rxBufferIndex = 0;
uint8_t TwoWire::rxBufferLength = 0;
uint8_t TwoWire::txAddress = 0;
uint8_t TwoWire::txBuffer[BUFFER_LENGTH];
uint16_t TwoWire::txBufferIndex = 0;
uint16_t TwoWire::txBufferLength = 0;
TwoWire::TwoWire()
{
@ -27,6 +33,12 @@ TwoWire::TwoWire()
void TwoWire::begin()
{
rxBufferIndex = 0;
rxBufferLength = 0;
txBufferIndex = 0;
txBufferLength = 0;
I2cError = 0;
if ((I2cDevHandle = open(i2cDevice, O_RDWR)) < 0) I2cError |= ERROR_I2C_OPEN;
}
@ -49,26 +61,45 @@ void TwoWire::requestFrom(int address, int quantity)
void TwoWire::beginTransmission(int address)
{
I2cError = 0;
if (ioctl(I2cDevHandle, I2C_SLAVE,address) < 0) I2cError |= ERROR_I2C_SETUP;
txAddress = address;
txBufferIndex = 0;
txBufferLength = 0;
}
void TwoWire::endTransmission()
{
I2cError = 0;
if (ioctl(I2cDevHandle, I2C_SLAVE,txAddress) < 0) I2cError |= ERROR_I2C_SETUP;
if(!I2cError)
{
if((::write(I2cDevHandle, txBuffer, txBufferLength)) != txBufferLength) I2cError |= ERROR_I2C_WRITE;
}
//printf("\n leng = %d \n",txBufferLength);
txBufferIndex = 0;
txBufferLength = 0;
//close(I2cDevHandle);
}
void TwoWire::write(uint8 cmd)
void TwoWire::write(uint8_t cmd)
{
if(!I2cError)
{
if((::write(I2cDevHandle, &cmd, 1)) != 1) I2cError |= ERROR_I2C_WRITE;
}
if(txBufferLength >= BUFFER_LENGTH){
return;
}
// put byte in tx buffer
txBuffer[txBufferIndex] = cmd;
++txBufferIndex;
// update amount in buffer
txBufferLength = txBufferIndex;
}
void TwoWire::write(uint8 reg, uint8 dat)
void TwoWire::write(uint8_t reg, uint8_t dat)
{
uint8 buf[2];
uint8_t buf[2];
buf[0]=reg;
buf[1]=dat;
if(!I2cError)
@ -77,11 +108,18 @@ void TwoWire::write(uint8 reg, uint8 dat)
}
}
void TwoWire::write(uint8* dat, int length)
void TwoWire::write(uint8_t* dat, int length)
{
if(txBufferLength+length >= BUFFER_LENGTH){
return;
}
memcpy(txBuffer, dat, length);
txBufferIndex+=length;
txBufferLength = txBufferIndex;
return;
if(!I2cError)
{
//write(int handle, void *buf, int nbyte);
if((::write(I2cDevHandle, dat, length)) != length) I2cError |= ERROR_I2C_WRITE;
}
}

20
Wire.h
View File

@ -8,14 +8,20 @@
#define ERROR_I2C_READ 4
#define ERROR_I2C_WRITE 8
#define BUFFER_LENGTH 32
#define BUFFER_LENGTH 2000
class TwoWire
{
private:
static uint8 rxBuffer[];
static uint8 rxBufferIndex;
static uint8 rxBufferLength;
static uint8_t rxBuffer[];
static uint8_t rxBufferIndex;
static uint8_t rxBufferLength;
static uint8_t txAddress;
static uint8_t txBuffer[];
static uint16_t txBufferIndex;
static uint16_t txBufferLength;
int I2cDevHandle;
int I2cError;
public:
@ -26,9 +32,9 @@ class TwoWire
void requestFrom(int, int);
int available(void);
int read(void);
void write(uint8);
void write(uint8,uint8);
void write(uint8*,int);
void write(uint8_t);
void write(uint8_t,uint8_t);
void write(uint8_t*,int);
};
extern TwoWire Wire;

View File

@ -14,7 +14,7 @@
*/
#define BUFFER_SIZE 1024
uint8 buffer[BUFFER_SIZE];
uint8_t buffer[BUFFER_SIZE];
Miku_Oled oled;

View File

@ -1,7 +1,5 @@
#include "MikuDuino.h"
#include "MikuOled.h"
#include <stdio.h>
#include <stdlib.h>
/*
* arg_oled.cpp:

View File

@ -2,7 +2,7 @@ CC := gcc
LD := ld
CFLAGS := -fPIC
LDFLAGS := -shared -fpic
SOURCE := MikuPi.cpp MikuDuino.cpp MikuRelay.cpp MikuSHT2x.cpp Wire.cpp MikuOled.cpp
SOURCE := $(wildcard *.cpp)
HEADER := $(wildcard *.h)
OBJS := $(patsubst %.cpp,%.o,$(SOURCE))
TARGET_LIB := libMikuDuino.so