I2C bit banging with Clock Stretching is not working - clock

I try to implement I2C bit banging to communicate with OLED in PIC 18F4520. Its working fine without 'clock stretching' but if I put 'clock stretching' its not working. And also I tried with put the 'clock stretching' block before and after the ACK pulse, both are not working.whats wrong with my clock stretching??
void send_packet(){
/* Soft_I2C_Start(); //Here its working fine
Soft_I2C_Write(0x78);
Soft_I2C_Write(tx_packet[0]);
Soft_I2C_Write(tx_packet[1]);
Soft_I2C_Stop();*/
unsigned char i,temp=0x78; //Slave Address with write permission
ASDA=1; //Start Condition
ASCL=1;
delay_ms(1);
ASDA=0;
ASCL=0;
for(i=0;i<8;i++){
if(temp & 0x80){
ASDA=1;
}
else{
ASDA=0;
}
temp=temp<<1;
ASCL=1;
ASCL=0;
}
ASCL=1; //Acknowledgment Pulse
ASCL=0;
while(PORTC.RC4==0); //Clock Stretching
for(i=0;i<8;i++){
if(tx_packet[0] & 0x80){
ASDA=1;
}
else{
ASDA=0;
}
tx_packet[0]=tx_packet[0]<<1;
ASCL=1;
ASCL=0;
}
ASCL=1; //Acknowledgment Pulse
ASCL=0;
while(PORTC.RC4==0); //Clock Stretching
for(i=0;i<8;i++){
if(tx_packet[1] & 0x80){
ASDA=1;
}
else{
ASDA=0;
}
tx_packet[1]=tx_packet[1]<<1;
ASCL=1;
ASCL=0;
}
ASCL=1; //Acknowledgment Pulse
ASCL=0;
while(PORTC.RC4==0); //Clock Stretching
ASCL=1; //Stop Condition
ASDA=1;
}

if((temp&0x80)==1){
temp&0x80 has two possible values, 0 and 0x80. It will never == 1.

Related

I got 14:29 when running this code. Trying to use Ardouino circuits

int switchmode=0;
void setup()
{
pinMode(3, INPUT);
pinMode(7, OUTPUT);
pinMode(9, OUTPUT);
}
void loop()
{
switchmode = digitalRead(3;
digitalWrite(7,switchmode);
if(switchmode== HIGH){
digitalWrite(9,HIGH);
delay(1000);
digitalWrite(9,LOW);
delay(1000);
}
I'm running this code on a virtual electric circuit on Tinkercad.com
This is sthe error that I get
** In function 'void loop()':
14:29: error: expected ')' before ';' token
exit status 1**
I think you miss this bracket here:
// ↓
switchmode = digitalRead(3;
// The correct is:
switchmode = digitalRead(3);

ESP OTA updating over https web server

I have an old code which works great and has no problem but I have been asked to change the OTA configuration so that this code can update itself from a SSL server. I have the certificate and the fingerprint needed for this (downloaded it from google chrome). I have googled and tried most of the advised method for OTA over HTTPS. but none of them worked for me. the results which I get from 'ESPhttpUpdate.update' is always "-1" which means "connection failed".
can anybody propose a method which works all right? as I don't have any correct code I don't post any. I just want a suggestion or a sample code.
thank you all in advance
The problem was solved.
I had split the server address into 2 parts (as the sample code suggested), URL and URI; but I don't know why, when I concatenated them together, the problem was solved.
here is the code for those who may need it:
#include <ESP8266WiFi.h>
#include <WiFiClientSecure.h>
#include <FS.h>
#include "ESP8266httpUpdate.h"
/********************************************************
********************************************************
********************************************************/
const char* ssid = "********"; // modify this
const char* password = "********"; // modify this
const char* host = "https://server/steamer_v1_2.bin"; // modify this
/********************************************************
********************************************************
********************************************************/
void setup() {
Serial.begin(115200);
WiFi.mode(WIFI_STA);
for (uint8_t t = 4; t > 0; t--)
{
Serial.printf("[SETUP] WAIT %d...\n", t);
Serial.flush();
delay(1000);
}
Serial.println();
Serial.print("connecting to ");
Serial.println(ssid);
if (WiFi.SSID() != ssid) {
WiFi.begin(ssid, password);
}
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
// configure time
configTime(3 * 3600, 0, "pool.ntp.org");
BearSSL::WiFiClientSecure client;
const uint8_t fingerprint[20] = {0xdd, 0xa5, 0x2d, 0x31, 0x25, 0x31, 0xae, 0x7a, 0x10, 0x0b, 0x68, 0xba, 0x22, 0x84, 0x1a, 0x94, 0xec, 0x79, 0xb4, 0xbb}; // modify this
client.setFingerprint(fingerprint);
auto ret = ESPhttpUpdate.update(client, host);
// if successful, ESP will restart
Serial.println("update failed");
Serial.println((int) ret);
}
/********************************************************
********************************************************
********************************************************/
void loop() {
}

User input stuck in loop

I have made this code on Arduino where the objective is to have the user type in a delay time into the serial monitor, and then the LED should be blink with that delay time. For example if I type in 1000 the LED should be turned on for 1 second then off for 1 second, then repeat.
My problem is that when the code has finished running once, it waits for a new user input, instead of continuing to blink. I think i have to take the Serial.parseInt out of the loop but i'm not sure how as every time I have tried to put it somewhere else the LED just lights up constantly.
Here is the code:
int ledPin = 13;
void setup() {
// put your setup code here, to run once:
pinMode(ledPin, OUTPUT);
Serial.begin(9600);
Serial.print(" Enter delay time: ");
while (!Serial.available());
}
void loop() {
// put your main code here, to run repeatedly
int delayTime = Serial.parseInt();
digitalWrite(ledPin, HIGH);
delay(delayTime);
digitalWrite(ledPin, LOW);
delay(delayTime);
}
Serial.parseInt is a blocking function. That means it waits for valid serial input until it times out. Because of this, any other action in loop has to wait too. Reading user input in setup works only once though, so it never asks the user for input again.
To avoid this, you'll have to check the serial buffer, and then read each byte individually, while also doing the LED blinking in the main loop.
Another thing to avoid now, is the use of the delay function, because it also hangs the entire main loop (including the serial readings) for the given parameter time. You can still blink the LED by using timestamp intervals.
For a nice example of a non-blocking serial read, we can use this sample from the Arduino docs. Additionally, for another nice example of an LED-blinking sketch without using delay, we can use the BlinkWithoutDelay sample from the Arduino docs too.
String inString = "";
unsigned long previousMillis = 0;
int delayTime = 0;
int ledState = LOW;
int ledPin = 13;
void nonBlockingSerialReadDelayTime() {
while (Serial.available() > 0) {
int inChar = Serial.read();
if (isDigit(inChar)) {
// convert the incoming byte to a char and add it to the string
inString += (char)inChar;
}
// if you get a newline (user pressed ENTER on the serial console)
if (inChar == '\n') {
// set our new delay time
delayTime = inString.toInt();
// clear the string for new input
inString = "";
// ask user again
Serial.print(" Enter delay time: ");
}
}
}
void blinkLED() {
unsigned long currentMillis = millis();
if (currentMillis - previousMillis >= delayTime) {
// save the last time you blinked the LED
previousMillis = currentMillis;
// if the LED is off turn it on and vice-versa
if (ledState == LOW) {
ledState = HIGH;
} else {
ledState = LOW;
}
// set the LED with the ledState of the variable
digitalWrite(ledPin, ledState);
}
}
void setup() {
pinMode(ledPin, OUTPUT);
Serial.begin(9600);
while (!Serial.available());
Serial.print(" Enter delay time: ");
}
void loop() {
nonBlockingSerialReadDelayTime();
blinkLED();
}
Simply read the delay time in your setup befor you enter loop
int ledPin = 13;
int delayTime = 0;
void setup() {
// put your setup code here, to run once:
pinMode(ledPin, OUTPUT);
Serial.begin(9600);
Serial.print(" Enter delay time: ");
while (!Serial.available());
delayTime = Serial.parseInt();
}
void loop() {
// put your main code here, to run repeatedly
digitalWrite(ledPin, HIGH);
delay(delayTime);
digitalWrite(ledPin, LOW);
delay(delayTime);
}
Sure Serial.parseInt() is blocking, but you can combine it with Serial.available()
const int ledPin = 13;
int delayTime = 1000;
void setup() {
pinMode(ledPin, OUTPUT);
Serial.begin(9600);
Serial.print(" Enter delay time: ");
}
void loop() {
digitalWrite(ledPin, HIGH);
delay(delayTime);
digitalWrite(ledPin, LOW);
delay(delayTime);
if (Serial.available()) {
int temp = Serial.parseInt();
if (temp > 0) delayTime = temp;
Serial.print(" Enter delay time: ");
}
}
Of course this approach does not allow to break into a very slow blink cycle immediately, but that's a different issue.

Mpu6050 and Adafruit Ultimate Gps not working together on Arduino Due

I have the codes for mpu6050 and adafruit ultimate gps breakout v3 and they are working fine seperately on arduino due but when i try to combine both the codes the gps does not get a fix. Can anybody help me out?
The code for mpu6050 is given below
// MPU-6050 Short Example Sketch
// By Arduino User JohnChi
// August 17, 2014
// Public Domain
#include<Wire.h>
extern TwoWire Wire1;
const int MPU_addr=0x68; // I2C address of the MPU-6050
int16_t AcX,AcY,AcZ,Tmp,GyX,GyY,GyZ;
int minVal=265;
int maxVal=402;
double x;
double y;
double z;
double pitch,roll,delta_X,delta_Y,delta_Z;
double old_AcX=0;
double old_AcY=0;
double old_AcZ=0;
int led = 13;
void setup(){
Wire1.begin();
Wire1.beginTransmission(MPU_addr);
Wire1.write(0x6B); // PWR_MGMT_1 register
Wire1.write(0); // set to zero (wakes up the MPU-6050)
Wire1.endTransmission(true);
Serial.begin(9600);
pinMode(led, OUTPUT);
}
void loop(){
Wire1.beginTransmission(MPU_addr);
Wire1.write(0x3B); // starting with register 0x3B (ACCEL_XOUT_H)
Wire1.endTransmission(false);
Wire1.requestFrom(MPU_addr,14,true); // request a total of 14 registers
AcX=Wire1.read()<<8|Wire1.read(); // 0x3B (ACCEL_XOUT_H) & 0x3C (ACCEL_XOUT_L)
AcY=Wire1.read()<<8|Wire1.read(); // 0x3D (ACCEL_YOUT_H) & 0x3E (ACCEL_YOUT_L)
AcZ=Wire1.read()<<8|Wire1.read(); // 0x3F (ACCEL_ZOUT_H) & 0x40 (ACCEL_ZOUT_L)
Tmp=Wire1.read()<<8|Wire1.read(); // 0x41 (TEMP_OUT_H) & 0x42 (TEMP_OUT_L)
GyX=Wire1.read()<<8|Wire1.read(); // 0x43 (GYRO_XOUT_H) & 0x44 (GYRO_XOUT_L)
GyY=Wire1.read()<<8|Wire1.read(); // 0x45 (GYRO_YOUT_H) & 0x46 (GYRO_YOUT_L)
GyZ=Wire1.read()<<8|Wire1.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(1000);
}
And the code for the Adafruit ultimate Gps breakout is given below
#include <Adafruit_GPS.h>
#define mySerial Serial1
Adafruit_GPS GPS(&mySerial);
#define GPSECHO true
boolean usingInterrupt = false;
void useInterrupt(boolean); // Func prototype keeps Arduino 0023 happy
void setup()
{
Serial.begin(9600);
GPS.begin(9600);
mySerial.begin(9600);
GPS.sendCommand(PMTK_SET_NMEA_OUTPUT_RMCGGA);
GPS.sendCommand(PMTK_SET_NMEA_UPDATE_1HZ);
GPS.sendCommand(PGCMD_ANTENNA);
#ifdef __arm__
usingInterrupt = false;
#else
useInterrupt(true);
#endif
delay(1000);
}
#ifdef __AVR__
SIGNAL(TIMER0_COMPA_vect) {
char c = GPS.read();
#ifdef UDR0
if (GPSECHO)
if (c) UDR0 = c;
// writing direct to UDR0 is much much faster than Serial.print
// but only one character can be written at a time.
#endif
}
void useInterrupt(boolean v) {
if (v) {
OCR0A = 0xAF;
TIMSK0 |= _BV(OCIE0A);
usingInterrupt = true;
} else {
// do not call the interrupt function COMPA anymore
TIMSK0 &= ~_BV(OCIE0A);
usingInterrupt = false;
}
}
#endif //#ifdef__AVR__
uint32_t timer = millis();
void loop()
{
if (! usingInterrupt) {
char c = GPS.read();
}
// if a sentence is received, we can check the checksum, parse it...
if (GPS.newNMEAreceived()) {
// a tricky thing here is if we print the NMEA sentence, or data
// we end up not listening and catching other sentences!
// so be very wary if using OUTPUT_ALLDATA and trytng to print out data
//Serial.println(GPS.lastNMEA()); // this also sets the newNMEAreceived() flag to false
if (!GPS.parse(GPS.lastNMEA())) // this also sets the newNMEAreceived() flag to false
return; // we can fail to parse a sentence in which case we should just wait for another
}
// if millis() or timer wraps around, we'll just reset it
if (timer > millis()) timer = millis();
// approximately every 2 seconds or so, print out the current stats
if (millis() - timer > 2000) {
timer = millis(); // reset the timer
Serial.print("\nTime: ");
Serial.print(GPS.hour, DEC); Serial.print(':');
Serial.print(GPS.minute, DEC); Serial.print(':');
Serial.print(GPS.seconds, DEC); Serial.print('.');
Serial.println(GPS.milliseconds);
Serial.print("Date: ");
Serial.print(GPS.day, DEC); Serial.print('/');
Serial.print(GPS.month, DEC); Serial.print("/20");
Serial.println(GPS.year, DEC);
Serial.print("Fix: "); Serial.print((int)GPS.fix);
Serial.print(" quality: "); Serial.println((int)GPS.fixquality);
if (GPS.fix) {
//Serial.print("Location: ");
Serial.print(convertDegMinToDecDeg(GPS.latitude));
Serial.print(", ");
Serial.println(convertDegMinToDecDeg(GPS.longitude));
//Serial.print("Speed (knots): "); Serial.println(GPS.speed);
//Serial.print("Angle: "); Serial.println(GPS.angle);
//Serial.print("Altitude: "); Serial.println(GPS.altitude);
//Serial.print("Satellites: "); Serial.println((int)GPS.satellites);
}
}
}
Both the codes are working fine separetely but i am unable to combine them and run in a single code.I tried to combine them and tha adafruit Ultimate gps breakout isn't working and it gives nothing. I want to know how i can combine them to work in a single code.Thanks in advance.
Use NeoGPS instead -- just add it to your IMU sketch:
#include <NMEAGPS.h>
NMEAGPS gps;
#define gpsPort Serial1
...
void setup(){
Wire1.begin();
Wire1.beginTransmission(MPU_addr);
Wire1.write(0x6B); // PWR_MGMT_1 register
Wire1.write(0); // set to zero (wakes up the MPU-6050)
Wire1.endTransmission(true);
Serial.begin(9600);
pinMode(led, OUTPUT);
gpsPort.begin( 9600 );
}
void loop(){
if (gps.available( gpsPort )) {
gps_fix fix = gps.read(); // A new GPS update is ready, get all the pieces
// Print some of the pieces?
Serial.print( F("Location: ") );
if (fix.valid.location) {
Serial.print( fix.latitude(), 6 );
Serial.print( ',' );
Serial.print( fix.longitude(), 6 );
}
Serial.print( F(", Altitude: ") );
if (fix.valid.altitude)
Serial.print( fix.altitude() );
Serial.println();
// Take an IMU sample too.
Wire1.beginTransmission(MPU_addr);
...
Serial.print(" | GyZ = "); Serial.println(GyZ);
}
}
This will display one GPS update and one IMU sample per second.
Also, you cannot use delay. The Arduino will not do anything else during the delay, and it will lose GPS characters. Notice that the above loop structure is always running, checking for GPS data. When a GPS update is finally ready, it takes the IMU sample and prints all the results.
You also have to be careful about printing too much information. Eventually, the Arduino will spend all its time waiting to print characters.
NeoGPS is available from the Arduino IDE Library Manager, under the menu Sketch -> Include Library -> Manage Libraries. NeoGPS is faster, smaller, more reliable and more accurate than all other GPS libraries, and the examples are properly structured. It is very common for the other libraries' examples to break when they are modified. Even if you don't use it, there is lots of information on the NeoGPS Installation and Troubleshooting pages.

SD card error for Arduino Mega

I am trying to run a simple program using a SD card module from spark fun with a Arduino Mega2560. This is the program i am current using:
#include <SD.h>
const int chipSelect = 10;
void setup()
{
Serial.begin(9600);
Serial.print("Initializing SD card...");
pinMode(53, OUTPUT);
digitalWrite(10, HIGH);
if (!SD.begin(chipSelect)) {
Serial.println("Card failed, or not present");
// don't do anything more:
return;
}
Serial.println("card initialized.");
}
void loop()
{
String dataString = "";
for (int analogPin = 0; analogPin < 3; analogPin++) {
int sensor = analogRead(analogPin);
dataString += String(sensor);
if (analogPin < 2) {
dataString += ",";
}
}
File dataFile = SD.open("datalog.txt", FILE_WRITE);
if (dataFile) {
dataFile.println(dataString);
dataFile.close();
Serial.println(dataString);
}
else {
Serial.println("error opening datalog.txt");
}
}
The error i am receiving says :
Initializing SD card...Card failed, or not present
error opening datalog.txt
Change
pinMode(53, OUTPUT);
digitalWrite(10, HIGH);
To
pinMode(53, OUTPUT);
digitalWrite(53, HIGH);
And have a try.
Sometimes it may happen for not writing this
File dataFile = SD.open("datalog.txt", FILE_WRITE);
immediately after this [or long before writing to that file]
Serial.println("card initialized.");
Believe me, this happened to me.