fix wire & add pwm
This commit is contained in:
parent
0227bb63aa
commit
e5fdcb17d3
@ -2,6 +2,7 @@
|
||||
#define _MIKUDUINO_H_
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "MikuPi.h"
|
||||
|
||||
|
||||
30
MikuOled.cpp
30
MikuOled.cpp
@ -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);
|
||||
|
||||
16
MikuOled.h
16
MikuOled.h
@ -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
114
MikuPWM.cpp
Executable 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
41
MikuPWM.h
Executable 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
|
||||
2
MikuPi.h
2
MikuPi.h
@ -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];
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -17,7 +17,7 @@ typedef enum {
|
||||
class Miku_SHT2x
|
||||
{
|
||||
private:
|
||||
uint16 readSensor(uint8 command);
|
||||
uint16_t readSensor(uint8_t command);
|
||||
|
||||
public:
|
||||
float GetHumidity(void);
|
||||
|
||||
15
MikuTypes.h
15
MikuTypes.h
@ -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
|
||||
|
||||
11
README.md
11
README.md
@ -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
|
||||
|
||||
|
||||
68
Wire.cpp
68
Wire.cpp
@ -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
20
Wire.h
@ -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;
|
||||
|
||||
@ -14,7 +14,7 @@
|
||||
*/
|
||||
|
||||
#define BUFFER_SIZE 1024
|
||||
uint8 buffer[BUFFER_SIZE];
|
||||
uint8_t buffer[BUFFER_SIZE];
|
||||
|
||||
Miku_Oled oled;
|
||||
|
||||
|
||||
@ -1,7 +1,5 @@
|
||||
#include "MikuDuino.h"
|
||||
#include "MikuOled.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
/*
|
||||
* arg_oled.cpp:
|
||||
|
||||
2
makefile
2
makefile
@ -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
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user