Move from PCM PIC16 Microcontroller to PCH PIC18 - c

I have written a C code for PCM PIC 16 Microcontroller. I have now replaced the board with a PCH PIC 18. I am having issues configuring the new board. Here is an excerpt of my code where I am getting the errors.
#include "i2c_custom.h"
const int getIIC_period_us(){
return (1000/IIC_CLOCK_KHz);
}
#ifdef USE_IIC_CCS_FUNCTION
int i2c_custom_read(int ack) {return i2c_read(ack);}
void i2c_custom_stop() {i2c_stop();}
void i2c_custom_start() {i2c_start();}
int i2c_custom_write(int8 data) {return i2c_write(data);}
#else
int i2c_custom_read(int ack) {
int data=0;
for(int i=7;i>=-1;i--)
{
if(i>=0){
i2c_custom_delay_us(IIC_period_4);
data |= (input(hw_IIC_SDA)<<i);
}else{
if(ack) output_low(hw_IIC_SDA);
else output_high(hw_IIC_SDA);
i2c_custom_delay_us(IIC_period_4);
}
i2c_custom_delay_us(IIC_period_4);
output_high(hw_IIC_SCL);
i2c_custom_delay_us(IIC_period_2);
output_low(hw_IIC_SCL);
}
return data;
}
void i2c_custom_stop() {
if(input_state(hw_IIC_SDA) || input_state(hw_IIC_SCL)){
output_low(hw_IIC_SCL);
output_low(hw_IIC_SDA);
i2c_custom_delay_us(IIC_period_4);
}
output_high(hw_IIC_SCL);
i2c_custom_delay_us(IIC_period_4);
output_high(hw_IIC_SDA);
i2c_custom_delay_us(IIC_period_4);
}
void i2c_custom_start() {
if(!input_state(hw_IIC_SDA) || !input_state(hw_IIC_SCL)){
output_high(hw_IIC_SDA);
output_high(hw_IIC_SCL);
i2c_custom_delay_us(IIC_period_4);
}
output_low(hw_IIC_SDA);
i2c_custom_delay_us(IIC_period_4);
output_low(hw_IIC_SCL);
}
int i2c_custom_write(int8 data) {
int ack=0;
for(int i=7;i>=-1;i--)
{
if(i>=0){
if((data&(0x01<<i)) ==0) output_low(hw_IIC_SDA);
else output_high(hw_IIC_SDA);
i2c_custom_delay_us(IIC_period_4);
}else{
i2c_custom_delay_us(IIC_period_4);
ack= input(hw_IIC_SDA);
}
i2c_custom_delay_us(IIC_period_4);
output_high(hw_IIC_SCL);
i2c_custom_delay_us(IIC_period_2);
output_low(hw_IIC_SCL);
}
return ack;
}
void i2c_custom_delay_us(int delay){
for(int i=0;i<delay;i++)
delay_us(1);
}
#endif
I am getting the following errors:
Error#51 A numeric expression must appear here :: i2c_read() not supported when using MASTER mode and HW I2C on this device, see i2c_transfer():
Error#112 Function used but not defined: :: i2c_stop() not supported when using HW I2C on this device, see i2c_transfer():
Error#112 Function used but not defined: :: i2c_start() not supported when using HW I2C on this device, see i2c_transfer():
Error#51 A numeric expression must appear here :: i2c_write() not supported when using MASTER mode and HW I2C on this device, see i2c_transfer():
I am not sure if I have to replace i2c_start(),i2c_stop(),i2c_read(), i2c_write() with i2c_transfer(). But I am not sure how to use i2c_transfer().
I would appreciate any help.

Related

Array Data Reading Failed

I am reading the data from a "Torque Wrench" using "USB Host Shield2.0" and Arduino UNO. I am receiving correct data from my "Torque Wrench" Data is receiving in a array.
But when I started reading data after "for" loop inside Void loop() I am receiving incorrect data. I attached Both output pictures correct and incorrect data.
Basically I am read data from Torque Wrench and send to receiver using Nrf24l01. I am receiving incorrect data.
My question is :- Why I am reading Incorrect data outside "for" loop.
Correct Data inside "for" loop :- enter image description here
Incorrect Data outside "for" loop :- enter image description here
#include <SPI.h> // for SPI communication
#include <nRF24L01.h>
#include <RF24.h>
#include <cdcacm.h>
#include <usbhub.h>
//#include "pgmstrings.h"
// Satisfy the IDE, which needs to see the include statment in the ino too.
#ifdef dobogusinclude
#include <spi4teensy3.h>
#endif
#include <SPI.h>
RF24 radio(7, 8); // CE, CSN
const byte address[6] = {'R','x','A','A','A','B'}; // the address the the module
class ACMAsyncOper : public CDCAsyncOper
{
public:
uint8_t OnInit(ACM *pacm);
};
uint8_t ACMAsyncOper::OnInit(ACM *pacm)
{
uint8_t rcode;
// Set DTR = 1 RTS=1
rcode = pacm->SetControlLineState(3);
if (rcode)
{
ErrorMessage<uint8_t>(PSTR("SetControlLineState"), rcode);
return rcode;
}
LINE_CODING lc;
lc.dwDTERate = 9600;
lc.bCharFormat = 0;
lc.bParityType = 0;
lc.bDataBits = 8;
rcode = pacm->SetLineCoding(&lc);
if (rcode)
ErrorMessage<uint8_t>(PSTR("SetLineCoding"), rcode);
return rcode;
}
USB Usb;
//USBHub Hub(&Usb);
ACMAsyncOper AsyncOper;
ACM Acm(&Usb, &AsyncOper);
void setup() {
Serial.begin(9600);
radio.begin();
radio.openWritingPipe(address);
radio.setPALevel(RF24_PA_MAX);
radio.stopListening();
#if !defined(__MIPSEL__)
while (!Serial);
#endif
Serial.println("Start");
if (Usb.Init() == -1)
Serial.println("USB Not Connected");
delay( 200 );
}
void loop() {
Usb.Task();
if( Acm.isReady()) {
uint8_t rcode;
/* reading the keyboard */
if(Serial.available()) {
uint8_t data= Serial.read();
/* sending to the phone */
rcode = Acm.SndData(1, &data);
if (rcode)
ErrorMessage<uint8_t>(PSTR("SndData"), rcode);
}
delay(10);
uint8_t buf[64];
uint16_t rcvd = 64;
char text[64];
rcode = Acm.RcvData(&rcvd, buf);
if (rcode && rcode != hrNAK)
ErrorMessage<uint8_t>(PSTR("Ret"), rcode);
if ( rcvd ) {
for(uint16_t i=0; i < rcvd; i++ )
{
// Serial.print((char)buf[i]); // correct Data read from torque wrench
text[i] = (char)buf[i];
}
Serial.println(text); // reading wrong data here
//radio.write(&text, sizeof(text));
//Serial.println(text);
}
delay(10);
}
}
Character arrays must be null-terminated to count as C strings.
After the for loop, add text[rcvd] = '\0';
Also, your rcvd is fixed at 64. It needs to be one less than the array size for the null terminator to fit.

Atmel studio with Xmega Timer/USART

I'm new in embedded systems developing also in Atmel studio Environment,
I'm using Atxmega128a1 with 32MHz system clk.
I'm trying to send some characters to the PC thought RS232 module at every timer interrupt overflow (0.05s),
so I defined (tc)Timers,USART Drivers on ASF and wrote the below code in main.c file, finally I debugged it without any error but not succeeded to transmit any thing through serial port.
anyone can help me or give me some advices.
#include <asf.h>
volatile int flag=0;
uint8_t received_byte;
uint8_t tx_buf[] = "\n\rHello AVR world ! : ";
uint8_t tx_length = 22;
uint8_t i;
static void my_callback(void)
{
flag =1;
}
int main (void)
{
/* Insert system clock initialization code here (sysclk_init()). */
board_init();
sysclk_init();
static usart_rs232_options_t USART_SERIAL_OPTIONS = {
.baudrate = 9600,
.charlength = 8,
.paritytype = USART_PMODE_DISABLED_gc,
.stopbits = false
};
usart_init_rs232(& USARTF0, &USART_SERIAL_OPTIONS);
//usart_set_baudrate_precalculated(& USARTF0,0x00017700,0x01E84800);
/* Insert application code here, after the board has been initialized. */
if (flag==1)
{
//received_byte = usart_getchar(& USARTF0);
//if (received_byte == '\r') {
for (i = 0; i < tx_length; i++)
{
usart_putchar(& USARTF0, tx_buf[i]);
}
}
else
usart_putchar(& USARTF0, received_byte);
flag=0;
}
I believe you are missing the initialization of the related system clock module:
sysclk_enable_module(SYSCLK_PORT_F, PR_USART0_bm);

Granting access with RFID card

I've got a problem with my arduino program. I'm using a RFID reader to scan cards (this part works flawlessly). I want the program to grant access to using some buttons (doesn't matter to be honest). The user who uses a verified card can use the functionalities until he scans a card again. I've deleted some unnecessary parts of the code.
#include <SPI.h>
#include <MFRC522.h>
String read_rfid;
String ok_rfid_1="a3f90f7"; //ID of the verified CARD
const int buzzer=8; //Buzzer
const int redLed=7;
const int greenLed=6;
const int yellowLed=5;
byte access=false; //
void setup() {
Serial.begin(9600); // Initialize serial communications with the PC
SPI.begin(); // Init SPI bus
mfrc522.PCD_Init(); // Init MFRC522 card
}
/*
* Helper routine to dump a byte array as hex values to Serial.
*/
void dump_byte_array(byte *buffer, byte bufferSize) {
read_rfid="";
for (byte i = 0; i < bufferSize; i++) {
read_rfid=read_rfid + String(buffer[i], HEX);
}
}
void granted() { } //it lights up the green led
void denied() { } //it lights up the red led
void login() {
if (read_rfid==ok_rfid_1) {
granted();
access=true;
} else {
denied();
}
delay(1000);
}
void logout() {
if (read_rfid==ok_rfid_1 && access==1) {
access=false;
Serial.println("Logout ");
}
}
void loop() {
// Look for new cards
if ( ! mfrc522.PICC_IsNewCardPresent())
return;
// Select one of the cards
if ( ! mfrc522.PICC_ReadCardSerial())
return;
dump_byte_array(mfrc522.uid.uidByte, mfrc522.uid.size);
Serial.println(read_rfid);
login();
while(access==true)
{logout();};
}
The logging in part works well, but it logs out automatically. As I observed the problem might be that if(read_rfid==ok_rfid_1 && access==1) is always true, because the read_rfid does not change. Do you have any ideas to solve my dillema?

How to Sync an Arduino with a DS1307

I am using an Arduino and a DS1307. I have acquired the time from the RTC no problem but when i try to apply the setSyncProvider call i get a few errors which are implying to my ds1307.h files in my library. attached is my code and errors. These errors , I am not quite sure what they are and mean. Do I need to go in notepad++ and change lines 66-68 to something or alter the .h in anyway? Does any body have an idea? Your help is most appreciated. By the way, the code is from the Arduino Cookbook so i know it works, its just smething in that .h file...... i think
#include <Time.h>
#include <Wire.h>
#include <DS1307.h> // a basic DS1307 library that returns time as a time_t
void setup() {
Serial.begin(9600);
setSyncProvider(RTC.get); // the function to get the time from the RTC
if(timeStatus() != timeSet)
Serial.println("Unable to sync with the RTC");
else
Serial.println("RTC has set the system time");
}
void loop() {
if(Serial.available()) {
time_t t = processSyncMessage();
if(t > 0) {
RTC.set(t); // set the RTC and the system time to the received value
setTime(t);
}
}
digitalClockDisplay();
delay(1000);
}
void digitalClockDisplay() {
// digital clock display of the time
Serial.print(hour());
printDigits(minute());
printDigits(second());
Serial.print(" ");
Serial.print(day());
Serial.print(" ");
Serial.print(month());
Serial.print(" ");
Serial.print(year());
Serial.println();
}
// utility function for digital clock display: prints preceding colon and
// leading 0.
//
void printDigits(int digits) {
Serial.print(":");
if(digits < 10)
Serial.print('0');
Serial.print(digits);
}
/* code to process time sync messages from the serial port */
#define TIME_MSG_LEN 11 // time sync to PC is HEADER followed by Unix time_t
#define TIME_HEADER 'T' // Header tag for serial time sync message
time_t processSyncMessage() {
while(Serial.available() >= TIME_MSG_LEN ) {
char c = Serial.read() ;
Serial.print(c);
if( c == TIME_HEADER ) {
time_t pctime = 0;
for(int i=0; i < TIME_MSG_LEN -1; i++) {
c = Serial.read();
if( c >= '0' && c <= '9') {
pctime = (10 * pctime) + (c - '0') ; // convert digits to a number
}
}
return pctime;
}
}
return 0;
}
My errors.......................................
sketch_dec27d.ino: In function 'void setup()':
sketch_dec27d:14: error: no matches converting function 'get' to type 'time_t (*)()'
C:\Users\AlbertR\Desktop\arduino-1.0.3\libraries\DS1307/DS1307.h:66: error: candidates are: void DS1307::get(int*, boolean)
C:\Users\AlbertR\Desktop\arduino-1.0.3\libraries\DS1307/DS1307.h:67: error: int DS1307::get(int, boolean)
sketch_dec27d.ino: In function 'void loop()':
sketch_dec27d:27: error: no matching function for call to 'DS1307::set(time_t&)'
C:\Users\AlbertR\Desktop\arduino-1.0.3\libraries\DS1307/DS1307.h:68: note: candidates are: void DS1307::set(int, int)

Receiving OK response for AT command via PIC Microcontroller

char rcv[10];
void main()
{
UART1_Init(9600);
Delay_ms(2000);
TRISB=0x00;
UART1_Write_Text("at");
UART1_Write(13); //Enter key = CF + LF
UART1_Write(10);
delay_ms(500);
while (1)
{ PORTB.RB0=1; // Endless loop
while(!UART1_Data_Ready()); // If data is received,
rcv[0]=UART1_Read();
rcv[1]=UART1_Read();
rcv[2]='\0';
UART1_Write_Text(rcv);
PORTB.RB0=0;
}
}
Compiler used : MikroC
I get the rcv output as ATTTTTTTTT. Pls help me out here to receive OK response from GSM Modem as this works with Hyperterminal.
Using PIC 18F4520 in PICPLC16v6 development board from Mikroelectronika.
It seems that you have the modem echo set on, so you'll receive each caracter you send it.
I would rewrite your code to something like :
void main(void)
{
uint8_t cmd[10];
uint8_t answer[20];
uint16_t timeout = 500; //max miliseconds to wait for an answer
UART1_Init(9600);
Delay_ms(1000);
TRISB=0;
cmd[0]='A';
cmd[1]='T';
cmd[2]=13;
cmd[3]=10;
cmd[4]=0;//marks end of CMD string
while(1)
{
uint8_t answer_len = SendModemCMD(cmd,answer,timeout);
UART1_Write_Text(answer);
Delay_ms(500);//not really needed ...
}
}
uint8_t SendModemCMD(uint8_t *cmd,uint8_t* answer,uint16_t timeout)
{
uint16_t local_timeout;
uint8_t answer_len=0;
while(*cmd!=0)
{
UART1_Write(*cmd++);
local_timeout=timeout;
while(local_timeout>0 && !UART1_Data_Ready())
{
Delay_ms(1);
local_timeout--;
}
if(UART1_Data_Ready())
{
UART1_Read();//discard echoed character
}
}
uint8_t finished=0;
while(finished==0)
{
local_timeout=timeout;
while(local_timeout>0 && !UART1_Data_Ready())
{
Delay_ms(1);
local_timeout--;
}
if(UART1_Data_Ready())
{
*answer++=UART1_Read();
answer_len++;
}
else
{
finished=1;
}
}
*answer=0;
return answer_len;
}

Resources